diff --git a/hydrogen/assets/Inter-Black.067c82f7.woff b/hydrogen/assets/Inter-Black.067c82f7.woff new file mode 100644 index 0000000..07800f4 Binary files /dev/null and b/hydrogen/assets/Inter-Black.067c82f7.woff differ diff --git a/hydrogen/assets/Inter-Black.7f1f5616.woff2 b/hydrogen/assets/Inter-Black.7f1f5616.woff2 new file mode 100644 index 0000000..9a615e6 Binary files /dev/null and b/hydrogen/assets/Inter-Black.7f1f5616.woff2 differ diff --git a/hydrogen/assets/Inter-BlackItalic.72d5983b.woff2 b/hydrogen/assets/Inter-BlackItalic.72d5983b.woff2 new file mode 100644 index 0000000..9dfced9 Binary files /dev/null and b/hydrogen/assets/Inter-BlackItalic.72d5983b.woff2 differ diff --git a/hydrogen/assets/Inter-BlackItalic.c628a2cf.woff b/hydrogen/assets/Inter-BlackItalic.c628a2cf.woff new file mode 100644 index 0000000..8790638 Binary files /dev/null and b/hydrogen/assets/Inter-BlackItalic.c628a2cf.woff differ diff --git a/hydrogen/assets/Inter-Bold.20d46cff.woff b/hydrogen/assets/Inter-Bold.20d46cff.woff new file mode 100644 index 0000000..61e1c25 Binary files /dev/null and b/hydrogen/assets/Inter-Bold.20d46cff.woff differ diff --git a/hydrogen/assets/Inter-Bold.6f5e9a23.woff2 b/hydrogen/assets/Inter-Bold.6f5e9a23.woff2 new file mode 100644 index 0000000..6c401bb Binary files /dev/null and b/hydrogen/assets/Inter-Bold.6f5e9a23.woff2 differ diff --git a/hydrogen/assets/Inter-BoldItalic.31a185fa.woff b/hydrogen/assets/Inter-BoldItalic.31a185fa.woff new file mode 100644 index 0000000..2de403e Binary files /dev/null and b/hydrogen/assets/Inter-BoldItalic.31a185fa.woff differ diff --git a/hydrogen/assets/Inter-BoldItalic.e09dcbe1.woff2 b/hydrogen/assets/Inter-BoldItalic.e09dcbe1.woff2 new file mode 100644 index 0000000..80efd48 Binary files /dev/null and b/hydrogen/assets/Inter-BoldItalic.e09dcbe1.woff2 differ diff --git a/hydrogen/assets/Inter-ExtraBold.0ef4267e.woff2 b/hydrogen/assets/Inter-ExtraBold.0ef4267e.woff2 new file mode 100644 index 0000000..5a08b36 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraBold.0ef4267e.woff2 differ diff --git a/hydrogen/assets/Inter-ExtraBold.45bae435.woff b/hydrogen/assets/Inter-ExtraBold.45bae435.woff new file mode 100644 index 0000000..433fb32 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraBold.45bae435.woff differ diff --git a/hydrogen/assets/Inter-ExtraBoldItalic.30a1af87.woff b/hydrogen/assets/Inter-ExtraBoldItalic.30a1af87.woff new file mode 100644 index 0000000..bd97df3 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraBoldItalic.30a1af87.woff differ diff --git a/hydrogen/assets/Inter-ExtraBoldItalic.d1e1f6a0.woff2 b/hydrogen/assets/Inter-ExtraBoldItalic.d1e1f6a0.woff2 new file mode 100644 index 0000000..97bda24 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraBoldItalic.d1e1f6a0.woff2 differ diff --git a/hydrogen/assets/Inter-ExtraLight.d7be68a4.woff b/hydrogen/assets/Inter-ExtraLight.d7be68a4.woff new file mode 100644 index 0000000..39e6f97 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraLight.d7be68a4.woff differ diff --git a/hydrogen/assets/Inter-ExtraLight.da47c335.woff2 b/hydrogen/assets/Inter-ExtraLight.da47c335.woff2 new file mode 100644 index 0000000..442e225 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraLight.da47c335.woff2 differ diff --git a/hydrogen/assets/Inter-ExtraLightItalic.762fa4d2.woff b/hydrogen/assets/Inter-ExtraLightItalic.762fa4d2.woff new file mode 100644 index 0000000..a6e1d14 Binary files /dev/null and b/hydrogen/assets/Inter-ExtraLightItalic.762fa4d2.woff differ diff --git a/hydrogen/assets/Inter-ExtraLightItalic.b3f94cfe.woff2 b/hydrogen/assets/Inter-ExtraLightItalic.b3f94cfe.woff2 new file mode 100644 index 0000000..db6880b Binary files /dev/null and b/hydrogen/assets/Inter-ExtraLightItalic.b3f94cfe.woff2 differ diff --git a/hydrogen/assets/Inter-Italic.7b187d57.woff b/hydrogen/assets/Inter-Italic.7b187d57.woff new file mode 100644 index 0000000..e7da666 Binary files /dev/null and b/hydrogen/assets/Inter-Italic.7b187d57.woff differ diff --git a/hydrogen/assets/Inter-Italic.bab4e808.woff2 b/hydrogen/assets/Inter-Italic.bab4e808.woff2 new file mode 100644 index 0000000..8559dfd Binary files /dev/null and b/hydrogen/assets/Inter-Italic.bab4e808.woff2 differ diff --git a/hydrogen/assets/Inter-Light.0f7dfe72.woff2 b/hydrogen/assets/Inter-Light.0f7dfe72.woff2 new file mode 100644 index 0000000..80378a3 Binary files /dev/null and b/hydrogen/assets/Inter-Light.0f7dfe72.woff2 differ diff --git a/hydrogen/assets/Inter-Light.38326098.woff b/hydrogen/assets/Inter-Light.38326098.woff new file mode 100644 index 0000000..108c112 Binary files /dev/null and b/hydrogen/assets/Inter-Light.38326098.woff differ diff --git a/hydrogen/assets/Inter-LightItalic.125c7e6a.woff2 b/hydrogen/assets/Inter-LightItalic.125c7e6a.woff2 new file mode 100644 index 0000000..091ff4e Binary files /dev/null and b/hydrogen/assets/Inter-LightItalic.125c7e6a.woff2 differ diff --git a/hydrogen/assets/Inter-LightItalic.ec6c76a8.woff b/hydrogen/assets/Inter-LightItalic.ec6c76a8.woff new file mode 100644 index 0000000..b30452a Binary files /dev/null and b/hydrogen/assets/Inter-LightItalic.ec6c76a8.woff differ diff --git a/hydrogen/assets/Inter-Medium.0fc5d904.woff b/hydrogen/assets/Inter-Medium.0fc5d904.woff new file mode 100644 index 0000000..8c36a63 Binary files /dev/null and b/hydrogen/assets/Inter-Medium.0fc5d904.woff differ diff --git a/hydrogen/assets/Inter-Medium.5d308f3d.woff2 b/hydrogen/assets/Inter-Medium.5d308f3d.woff2 new file mode 100644 index 0000000..3b31d33 Binary files /dev/null and b/hydrogen/assets/Inter-Medium.5d308f3d.woff2 differ diff --git a/hydrogen/assets/Inter-MediumItalic.1458af9d.woff b/hydrogen/assets/Inter-MediumItalic.1458af9d.woff new file mode 100644 index 0000000..fb79e91 Binary files /dev/null and b/hydrogen/assets/Inter-MediumItalic.1458af9d.woff differ diff --git a/hydrogen/assets/Inter-MediumItalic.76551c20.woff2 b/hydrogen/assets/Inter-MediumItalic.76551c20.woff2 new file mode 100644 index 0000000..d32c111 Binary files /dev/null and b/hydrogen/assets/Inter-MediumItalic.76551c20.woff2 differ diff --git a/hydrogen/assets/Inter-Regular.5b3a854b.woff b/hydrogen/assets/Inter-Regular.5b3a854b.woff new file mode 100644 index 0000000..7d587c4 Binary files /dev/null and b/hydrogen/assets/Inter-Regular.5b3a854b.woff differ diff --git a/hydrogen/assets/Inter-Regular.89d406b0.woff2 b/hydrogen/assets/Inter-Regular.89d406b0.woff2 new file mode 100644 index 0000000..d5ffd2a Binary files /dev/null and b/hydrogen/assets/Inter-Regular.89d406b0.woff2 differ diff --git a/hydrogen/assets/Inter-SemiBold.04cd699f.woff b/hydrogen/assets/Inter-SemiBold.04cd699f.woff new file mode 100644 index 0000000..99df06c Binary files /dev/null and b/hydrogen/assets/Inter-SemiBold.04cd699f.woff differ diff --git a/hydrogen/assets/Inter-SemiBold.c7c3befe.woff2 b/hydrogen/assets/Inter-SemiBold.c7c3befe.woff2 new file mode 100644 index 0000000..df746af Binary files /dev/null and b/hydrogen/assets/Inter-SemiBold.c7c3befe.woff2 differ diff --git a/hydrogen/assets/Inter-SemiBoldItalic.420db54a.woff b/hydrogen/assets/Inter-SemiBoldItalic.420db54a.woff new file mode 100644 index 0000000..91e192b Binary files /dev/null and b/hydrogen/assets/Inter-SemiBoldItalic.420db54a.woff differ diff --git a/hydrogen/assets/Inter-SemiBoldItalic.d376ade4.woff2 b/hydrogen/assets/Inter-SemiBoldItalic.d376ade4.woff2 new file mode 100644 index 0000000..ff8774c Binary files /dev/null and b/hydrogen/assets/Inter-SemiBoldItalic.d376ade4.woff2 differ diff --git a/hydrogen/assets/Inter-Thin.5565b01e.woff b/hydrogen/assets/Inter-Thin.5565b01e.woff new file mode 100644 index 0000000..9d2e3e5 Binary files /dev/null and b/hydrogen/assets/Inter-Thin.5565b01e.woff differ diff --git a/hydrogen/assets/Inter-Thin.5d8e2ac4.woff2 b/hydrogen/assets/Inter-Thin.5d8e2ac4.woff2 new file mode 100644 index 0000000..5f7bc37 Binary files /dev/null and b/hydrogen/assets/Inter-Thin.5d8e2ac4.woff2 differ diff --git a/hydrogen/assets/Inter-ThinItalic.6b3ded18.woff2 b/hydrogen/assets/Inter-ThinItalic.6b3ded18.woff2 new file mode 100644 index 0000000..2ceec60 Binary files /dev/null and b/hydrogen/assets/Inter-ThinItalic.6b3ded18.woff2 differ diff --git a/hydrogen/assets/Inter-ThinItalic.c413497b.woff b/hydrogen/assets/Inter-ThinItalic.c413497b.woff new file mode 100644 index 0000000..885d8d5 Binary files /dev/null and b/hydrogen/assets/Inter-ThinItalic.c413497b.woff differ diff --git a/hydrogen/assets/cam-muted-1894081672.22150c2b.svg b/hydrogen/assets/cam-muted-1894081672.22150c2b.svg new file mode 100644 index 0000000..324822f --- /dev/null +++ b/hydrogen/assets/cam-muted-1894081672.22150c2b.svg @@ -0,0 +1 @@ + diff --git a/hydrogen/assets/cam-muted-2247331037.b0b2cf01.svg b/hydrogen/assets/cam-muted-2247331037.b0b2cf01.svg new file mode 100644 index 0000000..026699c --- /dev/null +++ b/hydrogen/assets/cam-muted-2247331037.b0b2cf01.svg @@ -0,0 +1 @@ + diff --git a/hydrogen/assets/cam-muted-3489740486.a882d986.svg b/hydrogen/assets/cam-muted-3489740486.a882d986.svg new file mode 100644 index 0000000..215b0e6 --- /dev/null +++ b/hydrogen/assets/cam-muted-3489740486.a882d986.svg @@ -0,0 +1 @@ + diff --git a/hydrogen/assets/cam-muted-711199923.069dcf2b.svg b/hydrogen/assets/cam-muted-711199923.069dcf2b.svg new file mode 100644 index 0000000..ce74486 --- /dev/null +++ b/hydrogen/assets/cam-muted-711199923.069dcf2b.svg @@ -0,0 +1 @@ + diff --git a/hydrogen/assets/cam-muted.9f690631.svg b/hydrogen/assets/cam-muted.9f690631.svg new file mode 100644 index 0000000..b59a1a1 --- /dev/null +++ b/hydrogen/assets/cam-muted.9f690631.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/cam-unmuted-2215154474.a82b7bf1.svg b/hydrogen/assets/cam-unmuted-2215154474.a82b7bf1.svg new file mode 100644 index 0000000..f63c6fc --- /dev/null +++ b/hydrogen/assets/cam-unmuted-2215154474.a82b7bf1.svg @@ -0,0 +1 @@ + diff --git a/hydrogen/assets/cam-unmuted-2274150835.69bcdbc4.svg b/hydrogen/assets/cam-unmuted-2274150835.69bcdbc4.svg new file mode 100644 index 0000000..1de6c51 --- /dev/null +++ b/hydrogen/assets/cam-unmuted-2274150835.69bcdbc4.svg @@ -0,0 +1 @@ + diff --git a/hydrogen/assets/cam-unmuted.67e18332.svg b/hydrogen/assets/cam-unmuted.67e18332.svg new file mode 100644 index 0000000..4c96784 --- /dev/null +++ b/hydrogen/assets/cam-unmuted.67e18332.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/chevron-down-1956489915.3389f17f.svg b/hydrogen/assets/chevron-down-1956489915.3389f17f.svg new file mode 100644 index 0000000..e0ceb18 --- /dev/null +++ b/hydrogen/assets/chevron-down-1956489915.3389f17f.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + diff --git a/hydrogen/assets/chevron-down-3300400168.d1a083a1.svg b/hydrogen/assets/chevron-down-3300400168.d1a083a1.svg new file mode 100644 index 0000000..c391861 --- /dev/null +++ b/hydrogen/assets/chevron-down-3300400168.d1a083a1.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + diff --git a/hydrogen/assets/chevron-down.9a7440b9.svg b/hydrogen/assets/chevron-down.9a7440b9.svg new file mode 100644 index 0000000..5435cc3 --- /dev/null +++ b/hydrogen/assets/chevron-down.9a7440b9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/chevron-left-2611498805.b5555a61.svg b/hydrogen/assets/chevron-left-2611498805.b5555a61.svg new file mode 100644 index 0000000..90d2ced --- /dev/null +++ b/hydrogen/assets/chevron-left-2611498805.b5555a61.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hydrogen/assets/chevron-left-3506338632.4e437777.svg b/hydrogen/assets/chevron-left-3506338632.4e437777.svg new file mode 100644 index 0000000..2e0ed1b --- /dev/null +++ b/hydrogen/assets/chevron-left-3506338632.4e437777.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/hydrogen/assets/chevron-left.b8b2c5fc.svg b/hydrogen/assets/chevron-left.b8b2c5fc.svg new file mode 100644 index 0000000..dc01720 --- /dev/null +++ b/hydrogen/assets/chevron-left.b8b2c5fc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/chevron-right-2390431650.ec9bf561.svg b/hydrogen/assets/chevron-right-2390431650.ec9bf561.svg new file mode 100644 index 0000000..7df4847 --- /dev/null +++ b/hydrogen/assets/chevron-right-2390431650.ec9bf561.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/chevron-right-847198822.23380c56.svg b/hydrogen/assets/chevron-right-847198822.23380c56.svg new file mode 100644 index 0000000..c78cdce --- /dev/null +++ b/hydrogen/assets/chevron-right-847198822.23380c56.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/chevron-right.885731d1.svg b/hydrogen/assets/chevron-right.885731d1.svg new file mode 100644 index 0000000..2f1e3e7 --- /dev/null +++ b/hydrogen/assets/chevron-right.885731d1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/chevron-small-4098047679.489e66cc.svg b/hydrogen/assets/chevron-small-4098047679.489e66cc.svg new file mode 100644 index 0000000..95d9bdf --- /dev/null +++ b/hydrogen/assets/chevron-small-4098047679.489e66cc.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/chevron-small-781914114.936b4943.svg b/hydrogen/assets/chevron-small-781914114.936b4943.svg new file mode 100644 index 0000000..bec3492 --- /dev/null +++ b/hydrogen/assets/chevron-small-781914114.936b4943.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/chevron-small.dfd7e618.svg b/hydrogen/assets/chevron-small.dfd7e618.svg new file mode 100644 index 0000000..6c85b97 --- /dev/null +++ b/hydrogen/assets/chevron-small.dfd7e618.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/chevron-thin-left-3078630092.d0d143e3.svg b/hydrogen/assets/chevron-thin-left-3078630092.d0d143e3.svg new file mode 100644 index 0000000..66a541a --- /dev/null +++ b/hydrogen/assets/chevron-thin-left-3078630092.d0d143e3.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/chevron-thin-left-3831175135.13f60c05.svg b/hydrogen/assets/chevron-thin-left-3831175135.13f60c05.svg new file mode 100644 index 0000000..cf2e7a2 --- /dev/null +++ b/hydrogen/assets/chevron-thin-left-3831175135.13f60c05.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/chevron-thin-left.d111869b.svg b/hydrogen/assets/chevron-thin-left.d111869b.svg new file mode 100644 index 0000000..3119aad --- /dev/null +++ b/hydrogen/assets/chevron-thin-left.d111869b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/clear-2203718389.37dd36a5.svg b/hydrogen/assets/clear-2203718389.37dd36a5.svg new file mode 100644 index 0000000..cc7ef45 --- /dev/null +++ b/hydrogen/assets/clear-2203718389.37dd36a5.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/clear-2743697487.2f1a17f1.svg b/hydrogen/assets/clear-2743697487.2f1a17f1.svg new file mode 100644 index 0000000..a51940a --- /dev/null +++ b/hydrogen/assets/clear-2743697487.2f1a17f1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/clear-4137897294.7b90e8df.svg b/hydrogen/assets/clear-4137897294.7b90e8df.svg new file mode 100644 index 0000000..96d4672 --- /dev/null +++ b/hydrogen/assets/clear-4137897294.7b90e8df.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/clear-426756705.361f7a30.svg b/hydrogen/assets/clear-426756705.361f7a30.svg new file mode 100644 index 0000000..2e470ef --- /dev/null +++ b/hydrogen/assets/clear-426756705.361f7a30.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/clear.0d180c33.svg b/hydrogen/assets/clear.0d180c33.svg new file mode 100644 index 0000000..0f32a77 --- /dev/null +++ b/hydrogen/assets/clear.0d180c33.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/disable-grid-3304422220.8a79cfcb.svg b/hydrogen/assets/disable-grid-3304422220.8a79cfcb.svg new file mode 100644 index 0000000..41d19bb --- /dev/null +++ b/hydrogen/assets/disable-grid-3304422220.8a79cfcb.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/disable-grid-4240599831.c8dc25a1.svg b/hydrogen/assets/disable-grid-4240599831.c8dc25a1.svg new file mode 100644 index 0000000..c87b7ce --- /dev/null +++ b/hydrogen/assets/disable-grid-4240599831.c8dc25a1.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/disable-grid.371ceaaa.svg b/hydrogen/assets/disable-grid.371ceaaa.svg new file mode 100644 index 0000000..571cecf --- /dev/null +++ b/hydrogen/assets/disable-grid.371ceaaa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/dismiss-2476348673.d0f98560.svg b/hydrogen/assets/dismiss-2476348673.d0f98560.svg new file mode 100644 index 0000000..f5b82e3 --- /dev/null +++ b/hydrogen/assets/dismiss-2476348673.d0f98560.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/download-sandbox.48a866e9.html b/hydrogen/assets/download-sandbox.48a866e9.html new file mode 100644 index 0000000..9666cb9 --- /dev/null +++ b/hydrogen/assets/download-sandbox.48a866e9.html @@ -0,0 +1,46 @@ + + + + + + + Download + + + diff --git a/hydrogen/assets/e2ee-disabled-1470792300.6863c16d.svg b/hydrogen/assets/e2ee-disabled-1470792300.6863c16d.svg new file mode 100644 index 0000000..170ddb0 --- /dev/null +++ b/hydrogen/assets/e2ee-disabled-1470792300.6863c16d.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/hydrogen/assets/e2ee-disabled.8507165d.svg b/hydrogen/assets/e2ee-disabled.8507165d.svg new file mode 100644 index 0000000..a839e4e --- /dev/null +++ b/hydrogen/assets/e2ee-disabled.8507165d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/e2ee-normal-1448349558.af8f5484.svg b/hydrogen/assets/e2ee-normal-1448349558.af8f5484.svg new file mode 100644 index 0000000..0fd19d3 --- /dev/null +++ b/hydrogen/assets/e2ee-normal-1448349558.af8f5484.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/e2ee-normal-2713987956.215b3ddf.svg b/hydrogen/assets/e2ee-normal-2713987956.215b3ddf.svg new file mode 100644 index 0000000..0c6e1bc --- /dev/null +++ b/hydrogen/assets/e2ee-normal-2713987956.215b3ddf.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/e2ee-normal-3127337641.2624a9c9.svg b/hydrogen/assets/e2ee-normal-3127337641.2624a9c9.svg new file mode 100644 index 0000000..9dc9e1f --- /dev/null +++ b/hydrogen/assets/e2ee-normal-3127337641.2624a9c9.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/e2ee-normal-3652557173.2a97dccf.svg b/hydrogen/assets/e2ee-normal-3652557173.2a97dccf.svg new file mode 100644 index 0000000..430cea0 --- /dev/null +++ b/hydrogen/assets/e2ee-normal-3652557173.2a97dccf.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/e2ee-normal-3923817510.8737e7ee.svg b/hydrogen/assets/e2ee-normal-3923817510.8737e7ee.svg new file mode 100644 index 0000000..c025286 --- /dev/null +++ b/hydrogen/assets/e2ee-normal-3923817510.8737e7ee.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/e2ee-normal.bef76bd4.svg b/hydrogen/assets/e2ee-normal.bef76bd4.svg new file mode 100644 index 0000000..ca9802c --- /dev/null +++ b/hydrogen/assets/e2ee-normal.bef76bd4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/element-logo-1551909733.1d59f06a.svg b/hydrogen/assets/element-logo-1551909733.1d59f06a.svg new file mode 100644 index 0000000..0213265 --- /dev/null +++ b/hydrogen/assets/element-logo-1551909733.1d59f06a.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/hydrogen/assets/element-logo-703176763.fc54fc8d.svg b/hydrogen/assets/element-logo-703176763.fc54fc8d.svg new file mode 100644 index 0000000..8e576d4 --- /dev/null +++ b/hydrogen/assets/element-logo-703176763.fc54fc8d.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/hydrogen/assets/element-logo.86bc8565.svg b/hydrogen/assets/element-logo.86bc8565.svg new file mode 100644 index 0000000..31c3bca --- /dev/null +++ b/hydrogen/assets/element-logo.86bc8565.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/enable-grid-2071838379.ab4f40c5.svg b/hydrogen/assets/enable-grid-2071838379.ab4f40c5.svg new file mode 100644 index 0000000..a8308bc --- /dev/null +++ b/hydrogen/assets/enable-grid-2071838379.ab4f40c5.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/enable-grid-2288309723.f83895c8.svg b/hydrogen/assets/enable-grid-2288309723.f83895c8.svg new file mode 100644 index 0000000..3ee085f --- /dev/null +++ b/hydrogen/assets/enable-grid-2288309723.f83895c8.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/enable-grid.eef43c65.svg b/hydrogen/assets/enable-grid.eef43c65.svg new file mode 100644 index 0000000..acf9a28 --- /dev/null +++ b/hydrogen/assets/enable-grid.eef43c65.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/encryption-status-2100926911.a90232b4.svg b/hydrogen/assets/encryption-status-2100926911.a90232b4.svg new file mode 100644 index 0000000..b9fe5af --- /dev/null +++ b/hydrogen/assets/encryption-status-2100926911.a90232b4.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/encryption-status-3449529405.c200a9bb.svg b/hydrogen/assets/encryption-status-3449529405.c200a9bb.svg new file mode 100644 index 0000000..de513dd --- /dev/null +++ b/hydrogen/assets/encryption-status-3449529405.c200a9bb.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/encryption-status-475927392.2fedc0bd.svg b/hydrogen/assets/encryption-status-475927392.2fedc0bd.svg new file mode 100644 index 0000000..ded7df8 --- /dev/null +++ b/hydrogen/assets/encryption-status-475927392.2fedc0bd.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/encryption-status-689620003.8086e625.svg b/hydrogen/assets/encryption-status-689620003.8086e625.svg new file mode 100644 index 0000000..81c480f --- /dev/null +++ b/hydrogen/assets/encryption-status-689620003.8086e625.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/encryption-status.8054183e.svg b/hydrogen/assets/encryption-status.8054183e.svg new file mode 100644 index 0000000..0006bdf --- /dev/null +++ b/hydrogen/assets/encryption-status.8054183e.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/hangup-1798659826.d0cb8438.svg b/hydrogen/assets/hangup-1798659826.d0cb8438.svg new file mode 100644 index 0000000..047ccad --- /dev/null +++ b/hydrogen/assets/hangup-1798659826.d0cb8438.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/hangup-581771896.279a6adf.svg b/hydrogen/assets/hangup-581771896.279a6adf.svg new file mode 100644 index 0000000..e6e2190 --- /dev/null +++ b/hydrogen/assets/hangup-581771896.279a6adf.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/hangup.8b163c30.svg b/hydrogen/assets/hangup.8b163c30.svg new file mode 100644 index 0000000..952b142 --- /dev/null +++ b/hydrogen/assets/hangup.8b163c30.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/icon-maskable.965d12c4.png b/hydrogen/assets/icon-maskable.965d12c4.png new file mode 100644 index 0000000..3d96b2d Binary files /dev/null and b/hydrogen/assets/icon-maskable.965d12c4.png differ diff --git a/hydrogen/assets/icon.8024c299.png b/hydrogen/assets/icon.8024c299.png new file mode 100644 index 0000000..b6c70c0 Binary files /dev/null and b/hydrogen/assets/icon.8024c299.png differ diff --git a/hydrogen/assets/index.e65aa065.js b/hydrogen/assets/index.e65aa065.js new file mode 100644 index 0000000..7d73633 --- /dev/null +++ b/hydrogen/assets/index.e65aa065.js @@ -0,0 +1,31 @@ +var Gc=Object.defineProperty,Yc=Object.defineProperties;var Jc=Object.getOwnPropertyDescriptors;var Yi=Object.getOwnPropertySymbols;var jn=Object.prototype.hasOwnProperty,qn=Object.prototype.propertyIsEnumerable;var $n=(n,e,t)=>e in n?Gc(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,It=(n,e)=>{for(var t in e||(e={}))jn.call(e,t)&&$n(n,t,e[t]);if(Yi)for(var t of Yi(e))qn.call(e,t)&&$n(n,t,e[t]);return n},Fr=(n,e)=>Yc(n,Jc(e));var Hn=(n,e)=>{var t={};for(var s in n)jn.call(n,s)&&e.indexOf(s)<0&&(t[s]=n[s]);if(n!=null&&Yi)for(var s of Yi(n))e.indexOf(s)<0&&qn.call(n,s)&&(t[s]=n[s]);return t};function oi(...n){const e={};for(const t of n)e[t]=t;return Object.freeze(e)}function Wn(n){try{return new URL(n).origin}catch{return new URL(`https://${n}`).origin}}async function Qc(n,e){const t={format:"json",timeout:3e4,method:"GET"};try{const s=`${n}/.well-known/matrix/client`;return await e(s,t).response()}catch(s){if(s.name==="ConnectionError")return null;throw s}}async function Xc(n,e){var s;n=Wn(n);const t=await Qc(n,e);if(t&&t.status===200){const{body:i}=t,r=(s=i["m.homeserver"])==null?void 0:s.base_url;typeof r=="string"&&(n=Wn(r))}return n}class $t{constructor(){this._handlersByName={}}emit(e,t){const s=this._handlersByName[e];s&&s.forEach(i=>i(t))}disposableOn(e,t){return this.on(e,t),()=>{this.off(e,t)}}on(e,t){let s=this._handlersByName[e];s||(this.onFirstSubscriptionAdded(e),this._handlersByName[e]=s=new Set),s.add(t)}off(e,t){const s=this._handlersByName[e];s&&(s.delete(t),s.size===0&&(delete this._handlersByName[e],this.onLastSubscriptionRemoved(e)))}onFirstSubscriptionAdded(e){}onLastSubscriptionRemoved(e){}}class oa extends $t{constructor(e){super(),this._abortable=void 0;const t=i=>(this._abortable=i,i);this._progress=void 0;const s=i=>{this._progress=i,this.emit("change","progress")};this.result=e(t,s)}get progress(){return this._progress}abort(){var e;(e=this._abortable)==null||e.abort(),this._abortable=void 0}}class rt extends Error{get name(){return"AbortError"}}class xr{constructor(){this._handlers=new Set}onSubscribeFirst(){}onUnsubscribeLast(){}subscribe(e){return this._handlers.add(e),this._handlers.size===1&&this.onSubscribeFirst(),()=>this.unsubscribe(e)}unsubscribe(e){e&&(this._handlers.delete(e),this._handlers.size===0&&this.onUnsubscribeLast())}unsubscribeAll(){this._handlers.size!==0&&(this._handlers.clear(),this.onUnsubscribeLast())}get hasSubscriptions(){return this._handlers.size!==0}}class yt extends xr{emit(e){for(const t of this._handlers)t(e)}waitFor(e){return e(this.get())?new el(Promise.resolve(this.get())):new Zc(this,e)}flatMap(e){return new sl(this,e)}}class Zc{constructor(e,t){this._promise=new Promise((s,i)=>{this._reject=i,this._subscription=e.subscribe(r=>{t(r)&&(this._reject=null,s(r),this.dispose())})})}get promise(){return this._promise}dispose(){this._subscription&&(this._subscription(),this._subscription=null),this._reject&&(this._reject(new rt),this._reject=null)}}class el{constructor(e){this.promise=e}dispose(){}}class tl extends yt{constructor(e,t){super(),this.value=e,this.eventName=t}onSubscribeFirst(){this.eventSubscription=this.value.disposableOn(this.eventName,()=>{this.emit(this.value)}),super.onSubscribeFirst()}onUnsubscribeLast(){this.eventSubscription(),super.onUnsubscribeLast()}get(){return this.value}}class Vt extends yt{constructor(e){super(),this._value=e}get(){return this._value}set(e){e!==this._value&&(this._value=e,this.emit(this._value))}}class sl extends yt{constructor(e,t){super(),this.source=e,this.mapper=t}onUnsubscribeLast(){super.onUnsubscribeLast(),this.sourceSubscription=this.sourceSubscription(),this.targetSubscription&&(this.targetSubscription=this.targetSubscription())}onSubscribeFirst(){super.onSubscribeFirst(),this.sourceSubscription=this.source.subscribe(()=>{this.updateTargetSubscription(),this.emit(this.get())}),this.updateTargetSubscription()}updateTargetSubscription(){const e=this.source.get();if(e){const t=this.mapper(e);if(t){this.targetSubscription||(this.targetSubscription=t.subscribe(()=>this.emit(this.get())));return}}this.targetSubscription&&(this.targetSubscription=this.targetSubscription())}get(){const e=this.source.get();if(!e)return;const t=this.mapper(e);return t==null?void 0:t.get()}}function il(n,e){return e{}){super(e),this.freeCallback=t,this.startCallback=s}onSubscribeFirst(){this.startCallback()}onUnsubscribeLast(){super.onUnsubscribeLast(),this.freeCallback()}}class ai extends xr{emitReset(){for(let e of this._handlers)e.onReset(this)}emitAdd(e,t){for(let s of this._handlers)s.onAdd(e,t,this)}emitUpdate(e,t,s){for(let i of this._handlers)i.onUpdate(e,t,s,this)}emitRemove(e,t){for(let s of this._handlers)s.onRemove(e,t,this)}emitMove(e,t,s){for(let i of this._handlers)i.onMove(e,t,s,this)}}/** + * @license + * Based off baseSortedIndex function in Lodash + * Copyright JS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */function Nt(n,e,t){let s=0,i=n.length;for(;s>>1,o=t(e,n[r]);o>0?s=r+1:o<0?i=r:s=i=r}return i}class gn extends ai{constructor(e=[]){super(),this._items=e}append(e){this._items.push(e),this.emitAdd(this._items.length-1,e)}remove(e){const[t]=this._items.splice(e,1);this.emitRemove(e,t)}insertMany(e,t){for(let s of t)this.insert(e,s),e+=1}insert(e,t){this._items.splice(e,0,t),this.emitAdd(e,t)}move(e,t){if(e=0&&e=this._items.length||this._comparator(this._items[s],e)!==0?(this._items.splice(s,0,e),this.emitAdd(s,e)):(this._items[s]=e,this.emitUpdate(s,e,t))}get(e){return this._items[e]}remove(e){const t=this._items[e];this._items.splice(e,1),this.emitRemove(e,t)}get array(){return this._items}get length(){return this._items.length}[Symbol.iterator](){return new nl(this)}}class nl{constructor(e){this._consumed=!1,this._sortedArray=e,this._current=null}next(){return this._consumed?{value:void 0,done:!0}:(this._current=this._current?this._sortedArray._getNext(this._current):this._sortedArray.get(0),this._current||(this._consumed=!0),{value:this._current,done:this._consumed})}}class ol extends ai{constructor(e,t,s,i){super(),this._sourceUnsubscribe=null,this._mappedValues=null,this._sourceList=e,this._mapper=t,this._updater=s,this._removeCallback=i}findAndUpdate(e,t){return aa(e,this._mappedValues,this,t)}get length(){return this._mappedValues.length}[Symbol.iterator](){return this._mappedValues.values()}}function al(n,e,t){n._mappedValues.splice(e,0,t),n.emitAdd(e,t)}function cl(n,e,t,s){const i=n._mappedValues[e];n._updater&&n._updater(i,s,t),n.emitUpdate(e,i,s)}function ll(n,e){const t=n._mappedValues[e];n._mappedValues.splice(e,1),n._removeCallback&&n._removeCallback(t),n.emitRemove(e,t)}function hl(n,e,t){const s=n._mappedValues[e];n._mappedValues.splice(e,1),n._mappedValues.splice(t,0,s),n.emitMove(e,t,s)}function dl(n){n._mappedValues=[],n.emitReset()}class ul extends ol{constructor(){super(...arguments),this._eventQueue=null,this._flushing=!1}onSubscribeFirst(){this._sourceUnsubscribe=this._sourceList.subscribe(this),this._eventQueue=[],this._mappedValues=[];let e=0;for(const t of this._sourceList)this._eventQueue.push(new zn(e,t)),e+=1;this._flush()}async _flush(){if(!this._flushing){this._flushing=!0;try{for(;this._eventQueue.length;)await this._eventQueue.shift().run(this)}finally{this._flushing=!1}}}onReset(){this._eventQueue&&(this._eventQueue.push(new gl),this._flush())}onAdd(e,t){this._eventQueue&&(this._eventQueue.push(new zn(e,t)),this._flush())}onUpdate(e,t,s){this._eventQueue&&(this._eventQueue.push(new ml(e,t,s)),this._flush())}onRemove(e){this._eventQueue&&(this._eventQueue.push(new _l(e)),this._flush())}onMove(e,t){this._eventQueue&&(this._eventQueue.push(new pl(e,t)),this._flush())}onUnsubscribeLast(){this._sourceUnsubscribe(),this._eventQueue=null,this._mappedValues=null}}class zn{constructor(e,t){this.index=e,this.value=t}async run(e){const t=await e._mapper(this.value);al(e,this.index,t)}}class ml{constructor(e,t,s){this.index=e,this.value=t,this.params=s}async run(e){cl(e,this.index,this.value,this.params)}}class _l{constructor(e){this.index=e}async run(e){ll(e,this.index)}}class pl{constructor(e,t){this.fromIdx=e,this.toIdx=t}async run(e){hl(e,this.fromIdx,this.toIdx)}}class gl{async run(e){dl(e)}}class ca extends ai{constructor(...e){super(),this._sourceUnsubscribes=null,this._sourceLists=e}_offsetForSource(e){const t=this._sourceLists.indexOf(e);let s=0;for(let i=0;ie.subscribe(this))}onUnsubscribeLast(){for(const e of this._sourceUnsubscribes)e()}onReset(){this.emitReset();let e=0;for(const t of this)this.emitAdd(e,t),e+=1}onAdd(e,t,s){this.emitAdd(this._offsetForSource(s)+e,t)}onUpdate(e,t,s,i){!this._sourceUnsubscribes||this.emitUpdate(this._offsetForSource(i)+e,t,s)}onRemove(e,t,s){this.emitRemove(this._offsetForSource(s)+e,t)}onMove(e,t,s,i){const r=this._offsetForSource(i);this.emitMove(r+e,r+t,s)}get length(){let e=0;for(let t=0;t{let s=t.next();for(;s.done;){if(e+=1,e>=this._sourceLists.length)return s;t=this._sourceLists[e][Symbol.iterator](),s=t.next()}return s}}}}class fl extends ai{constructor(e,t){super(),this._sourceMap=e,this._comparator=(s,i)=>t(s.value,i.value),this._sortedPairs=null,this._mapSubscription=null}onAdd(e,t){const s={key:e,value:t},i=Nt(this._sortedPairs,s,this._comparator);this._sortedPairs.splice(i,0,s),this.emitAdd(i,t)}onRemove(e,t){const s={key:e,value:t},i=Nt(this._sortedPairs,s,this._comparator);this._sortedPairs.splice(i,1),this.emitRemove(i,t)}onUpdate(e,t,s){if(!this._sortedPairs)return;const i=this._sortedPairs.findIndex(c=>c.key===e);this._sortedPairs.splice(i,1);const r={key:e,value:t},o=Nt(this._sortedPairs,r,this._comparator);this._sortedPairs.splice(o,0,r),i!==o&&this.emitMove(i,o,t),this.emitUpdate(o,t,s)}onReset(){this._sortedPairs=[],this.emitReset()}onSubscribeFirst(){this._mapSubscription=this._sourceMap.subscribe(this),this._sortedPairs=new Array(this._sourceMap.size);let e=0;for(let[t,s]of this._sourceMap)this._sortedPairs[e]={key:t,value:s},++e;this._sortedPairs.sort(this._comparator),super.onSubscribeFirst()}onUnsubscribeLast(){super.onUnsubscribeLast(),this._sortedPairs=null,this._mapSubscription=this._mapSubscription()}get(e){return this._sortedPairs[e].value}get length(){return this._sourceMap.size}[Symbol.iterator](){const e=this._sortedPairs.values();return{next(){const t=e.next();return t.value&&(t.value=t.value.value),t}}}}class ci extends xr{constructor(){super()}emitReset(){for(let e of this._handlers)e.onReset()}emitAdd(e,t){for(let s of this._handlers)s.onAdd(e,t)}emitUpdate(e,t,s){for(let i of this._handlers)i.onUpdate(e,t,s)}emitRemove(e,t){for(let s of this._handlers)s.onRemove(e,t)}join(...e){return new bl([this].concat(e))}mapValues(e,t){return new Il(this,e,t)}sortValues(e){return new fl(this,e)}filterValues(e){return new wl(this,e)}observeSize(){return new Cl(this)}}class yl extends ci{constructor(e,t){super(),this._source=e,this._apply=t}hasApply(){return!!this._apply}setApply(e){this._apply=e,this._apply&&this.applyOnce(this._apply)}applyOnce(e){for(const[t,s]of this._source)e(t,s)}onAdd(e,t){this._apply&&this._apply(e,t),this.emitAdd(e,t)}onRemove(e,t){this.emitRemove(e,t)}onUpdate(e,t,s){this._apply&&this._apply(e,t,s),this.emitUpdate(e,t,s)}onSubscribeFirst(){this._subscription=this._source.subscribe(this),this._apply&&this.applyOnce(this._apply),super.onSubscribeFirst()}onUnsubscribeLast(){super.onUnsubscribeLast(),this._subscription&&(this._subscription=this._subscription())}onReset(){this._apply&&this.applyOnce(this._apply),this.emitReset()}[Symbol.iterator](){return this._source[Symbol.iterator]()}get size(){return this._source.size}get(e){return this._source.get(e)}}class wl extends ci{constructor(e,t){super(),this._source=e,this._filter=t}setFilter(e){this._filter=e,this._subscription&&this._reapplyFilter()}_reapplyFilter(e=!1){if(this._filter){this._included=this._included||new Map;for(const[t,s]of this._source){const i=this._filter(s,t),r=this._included.get(t);if(this._included.set(t,i),!e){const o=r||!0;this._emitForUpdate(o,i,t,s)}}}else{if(this._included&&!e)for(const[t,s]of this._source)this._included.get(t)||this.emitAdd(t,s);this._included=void 0}}onAdd(e,t){if(this._filter)if(this._included){const s=this._filter(t,e);if(this._included.set(e,s),!s)return}else throw new Error("Internal logic error: FilteredMap._included used before initialized");this.emitAdd(e,t)}onRemove(e,t){var i;const s=!this._filter||((i=this._included)==null?void 0:i.get(e));if(this._included)this._included.delete(e),s&&this.emitRemove(e,t);else throw new Error("Internal logic error: FilteredMap._included used before initialized")}onUpdate(e,t,s){if(!!this._included)if(this._filter){const i=this._included.get(e),r=this._filter(t,e);this._included.set(e,r),this._emitForUpdate(i,r,e,t,s)}else this.emitUpdate(e,t,s)}_emitForUpdate(e,t,s,i,r=null){e&&!t?this.emitRemove(s,i):!e&&t?this.emitAdd(s,i):e&&t&&this.emitUpdate(s,i,r)}onSubscribeFirst(){this._subscription=this._source.subscribe(this),this._reapplyFilter(!0),super.onSubscribeFirst()}onUnsubscribeLast(){super.onUnsubscribeLast(),this._included=void 0,this._subscription&&(this._subscription=this._subscription())}onReset(){this._reapplyFilter(),this.emitReset()}[Symbol.iterator](){return new vl(this._source,this._included)}get size(){var t;let e=0;return(t=this._included)==null||t.forEach(s=>{s&&(e+=1)}),e}get(e){const t=this._source.get(e);if(t&&this._filter(t,e))return t}}class vl{constructor(e,t){this._included=t,this._sourceIterator=e[Symbol.iterator]()}next(){var e;for(;;){const t=this._sourceIterator.next();if(t.done)return t;const s=t.value[0];if((e=this._included)!=null&&e.get(s))return t}}}class bl extends ci{constructor(e){super(),this._sources=e}onAdd(e,t,s){if(!this._isKeyAtSourceOccluded(e,t)){const i=this._getValueFromOccludedSources(e,t);i!==void 0&&this.emitRemove(t,i),this.emitAdd(t,s)}}onRemove(e,t,s){if(!this._isKeyAtSourceOccluded(e,t)){this.emitRemove(t,s);const i=this._getValueFromOccludedSources(e,t);i!==void 0&&this.emitAdd(t,i)}}onUpdate(e,t,s,i){!this._subscriptions||this._isKeyAtSourceOccluded(e,t)||this.emitUpdate(t,s,i)}onReset(){this.emitReset()}onSubscribeFirst(){this._subscriptions=this._sources.map(e=>new kl(e,this).subscribe()),super.onSubscribeFirst()}_isKeyAtSourceOccluded(e,t){const s=this._sources.indexOf(e);for(let i=0;ie+t.size,0)}get(e){for(const t of this._sources){const s=t.get(e);if(s)return s}}}class Sl{constructor(e){this._sourceIndex=-1,this._encounteredKeys=new Set,this._sources=e}next(){var t;let e;for(;!e;){if(!this._currentIterator){if(this._sourceIndex+=1,this._sources.length<=this._sourceIndex)return{done:!0,value:null};this._currentIterator=this._sources[this._sourceIndex][Symbol.iterator]()}const s=(t=this._currentIterator)==null?void 0:t.next();if(!s||s.done){this._currentIterator=void 0;continue}else{const i=s.value[0];this._encounteredKeys.has(i)||(this._encounteredKeys.add(i),e=s)}}return e}}class kl{constructor(e,t){this._source=e,this._joinedMap=t,this._subscription=void 0}subscribe(){return this._subscription=this._source.subscribe(this),this}dispose(){this._subscription&&(this._subscription=this._subscription())}onAdd(e,t){this._joinedMap.onAdd(this._source,e,t)}onRemove(e,t){this._joinedMap.onRemove(this._source,e,t)}onUpdate(e,t,s){this._joinedMap.onUpdate(this._source,e,t,s)}onReset(){this._joinedMap.onReset()}}class Il extends ci{constructor(e,t,s){super(),this._source=e,this._mapper=t,this._updater=s,this._mappedValues=new Map}_emitSpontaneousUpdate(e,t){const s=this._mappedValues.get(e);s&&this.emitUpdate(e,s,t)}onAdd(e,t){const s=this._emitSpontaneousUpdate.bind(this,e),i=this._mapper(t,s);this._mappedValues.set(e,i),this.emitAdd(e,i)}onRemove(e){const t=this._mappedValues.get(e);this._mappedValues.delete(e)&&t&&this.emitRemove(e,t)}onUpdate(e,t,s){var r;if(!this._mappedValues)return;const i=this._mappedValues.get(e);i!==void 0&&((r=this._updater)==null||r.call(this,s,i,t),this.emitUpdate(e,i,s))}onSubscribeFirst(){this._subscription=this._source.subscribe(this);for(let[e,t]of this._source){const s=this._emitSpontaneousUpdate.bind(this,e),i=this._mapper(t,s);this._mappedValues.set(e,i)}super.onSubscribeFirst()}onUnsubscribeLast(){super.onUnsubscribeLast(),this._subscription&&(this._subscription=this._subscription()),this._mappedValues.clear()}onReset(){this._mappedValues.clear(),this.emitReset()}[Symbol.iterator](){return this._mappedValues.entries()}get size(){return this._mappedValues.size}get(e){return this._mappedValues.get(e)}}class Dt extends ci{constructor(e){super(),this._values=new Map(e)}update(e,t){const s=this._values.get(e);return s!==void 0?(this._values.set(e,s),this.emitUpdate(e,s,t),!0):!1}add(e,t){return this._values.has(e)?!1:(this._values.set(e,t),this.emitAdd(e,t),!0)}remove(e){const t=this._values.get(e);return t!==void 0?(this._values.delete(e),this.emitRemove(e,t),!0):!1}set(e,t){return this._values.has(e)?(this._values.set(e,t),this.update(e,void 0)):this.add(e,t)}reset(){this._values.clear(),this.emitReset()}get(e){return this._values.get(e)}get size(){return this._values.size}[Symbol.iterator](){return this._values.entries()}values(){return this._values.values()}keys(){return this._values.keys()}}class Ml extends ci{constructor(e,t){super(),this.key=e,this.observableValue=t}onSubscribeFirst(){this.subscription=this.observableValue.subscribe(e=>{this.emitUpdate(this.key,e,void 0)}),super.onSubscribeFirst()}onUnsubscribeLast(){this.subscription(),super.onUnsubscribeLast()}*[Symbol.iterator](){yield[this.key,this.observableValue.get()]}get size(){return 1}get(e){if(e==this.key)return this.observableValue.get()}}class Cl extends yt{constructor(e){super(),this.map=e}onSubscribeFirst(){this.subscription=this.map.subscribe({onAdd:(e,t)=>{this.emit(this.get())},onRemove:(e,t)=>{this.emit(this.get())},onUpdate:(e,t)=>{},onReset:()=>{this.emit(this.get())}})}onUnsubscribeLast(){var e;this.subscription=(e=this.subscription)==null?void 0:e.call(this)}get(){return this.map.size}}const El={"image/jpeg":!0,"image/gif":!0,"image/png":!0,"video/mp4":!0,"video/webm":!0,"video/ogg":!0,"video/quicktime":!0,"video/VP8":!0,"audio/mp4":!0,"audio/webm":!0,"audio/aac":!0,"audio/mpeg":!0,"audio/ogg":!0,"audio/wave":!0,"audio/wav":!0,"audio/x-wav":!0,"audio/x-pn-wav":!0,"audio/flac":!0,"audio/x-flac":!0},Gn="application/octet-stream";class Ts{constructor(e,t=null){this._blob=e,this._buffer=t,this._url=null}static fromBuffer(e,t){return t=t?t.split(";")[0].trim():"",El[t]||(t=Gn),new Ts(new Blob([e],{type:t}),e)}static fromBlobUnsafe(e){return new Ts(e)}get nativeBlob(){return this._blob}async readAsBuffer(){if(this._buffer)return this._buffer;{const e=new FileReader,t=new Promise((s,i)=>{e.addEventListener("load",r=>s(r.target.result)),e.addEventListener("error",r=>i(r.target.error))});return e.readAsArrayBuffer(this._blob),t}}get url(){return this._url||(this._url=URL.createObjectURL(this._blob)),this._url}get size(){return this._blob.size}get mimeType(){return this._blob.type||Gn}dispose(){this._url&&(URL.revokeObjectURL(this._url),this._url=null)}}function la(n){return Object.entries(n||{}).filter(([,e])=>e!==void 0).map(([e,t])=>(typeof t=="object"&&(t=JSON.stringify(t)),`${encodeURIComponent(e)}=${encodeURIComponent(t)}`)).join("&")}function Rl(n){if(n instanceof Ts){const e=n;return{mimeType:e.mimeType,body:e}}else{if(n instanceof Map)return{mimeType:"multipart/form-data",body:n};if(typeof n=="object"){const e=JSON.stringify(n);return{mimeType:"application/json",body:e}}else throw new Error("Unknown body type: "+n)}}class ha extends Error{constructor(e,t){super(`${e}: ${t.message}`),this.cause=t}get name(){return"WrappedError"}}class da extends Error{constructor(e,t,s,i){super(`${s?s.error:i} on ${e} ${t}`),this.errcode=s?s.errcode:null,this.retry_after_ms=s?s.retry_after_ms:0,this.statusCode=i}get name(){return"HomeServerError"}}class Ut extends Error{constructor(e,t){super(e||"ConnectionError"),this.isTimeout=t}get name(){return"ConnectionError"}}class Tl{constructor(e,t,s,i){let r;if(i!=null&&i.log){const o=i==null?void 0:i.log;r=o.child({t:"network",url:t,method:e},o.level.Info)}this._log=r,this._sourceRequest=s,this._promise=s.response().then(o=>{var c,l;if(r==null||r.set("status",o.status),o.status>=200&&o.status<300||((c=i==null?void 0:i.allowedStatusCodes)==null?void 0:c.includes(o.status)))return r==null||r.finish(),o.body;if(o.status>=500){const h=new Ut("Internal Server Error");throw r==null||r.catch(h),h}else if(o.status>=400&&!((l=o.body)!=null&&l.errcode)){const h=new Ut(`HTTP error status ${o.status} without errcode in body, assume this is a load balancer complaining the server is offline.`);throw r==null||r.catch(h),h}else{const h=new da(e,t,o.body,o.status);throw r==null||r.set("errcode",h.errcode),r==null||r.catch(h),h}},o=>{if(o.name==="AbortError"&&this._sourceRequest){const c=new Ut("Service worker aborted, either updating or hit #187.");throw r==null||r.catch(c),c}else throw o.name==="ConnectionError"&&(r==null||r.set("timeout",o.isTimeout)),r==null||r.catch(o),o})}abort(){var e;this._sourceRequest&&((e=this._log)==null||e.set("aborted",!0),this._sourceRequest.abort(),this._sourceRequest=void 0)}response(){return this._promise}async responseCode(){return(await this._sourceRequest.response()).status}}const Ji="/_matrix/client/r0",Yn="/_matrix/client/v3",Lr="/_matrix/client/unstable/org.matrix.msc2697.v2";class ws{constructor({homeserver:e,accessToken:t,request:s,reconnector:i}){this._homeserver=e,this._accessToken=t,this._requestFn=s,this._reconnector=i}_url(e,t=Ji){return this._homeserver+t+e}_baseRequest(e,t,s,i,r,o){const c=la(s);t=`${t}?${c}`;let l;const h=new Map;if(o&&h.set("Authorization",`Bearer ${o}`),h.set("Accept","application/json"),i){const p=Rl(i);h.set("Content-Type",p.mimeType),l=p.body}const a=this._requestFn(t,{method:e,headers:h,body:l,timeout:r==null?void 0:r.timeout,uploadProgress:r==null?void 0:r.uploadProgress,format:"json",cache:e!=="GET"}),u=new Tl(e,t,a,r);return this._reconnector&&u.response().catch(p=>{p.name==="ConnectionError"&&this._reconnector.onRequestFailed(this)}),u}_unauthedRequest(e,t,s,i,r){return this._baseRequest(e,t,s,i,r)}_authedRequest(e,t,s,i,r){return this._baseRequest(e,t,s,i,r,this._accessToken)}_post(e,t,s,i){return this._authedRequest("POST",this._url(e,(i==null?void 0:i.prefix)||Ji),t,s,i)}_put(e,t,s,i){return this._authedRequest("PUT",this._url(e,(i==null?void 0:i.prefix)||Ji),t,s,i)}_get(e,t,s,i){return this._authedRequest("GET",this._url(e,(i==null?void 0:i.prefix)||Ji),t,s,i)}updateAccessToken(e){this._accessToken=e}sync(e,t,s,i){return this._get("/sync",{since:e,timeout:s,filter:t},void 0,i)}context(e,t,s,i){return this._get(`/rooms/${encodeURIComponent(e)}/context/${encodeURIComponent(t)}`,{filter:i,limit:s})}messages(e,t,s){return this._get(`/rooms/${encodeURIComponent(e)}/messages`,t,void 0,s)}members(e,t,s){return this._get(`/rooms/${encodeURIComponent(e)}/members`,t,void 0,s)}send(e,t,s,i,r){return this._put(`/rooms/${encodeURIComponent(e)}/send/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,{},i,r)}redact(e,t,s,i,r){return this._put(`/rooms/${encodeURIComponent(e)}/redact/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,{},i,r)}receipt(e,t,s,i){return this._post(`/rooms/${encodeURIComponent(e)}/receipt/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,{},{},i)}state(e,t,s,i){return this._get(`/rooms/${encodeURIComponent(e)}/state/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,{},void 0,i)}sendState(e,t,s,i,r){return this._put(`/rooms/${encodeURIComponent(e)}/state/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,{},i,r)}getLoginFlows(){return this._unauthedRequest("GET",this._url("/login"))}register(e,t,s,i,r=!1,o={}){o.allowedStatusCodes=[401];const c={auth:i,password:t,initial_device_displayname:s,inhibit_login:r};return e&&(c.username=e),this._unauthedRequest("POST",this._url("/register",Yn),void 0,c,o)}passwordLogin(e,t,s,i){return this._unauthedRequest("POST",this._url("/login"),void 0,{type:"m.login.password",identifier:{type:"m.id.user",user:e},password:t,initial_device_display_name:s},i)}tokenLogin(e,t,s,i){return this._unauthedRequest("POST",this._url("/login"),void 0,{type:"m.login.token",identifier:{type:"m.id.user"},token:e,txn_id:t,initial_device_display_name:s},i)}createFilter(e,t,s){return this._post(`/user/${encodeURIComponent(e)}/filter`,{},t,s)}versions(e){return this._unauthedRequest("GET",`${this._homeserver}/_matrix/client/versions`,void 0,void 0,e)}uploadKeys(e,t,s){let i="/keys/upload";return e&&(i=i+`/${encodeURIComponent(e)}`),this._post(i,{},t,s)}uploadSignatures(e,t){return this._post("/keys/signatures/upload",{},e,t)}queryKeys(e,t){return this._post("/keys/query",{},e,t)}claimKeys(e,t){return this._post("/keys/claim",{},e,t)}sendToDevice(e,t,s,i){return this._put(`/sendToDevice/${encodeURIComponent(e)}/${encodeURIComponent(s)}`,{},t,i)}roomKeysVersion(e,t){let s="";return e&&(s=`/${encodeURIComponent(e)}`),this._get(`/room_keys/version${s}`,void 0,void 0,t)}roomKeyForRoomAndSession(e,t,s,i){return this._get(`/room_keys/keys/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,{version:e},void 0,i)}uploadRoomKeysToBackup(e,t,s={}){return s.prefix=Yn,this._put("/room_keys/keys",{version:e},t,s)}uploadAttachment(e,t,s){return this._authedRequest("POST",`${this._homeserver}/_matrix/media/r0/upload`,{filename:t},e,s)}setPusher(e,t){return this._post("/pushers/set",{},e,t)}getPushers(e){return this._get("/pushers",void 0,void 0,e)}invite(e,t,s,i){return this._post(`/rooms/${encodeURIComponent(e)}/invite`,{},{user_id:t,reason:s},i)}join(e,t){return this._post(`/rooms/${encodeURIComponent(e)}/join`,{},{},t)}joinIdOrAlias(e,t){return this._post(`/join/${encodeURIComponent(e)}`,{},{},t)}leave(e,t){return this._post(`/rooms/${encodeURIComponent(e)}/leave`,{},{},t)}forget(e,t){return this._post(`/rooms/${encodeURIComponent(e)}/forget`,{},{},t)}logout(e){return this._post("/logout",{},{},e)}getDehydratedDevice(e={}){return e.prefix=Lr,this._get("/dehydrated_device",void 0,void 0,e)}createDehydratedDevice(e,t={}){return t.prefix=Lr,this._put("/dehydrated_device",{},e,t)}claimDehydratedDevice(e,t={}){return t.prefix=Lr,this._post("/dehydrated_device/claim",{},{device_id:e},t)}profile(e,t){return this._get(`/profile/${encodeURIComponent(e)}`)}createRoom(e,t){return this._post("/createRoom",{},e,t)}setAccountData(e,t,s,i){return this._put(`/user/${encodeURIComponent(e)}/account_data/${encodeURIComponent(t)}`,{},s,i)}getTurnServer(e){return this._get("/voip/turnServer",void 0,void 0,e)}}class ua{constructor(e){this._start=2e3,this._current=2e3;const t=2e3;this._start=t,this._current=t,this._createTimeout=e,this._max=60*5*1e3}async waitForRetry(){this._timeout=this._createTimeout(this._current);try{await this._timeout.elapsed();const e=2*this._current;this._current=Math.min(this._max,e)}catch(e){if(!(e instanceof rt))throw e}finally{this._timeout=void 0}}abort(){this._timeout&&this._timeout.abort()}reset(){this._current=this._start,this.abort()}get nextValue(){return this._current}}var Ys=(n=>(n[n.Waiting=0]="Waiting",n[n.Reconnecting=1]="Reconnecting",n[n.Online=2]="Online",n))(Ys||{});class Al{constructor({retryDelay:e,createMeasure:t,onlineStatus:s}){this._onlineStatus=s,this._retryDelay=e,this._createTimeMeasure=t,this._state=new Vt(2),this._isReconnecting=!1}get lastVersionsResponse(){return this._versionsResponse}get connectionStatus(){return this._state}get retryIn(){return this._state.get()===0?this._retryDelay.nextValue-this._stateSince.measure():0}async onRequestFailed(e){if(!this._isReconnecting){this._isReconnecting=!0;const t=this._onlineStatus&&this._onlineStatus.subscribe(s=>{s&&this.tryNow()});try{await this._reconnectLoop(e)}catch(s){console.error(s)}finally{t&&t(),this._isReconnecting=!1}}}tryNow(){this._retryDelay&&this._retryDelay.abort()}_setState(e){e!==this._state.get()&&(e===0?this._stateSince=this._createTimeMeasure():this._stateSince=null,this._state.set(e))}async _reconnectLoop(e){for(this._versionsResponse=void 0,this._retryDelay.reset();!this._versionsResponse;)try{this._setState(1);const t=e.versions({timeout:3e4});this._versionsResponse=await t.response(),this._setState(2)}catch(t){if(t.name==="ConnectionError")this._setState(0),await this._retryDelay.waitForRetry();else throw t}}}async function xl(n,e,t){if(t===void 0||t.key===void 0||t.iv===void 0||t.hashes===void 0||t.hashes.sha256===void 0)throw new Error("Invalid info. Missing info.key, info.iv or info.hashes.sha256 key");const{crypto:s}=n,{base64:i}=n.encoding;var r=i.decode(t.iv),o=i.encode(i.decode(t.hashes.sha256));const c=await s.digest("SHA-256",e);if(i.encode(new Uint8Array(c))!=o)throw new Error("Mismatched SHA-256 digest");var l;return t.v=="v1"||t.v=="v2"?l=64:l=128,await s.aes.decryptCTR({jwkKey:t.key,iv:r,data:e,counterLength:l})}async function Vl(n,e){const{crypto:t}=n,{base64:s}=n.encoding,i=await t.aes.generateIV(),r=await t.aes.generateKey("jwk",256),o=await e.readAsBuffer(),c=await t.aes.encryptCTR({jwkKey:r,iv:i,data:o}),l=await t.digest("SHA-256",c);return{blob:n.createBlob(c,"application/octet-stream"),info:{v:"v2",key:r,iv:s.encodeUnpadded(i),hashes:{sha256:s.encodeUnpadded(l)}}}}class Nl{constructor(e){this.homeserver=e.homeserver,this.platform=e.platform,this.generateMediaUrl(e.serverVersions)}generateMediaUrl(e){const t="v1.11";e.includes(t)?this.mediaUrlPart="_matrix/client/v1/media":this.mediaUrlPart="_matrix/media/v3"}mxcUrlThumbnail(e,t,s,i){const r=this.parseMxcUrl(e);if(r){const[o,c]=r;return`${this.homeserver}/${this.mediaUrlPart}/thumbnail/${encodeURIComponent(o)}/${encodeURIComponent(c)}`+"?"+la({width:Math.round(t),height:Math.round(s),method:i})}}mxcUrl(e){const t=this.parseMxcUrl(e);if(t){const[s,i]=t;return`${this.homeserver}/${this.mediaUrlPart}/download/${encodeURIComponent(s)}/${encodeURIComponent(i)}`}}parseMxcUrl(e){const t="mxc://";if(e.startsWith(t))return e.slice(t.length).split("/",2)}async downloadEncryptedFile(e,t=!1){const s=this.mxcUrl(e.url),{body:i}=await this.platform.request(s,{method:"GET",format:"buffer",cache:t}).response(),r=await xl(this.platform,i,e);return this.platform.createBlob(r,e.mimetype)}async downloadPlaintextFile(e,t,s=!1){const i=this.mxcUrl(e),{body:r}=await this.platform.request(i,{method:"GET",format:"buffer",cache:s}).response();return this.platform.createBlob(r,t)}async downloadAttachment(e,t=!1){var s;return e.file?this.downloadEncryptedFile(e.file,t):this.downloadPlaintextFile(e.url,(s=e.info)==null?void 0:s.mimetype,t)}}class Dl{constructor(e,t){this.methodName=e,this.args=t,this._responsePromise=new Promise((s,i)=>{this.responseResolve=s,this.responseReject=i})}abort(){var e;this._requestResult?this._requestResult.abort():(this.responseReject(new rt),(e=this.responseCodeReject)==null||e.call(this,new rt))}response(){return this._responsePromise}responseCode(){return this.requestResult?this.requestResult.responseCode():(this._responseCodePromise||(this._responseCodePromise=new Promise((e,t)=>{this.responseCodeResolve=e,this.responseCodeReject=t})),this._responseCodePromise)}async setRequestResult(e){var i,r,o;this._requestResult=e;const t=await((i=this._requestResult)==null?void 0:i.response());this.responseResolve(t);const s=await((r=this._requestResult)==null?void 0:r.responseCode());(o=this.responseCodeResolve)==null||o.call(this,s)}get requestResult(){return this._requestResult}}class ma{constructor(e){this._scheduler=e}}for(const n of Object.getOwnPropertyNames(ws.prototype))n!=="constructor"&&!n.startsWith("_")&&(ma.prototype[n]=function(...e){return this._scheduler._hsApiRequest(n,e)});class Ul{constructor({hsApi:e,clock:t}){this._requests=new Set,this._stopped=!1,this._wrapper=new ma(this),this._hsApi=e,this._clock=t}get hsApi(){return this._wrapper}stop(){this._stopped=!0;for(const e of this._requests)e.abort();this._requests.clear()}start(){this._stopped=!1}_hsApiRequest(e,t){const s=new Dl(e,t);return this._doSend(s),s}async _doSend(e){this._requests.add(e);try{let t;for(;!this._stopped;)try{const s=this._hsApi[e.methodName].apply(this._hsApi,e.args);await e.setRequestResult(s);return}catch(s){if(s instanceof da&&s.errcode==="M_LIMIT_EXCEEDED")Number.isSafeInteger(s.retry_after_ms)?await this._clock.createTimeout(s.retry_after_ms).elapsed():(t||(t=new ua(this._clock.createTimeout)),await t.waitForRetry());else{e.responseReject(s);return}}this._stopped&&e.abort()}finally{this._requests.delete(e)}}}const Ol=3e4,te=oi("InitialSync","CatchupSync","Syncing","Stopped");function Pl(n){var e;try{const t=(e=n==null?void 0:n.timeline)==null?void 0:e.events;return Array.isArray(t)&&t.length===0}catch{return!0}}class Fl{constructor({hsApi:e,session:t,storage:s,logger:i}){this._hsApi=e,this._logger=i,this._session=t,this._storage=s,this._currentRequest=null,this._status=new Vt(te.Stopped),this._error=null}get status(){return this._status}get error(){return this._error}start(){if(this._status.get()!==te.Stopped)return;this._error=null;let e=this._session.syncToken;e?this._status.set(te.CatchupSync):this._status.set(te.InitialSync),this._syncLoop(e)}async _syncLoop(e){for(;this._status.get()!==te.Stopped;){let t,s,i=this._status.get()===te.CatchupSync||this._status.get()===te.InitialSync;await this._logger.run("sync",async r=>{r.set("token",e),r.set("status",this._status.get());try{const o=this._status.get()===te.Syncing?Ol:0,c=await this._syncRequest(e,o,r);e=c.syncToken,t=c.roomStates,s=c.sessionChanges,this._status.get()!==te.Syncing&&c.hadToDeviceMessages?this._status.set(te.CatchupSync):this._status.set(te.Syncing)}catch(o){if(o.name==="ConnectionError"&&o.isTimeout)return;this._error=o,o.name!=="AbortError"&&(r.error=o,r.logLevel=r.level.Fatal),r.set("stopping",!0),this._status.set(te.Stopped)}this._status.get()!==te.Stopped&&await r.wrap("afterSyncCompleted",o=>this._runAfterSyncCompleted(s,t,o))},this._logger.level.Info,(r,o)=>o.durationWithoutType("network")>=2e3||o.error||i?r.minLevel(o.level.Detail):r.minLevel(o.level.Info))}}async _runAfterSyncCompleted(e,t,s){const i=this._status.get()===te.CatchupSync,r=(async()=>{try{await s.wrap("session",c=>this._session.afterSyncCompleted(e,i,c))}catch{}})(),o=t.map(async c=>{try{await c.room.afterSyncCompleted(c.changes,s)}catch{}});await Promise.all(o.concat(r))}async _syncRequest(e,t,s){var g;let{syncFilterId:i}=this._session;typeof i!="string"&&(this._currentRequest=this._hsApi.createFilter(this._session.user.id,{room:{state:{lazy_load_members:!0}}},{log:s}),i=(await this._currentRequest.response()).filter_id);const r=t+80*1e3;this._currentRequest=this._hsApi.sync(e,i,t,{timeout:r,log:s});const o=await this._currentRequest.response(),c=!e,l=new Ll,h=this._parseInvites(o.rooms),{roomStates:a,archivedRoomStates:u}=await this._parseRoomsResponse(o.rooms,h,c,s);try{l.lock=await s.wrap("obtainSyncLock",()=>this._session.obtainSyncLock(o)),await s.wrap("prepare",f=>this._prepareSync(l,a,o,f)),await s.wrap("afterPrepareSync",f=>Promise.all(a.map(v=>v.room.afterPrepareSync(v.preparation,f)))),await s.wrap("write",async f=>this._writeSync(l,h,a,u,o,i,c,f))}finally{l.dispose()}s.wrap("after",f=>this._afterSync(l,h,a,u,f));const p=(g=o.to_device)==null?void 0:g.events;return{syncToken:o.next_batch,roomStates:a,sessionChanges:l.changes,hadToDeviceMessages:Array.isArray(p)&&p.length>0}}_openPrepareSyncTxn(){const e=this._storage.storeNames;return this._storage.readTxn([e.deviceKeys,e.olmSessions,e.inboundGroupSessions,e.timelineFragments,e.timelineEvents])}async _prepareSync(e,t,s,i){var c,l;const r=await this._openPrepareSyncTxn();e.preparation=await i.wrap("session",h=>this._session.prepareSync(s,e.lock,r,h));const o=(c=e.preparation)==null?void 0:c.newKeysByRoom;if(o){const{hasOwnProperty:h}=Object.prototype;for(const a of o.keys())if(!(((l=s.rooms)==null?void 0:l.join)&&h.call(s.rooms.join,a))){let p=this._session.rooms.get(a);p&&t.push(new Jn(p,!1,{},p.membership))}}await Promise.all(t.map(async h=>{const a=o==null?void 0:o.get(h.room.id);h.preparation=await i.wrap("room",async u=>(h.isNewRoom&&await h.room.load(null,r,u),h.room.prepareSync(h.roomResponse,h.membership,a,r,u)),i.level.Detail)})),await r.complete()}async _writeSync(e,t,s,i,r,o,c,l){const h=await this._openSyncTxn();try{e.changes=await l.wrap("session",a=>this._session.writeSync(r,o,e.preparation,h,a)),await Promise.all(t.map(async a=>{a.changes=await l.wrap("invite",u=>a.invite.writeSync(a.membership,a.roomResponse,h,u))})),await Promise.all(s.map(async a=>{a.changes=await l.wrap("room",u=>a.room.writeSync(a.roomResponse,c,a.preparation,h,u))})),await Promise.all(i.map(async a=>{var p;const u=(p=a.roomState)==null?void 0:p.summaryChanges;a.changes=await l.wrap("archivedRoom",g=>a.archivedRoom.writeSync(u,a.roomResponse,a.membership,h,g))}))}catch(a){throw h.abort(l),h.getCause(a)}await h.complete(l)}_afterSync(e,t,s,i,r){r.wrap("session",o=>this._session.afterSync(e.changes,o),r.level.Detail);for(let o of i)r.wrap("archivedRoom",c=>{o.archivedRoom.afterSync(o.changes,c),o.archivedRoom.release()},r.level.Detail);for(let o of s)r.wrap("room",c=>o.room.afterSync(o.changes,c),r.level.Detail);for(let o of t)r.wrap("invite",c=>o.invite.afterSync(o.changes,c),r.level.Detail);this._session.applyRoomCollectionChangesAfterSync(t,s,i,r)}_openSyncTxn(){const e=this._storage.storeNames;return this._storage.readWriteTxn([e.session,e.roomSummary,e.archivedRoomSummary,e.invites,e.roomState,e.roomMembers,e.timelineEvents,e.timelineRelations,e.timelineFragments,e.pendingEvents,e.userIdentities,e.groupSessionDecryptions,e.deviceKeys,e.outboundGroupSessions,e.operations,e.accountData,e.olmSessions,e.inboundGroupSessions,e.calls])}async _parseRoomsResponse(e,t,s,i){const r=[],o=[];if(e){const c=["join","leave"];for(const l of c){const h=e[l];if(h)for(const[a,u]of Object.entries(h)){if(s&&Pl(u))continue;const p=this._session.invites.get(a);p&&t.push(new Qn(p,!1,null,l));const g=this._createRoomSyncState(a,u,l,s);g&&r.push(g);const f=await this._createArchivedRoomSyncState(a,g,u,l,s,i);f&&o.push(f)}}}return{roomStates:r,archivedRoomStates:o}}_createRoomSyncState(e,t,s,i){let r=!1,o=this._session.rooms.get(e);if(!o&&(s==="join"||i&&s==="leave")&&(o=this._session.createJoinedRoom(e),r=!0),o)return new Jn(o,r,t,s)}async _createArchivedRoomSyncState(e,t,s,i,r,o){let c;if((t==null?void 0:t.shouldAdd)&&!r?c=this._session.createOrGetArchivedRoomForSync(e):i==="leave"&&(t?c=this._session.createOrGetArchivedRoomForSync(e):c=await this._session.loadArchivedRoom(e,o)),c)return new Kl(c,t,s,i)}_parseInvites(e){const t=[];if(e!=null&&e.invite)for(const[s,i]of Object.entries(e.invite)){let r=this._session.invites.get(s),o=!1;r||(r=this._session.createInvite(s),o=!0),t.push(new Qn(r,o,i,"invite"))}return t}stop(){this._status.get()!==te.Stopped&&(this._status.set(te.Stopped),this._currentRequest&&(this._currentRequest.abort(),this._currentRequest=null))}}class Ll{constructor(){this.lock=null,this.preparation=null,this.changes=null}dispose(){var e;(e=this.lock)==null||e.release()}}class Jn{constructor(e,t,s,i){this.room=e,this.isNewRoom=t,this.roomResponse=s,this.membership=i,this.preparation=null,this.changes=null}get id(){return this.room.id}get shouldAdd(){return this.isNewRoom&&this.membership==="join"}get shouldRemove(){return!this.isNewRoom&&this.membership!=="join"}get summaryChanges(){var e;return(e=this.changes)==null?void 0:e.summaryChanges}}class Kl{constructor(e,t,s,i,r){this.archivedRoom=e,this.roomState=t,this.roomResponse=s,this.membership=i,this.isInitialSync=r,this.changes=null}get id(){return this.archivedRoom.id}get shouldAdd(){return(this.roomState||this.isInitialSync)&&this.membership==="leave"}get shouldRemove(){return this.membership==="join"}}class Qn{constructor(e,t,s,i){this.invite=e,this.isNewInvite=t,this.membership=i,this.roomResponse=s,this.changes=null}get id(){return this.invite.id}get shouldAdd(){return this.isNewInvite}get shouldRemove(){return this.membership!=="invite"}}function _a(n){if(n.__esModule)return n;var e=Object.defineProperty({},"__esModule",{value:!0});return Object.keys(n).forEach(function(t){var s=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:function(){return n[t]}})}),e}var Xn=/[\\\"\x00-\x1F]/g,jt={};for(var Qi=0;Qi<32;++Qi)jt[String.fromCharCode(Qi)]="\\U"+("0000"+Qi.toString(16)).slice(-4).toUpperCase();jt["\b"]="\\b";jt[" "]="\\t";jt[` +`]="\\n";jt["\f"]="\\f";jt["\r"]="\\r";jt['"']='\\"';jt["\\"]="\\\\";function pa(n){return Xn.lastIndex=0,n.replace(Xn,function(e){return jt[e]})}function yn(n){switch(typeof n){case"string":return'"'+pa(n)+'"';case"number":return isFinite(n)?n:"null";case"boolean":return n;case"object":return n===null?"null":Array.isArray(n)?Bl(n):$l(n);default:throw new Error("Cannot stringify: "+typeof n)}}function Bl(n){for(var e="[",t="",s=0;s(n[n.Sync=0]="Sync",n[n.Timeline=1]="Timeline",n[n.Retry=2]="Retry",n))(ts||{});const Oe="e2ee:",wn="m.olm.v1.curve25519-aes-sha2",ft="m.megolm.v1.aes-sha2";class fe extends Error{constructor(e,t,s){super(`Decryption error ${e}${s?": "+JSON.stringify(s):""}`),this.code=e,this.event=t,this.detailsObj=s}}const jl="ed25519";function ks(n){return n.keys[`ed25519:${n.device_id}`]}function _t(n){return n.keys[`curve25519:${n.device_id}`]}function ql(n,e,t){var s,i;return(i=(s=n==null?void 0:n.signatures)==null?void 0:s[e])==null?void 0:i[`${jl}:${t}`]}var ne=(n=>(n[n.Valid=0]="Valid",n[n.Invalid=1]="Invalid",n[n.NotSigned=2]="NotSigned",n))(ne||{});function vn(n,e,t,s,i,r){const o=ql(i,e,t);if(!o)return r==null||r.set("no_signature",!0),2;const c=Object.assign({},i);delete c.unsigned,delete c.signatures;const l=qi.stringify(c);try{return n.ed25519_verify(s,l,o),0}catch(h){if(r){const a=r.log({l:"Invalid signature, ignoring.",ed25519Key:s,canonicalJson:l,signature:o});a.error=h,a.logLevel=r.level.Warn}return 1}}function Hl(){return{type:"m.room.encryption",state_key:"",content:{algorithm:ft,rotation_period_ms:6048e5,rotation_period_msgs:100}}}function Xi(n,e){switch(e){case"world_readable":return!0;case"shared":return n!==void 0;case"joined":return n==="join";case"invited":return n==="invite"||n==="join";default:return!1}}function Qr(n){var e;return((e=n.unsigned)==null?void 0:e.prev_content)||n.prev_content}const gt="m.room.redaction";function Xr(n){var e;return!!((e=n==null?void 0:n.unsigned)!=null&&e.redacted_because)}var se=(n=>(n[n.None=1]="None",n[n.BeingCreated=2]="BeingCreated",n[n.Invited=4]="Invited",n[n.Joined=8]="Joined",n[n.Replaced=16]="Replaced",n[n.Archived=32]="Archived",n))(se||{}),Le=(n=>(n[n.DirectMessage=0]="DirectMessage",n[n.Private=1]="Private",n[n.Public=2]="Public",n))(Le||{});function Js(n,e){var o,c;let t;const s=l=>{const h=e(l);h instanceof Promise&&(t=t!=null?t:[],t.push(h))},i=(o=n.state)==null?void 0:o.events;if(i)for(let l=0;l{})}function Wl(n,e,t,s,i){return e.length&&(n=e.reduce((r,o)=>Jl(r,o,t,s,i),n)),n}function zl(n,e,t,s){e.summary&&(n=Ql(n,e.summary)),t!==n.membership&&(n=n.cloneIfNeeded(),n.membership=t),e.account_data&&(n=e.account_data.events.reduce(Yl,n)),Js(e,r=>{n=ga(n,r,s)});const i=e.unread_notifications;return i&&(n=Gl(n,i)),n}function Gl(n,e){const t=e.highlight_count||0;t!==n.highlightCount&&(n=n.cloneIfNeeded(),n.highlightCount=t);const s=e.notification_count;return s!==n.notificationCount&&(n=n.cloneIfNeeded(),n.notificationCount=s),n}function Yl(n,e){var t;if((e==null?void 0:e.type)==="m.tag"){let s=(t=e==null?void 0:e.content)==null?void 0:t.tags;(!s||Array.isArray(s)||typeof s!="object")&&(s=null),n=n.cloneIfNeeded(),n.tags=s}return n}function ga(n,e,t){var s,i,r;if(e.type==="m.room.create")n=n.cloneIfNeeded(),n.lastMessageTimestamp=e.origin_server_ts;else if(e.type==="m.room.encryption"){const o=(s=e.content)==null?void 0:s.algorithm;!n.encryption&&o===ft&&(n=n.cloneIfNeeded(),n.encryption=e.content)}else if(e.type==="m.room.name"){const o=(i=e.content)==null?void 0:i.name;o!==n.name&&(n=n.cloneIfNeeded(),n.name=o)}else if(e.type==="m.room.avatar"){const o=(r=e.content)==null?void 0:r.url;o!==n.avatarUrl&&(n=n.cloneIfNeeded(),n.avatarUrl=o)}else if(e.type==="m.room.canonical_alias"){const o=e.content;n=n.cloneIfNeeded(),n.canonicalAlias=o.alias}else if(e.type==="m.room.member"){const o=e.content;if(o.is_direct===!0&&o.membership==="invite"&&!n.isDirectMessage){let c;e.sender===t?c=e.state_key:e.state_key===t&&(c=e.sender),c&&(n=n.cloneIfNeeded(),n.isDirectMessage=!0,n.dmUserId=c)}else o.membership==="leave"&&n.isDirectMessage&&n.dmUserId===e.state_key&&(n=n.cloneIfNeeded(),n.isDirectMessage=!1,n.dmUserId=null)}return n}function Jl(n,e,t,s,i){return e.eventType==="m.room.message"&&((!n.lastMessageTimestamp||e.timestamp>n.lastMessageTimestamp)&&(n=n.cloneIfNeeded(),n.lastMessageTimestamp=e.timestamp),!t&&e.sender!==i&&s&&(n=n.cloneIfNeeded(),n.isUnread=!0)),n}function Ql(n,e){const t=e["m.heroes"],s=e["m.joined_member_count"],i=e["m.invited_member_count"];return t&&Array.isArray(t)&&(n=n.cloneIfNeeded(),n.heroes=t),Number.isInteger(i)&&(n=n.cloneIfNeeded(),n.inviteCount=i),Number.isInteger(s)&&(n=n.cloneIfNeeded(),n.joinCount=s),n}class Rt{constructor(e,t){this.roomId=e?e.roomId:t,this.name=e?e.name:null,this.lastMessageTimestamp=e?e.lastMessageTimestamp:null,this.isUnread=e?e.isUnread:!1,this.encryption=e?e.encryption:null,this.membership=e?e.membership:null,this.inviteCount=e?e.inviteCount:0,this.joinCount=e?e.joinCount:0,this.heroes=e?e.heroes:null,this.canonicalAlias=e?e.canonicalAlias:null,this.hasFetchedMembers=e?e.hasFetchedMembers:!1,this.isTrackingMembers=e?e.isTrackingMembers:!1,this.avatarUrl=e?e.avatarUrl:null,this.notificationCount=e?e.notificationCount:0,this.highlightCount=e?e.highlightCount:0,this.tags=e?e.tags:null,this.isDirectMessage=e?e.isDirectMessage:!1,this.dmUserId=e?e.dmUserId:null,this.cloned=!!e}changedKeys(e){return Object.getOwnPropertyNames(this).filter(s=>s!=="cloned"&&this[s]!==e[s])}cloneIfNeeded(){return this.cloned?this:new Rt(this)}serialize(){return Object.entries(this).reduce((e,[t,s])=>(t!=="cloned"&&s!==null&&(e[t]=s),e),{})}applyTimelineEntries(e,t,s,i){return Wl(this,e,t,s,i)}applySyncResponse(e,t,s){return zl(this,e,t,s)}get needsHeroes(){return!this.name&&!this.canonicalAlias&&this.heroes&&this.heroes.length>0}isNewJoin(e){return this.membership==="join"&&e.membership!=="join"}}class Xl{constructor(e){this._data=null,this.applyChanges(new Rt(null,e))}get data(){return this._data}writeClearUnread(e){const t=new Rt(this._data);return t.isUnread=!1,t.notificationCount=0,t.highlightCount=0,e.roomSummary.set(t.serialize()),t}writeHasFetchedMembers(e,t){const s=new Rt(this._data);return s.hasFetchedMembers=e,t.roomSummary.set(s.serialize()),s}writeIsTrackingMembers(e,t){const s=new Rt(this._data);return s.isTrackingMembers=e,t.roomSummary.set(s.serialize()),s}writeData(e,t){if(e!==this._data)return t.roomSummary.set(e.serialize()),e}writeArchivedData(e,t){if(e!==this._data)return t.archivedRoomSummary.set(e.serialize()),e}async writeAndApplyData(e,t){if(e===this._data)return!1;const s=await t.readWriteTxn([t.storeNames.roomSummary]);try{s.roomSummary.set(e.serialize())}catch(i){throw s.abort(),i}return await s.complete(),this.applyChanges(e),!0}applyChanges(e){this._data=e,this._data.cloned=!1}async load(e){this.applyChanges(new Rt(e))}}var J=(n=>(n.session="session",n.roomState="roomState",n.roomSummary="roomSummary",n.archivedRoomSummary="archivedRoomSummary",n.invites="invites",n.roomMembers="roomMembers",n.timelineEvents="timelineEvents",n.timelineRelations="timelineRelations",n.timelineFragments="timelineFragments",n.pendingEvents="pendingEvents",n.userIdentities="userIdentities",n.deviceKeys="deviceKeys",n.olmSessions="olmSessions",n.inboundGroupSessions="inboundGroupSessions",n.outboundGroupSessions="outboundGroupSessions",n.groupSessionDecryptions="groupSessionDecryptions",n.operations="operations",n.accountData="accountData",n.calls="calls",n.crossSigningKeys="crossSigningKeys",n.sharedSecrets="sharedSecrets",n))(J||{});const Oi=Object.values(J);class Ot extends Error{constructor(e,t=null){super(e),t&&(this.errcode=t.name),this.cause=t}get name(){return"StorageError"}}const ce={get minStorageKey(){return 0},get middleStorageKey(){return 2147483647},get maxStorageKey(){return 4294967295}};class pe{constructor(e,t){this.fragmentId=e,this.eventIndex=t}nextFragmentKey(){return new pe(this.fragmentId+1,ce.middleStorageKey)}nextKeyForDirection(e){return e.isForward?this.nextKey():this.previousKey()}previousKey(){return new pe(this.fragmentId,this.eventIndex-1)}nextKey(){return new pe(this.fragmentId,this.eventIndex+1)}static get maxKey(){return new pe(ce.maxStorageKey,ce.maxStorageKey)}static get minKey(){return new pe(ce.minStorageKey,ce.minStorageKey)}static get defaultLiveKey(){return pe.defaultFragmentKey(ce.minStorageKey)}static defaultFragmentKey(e){return new pe(e,ce.middleStorageKey)}toString(){return`[${this.fragmentId}/${this.eventIndex}]`}equals(e){return this.fragmentId===(e==null?void 0:e.fragmentId)&&this.eventIndex===(e==null?void 0:e.eventIndex)}}const Zr=Number.MAX_SAFE_INTEGER;class fa{constructor(e){this._fragmentIdComparer=e}compare(e){return this.fragmentId===e.fragmentId?this.entryIndex-e.entryIndex:this.fragmentId===Zr?1:e.fragmentId===Zr?-1:this._fragmentIdComparer.compare(this.fragmentId,e.fragmentId)}asEventKey(){return new pe(this.fragmentId,this.entryIndex)}}const Zl="m.reaction",ss="m.annotation",ya="m.reference";function eh(n,e){return{"m.relates_to":{event_id:n,key:e,rel_type:ss}}}function th(n){return{"m.relates_to":{event_id:n,rel_type:ya}}}function bn(n){var e;return n.event_id||((e=n["m.in_reply_to"])==null?void 0:e.event_id)}function wa(n,e){n.event_id!==void 0?n.event_id=e:n["m.in_reply_to"]&&(n["m.in_reply_to"].event_id=e)}function va(n){if(n.type===gt)return n.redacts;{const e=Xt(n);if(e)return bn(e)}return null}function rs(n){return n==null?void 0:n["m.relates_to"]}function Xt(n){return rs(n.content)}class sh{constructor(){this._entries=[]}get firstTimestamp(){return this._entries.reduce((e,t)=>t.isRedaction?e:Math.min(t.timestamp,e),Number.MAX_SAFE_INTEGER)}get annotationEntry(){return this._entries.find(e=>!e.isRedaction)}get redactionEntry(){return this._entries.find(e=>e.isRedaction)}get count(){return this._entries.reduce((e,t)=>e+(t.isRedaction?-1:1),0)}add(e){this._entries.push(e)}remove(e){const t=this._entries.indexOf(e);return t===-1?!1:(this._entries.splice(t,1),!0)}get willAnnotate(){const e=this._entries.reduce((t,s)=>!t||s.pendingEvent.queueIndex>t.pendingEvent.queueIndex?s:t,null);return e?!e.isRedaction:!1}get isEmpty(){return this._entries.length===0}}function Zn(n){return n.replace(/&/g,"&").replace(//g,">")}function ih(n){switch(n){case"m.file":return"sent a file.";case"m.image":return"sent an image.";case"m.video":return"sent a video.";case"m.audio":return"sent an audio file."}return null}function rh(n){return n==="m.emote"?"* ":""}function nh(n,e,t,s){return{msgtype:e,body:t,format:"org.matrix.custom.html",formatted_body:s,"m.relates_to":{"m.in_reply_to":{event_id:n}}}}function oh(n,e,t){const s=ih(n.content.msgtype),i=rh(n.content.msgtype),r=n.sender,o=n.displayName||r,c=s||n.content.formatted_body||n.content.body&&Zn(n.content.body)||"",l=`
In reply to ${i}${o}
${c}
`,a=(s||n.content.body||"").split(` +`);a[0]=`> ${i}<${r}> ${a[0]}`;const p=a.join(` +> `)+` + +`+t,g=l+Zn(t);return nh(n.id,e,p,g)}class ba extends fa{constructor(e){super(e),this._pendingRedactions=null,this._pendingAnnotations=null,this._contextEntry=null,this._contextForEntries=null}get isReply(){var e;return!!((e=this.relation)!=null&&e["m.in_reply_to"])}get isReference(){var e;return((e=this.relation)==null?void 0:e.rel_type)===ya}get isRedacting(){return!!this._pendingRedactions}get isRedacted(){return this.isRedacting}get isRedaction(){return this.eventType===gt}get redactionReason(){var e;return this._pendingRedactions?(e=this._pendingRedactions[0].content)==null?void 0:e.reason:null}setContextEntry(e){this._contextEntry=e,e._setAsContextOf(this)}_setAsContextOf(e){this._contextForEntries||(this._contextForEntries=[]),this._contextForEntries.push(e)}get contextForEntries(){return this._contextForEntries}get contextEntry(){return this._contextEntry}addLocalRelation(e){if(e.eventType===gt&&e.isRelatedToId(this.id)){if(this._pendingRedactions||(this._pendingRedactions=[]),this._pendingRedactions.push(e),this._pendingRedactions.length===1)return"isRedacted"}else{const t=e.redactingEntry||e;if(t.isRelatedToId(this.id)&&t.relation.rel_type===ss&&this._addPendingAnnotation(e))return"pendingAnnotations"}}removeLocalRelation(e){var t;if(e.eventType===gt&&e.isRelatedToId(this.id)&&this._pendingRedactions){const s=this._pendingRedactions.length;if(this._pendingRedactions=this._pendingRedactions.filter(i=>i!==e),this._pendingRedactions.length===0&&(this._pendingRedactions=null,s!==0))return"isRedacted"}else{const s=e.redactingEntry||e;if(s.isRelatedToId(this.id)&&((t=s.relation)==null?void 0:t.rel_type)===ss&&this._pendingAnnotations&&this._removePendingAnnotation(e))return"pendingAnnotations"}}_addPendingAnnotation(e){this._pendingAnnotations||(this._pendingAnnotations=new Map);const{key:t}=(e.redactingEntry||e).relation;if(t){let s=this._pendingAnnotations.get(t);return s||(s=new sh,this._pendingAnnotations.set(t,s)),s.add(e),!0}return!1}_removePendingAnnotation(e){const{key:t}=(e.redactingEntry||e).relation;if(t){let s=this._pendingAnnotations.get(t);return s.remove(e)&&s.isEmpty&&this._pendingAnnotations.delete(t),this._pendingAnnotations.size===0&&(this._pendingAnnotations=null),!0}return!1}async abortPendingRedaction(){if(this._pendingRedactions)for(const e of this._pendingRedactions)await e.pendingEvent.abort()}get pendingRedaction(){return this._pendingRedactions?this._pendingRedactions[0]:null}annotate(e){return eh(this.id,e)}createReplyContent(e,t){return oh(this,e,t)}isRelatedToId(e){return e&&this.relatedEventId===e}haveAnnotation(e){var r,o,c;const t=((o=(r=this.annotations)==null?void 0:r[e])==null?void 0:o.me)||!1,s=(c=this.pendingAnnotations)==null?void 0:c.get(e),i=(s==null?void 0:s.willAnnotate)||!1;return t&&(!s||i)||!t&&i}get relation(){return rs(this.content)}get pendingAnnotations(){return this._pendingAnnotations}get annotations(){return null}}class ah extends ba{constructor({pendingEvent:e,member:t,clock:s,redactingEntry:i}){super(null),this._pendingEvent=e,this._member=t,this._timestamp=s.now()-(100-e.queueIndex),this._redactingEntry=i}get fragmentId(){return Zr}get entryIndex(){return this._pendingEvent.queueIndex}get content(){return this._pendingEvent.content}get event(){return null}get eventType(){return this._pendingEvent.eventType}get stateKey(){return null}get sender(){var e;return(e=this._member)==null?void 0:e.userId}get displayName(){var e;return(e=this._member)==null?void 0:e.name}get avatarUrl(){var e;return(e=this._member)==null?void 0:e.avatarUrl}get timestamp(){return this._timestamp}get isPending(){return!0}get id(){return this._pendingEvent.txnId}get pendingEvent(){return this._pendingEvent}notifyUpdate(){}isRelatedToId(e){return e&&e===this._pendingEvent.relatedTxnId?!0:super.isRelatedToId(e)}get relatedEventId(){return this._pendingEvent.relatedEventId}get redactingEntry(){return this._redactingEntry}get contextEventId(){var e;return this.isReply?(e=this._pendingEvent.relatedEventId)!=null?e:this._pendingEvent.relatedTxnId:null}}class As{constructor(){let e,t;this.promise=new Promise((s,i)=>{e=s,t=i}),this.resolve=s=>{this._value=s,e(s)},this.reject=t}get value(){return this._value}}const X=oi("Waiting","EncryptingAttachments","UploadingAttachments","Encrypting","Sending","Sent","Error"),eo=["m.relates_to"];class ch{constructor({data:e,remove:t,emitUpdate:s,attachments:i}){this._data=e,this._attachments=i,this._emitUpdate=s,this._removeFromQueueCallback=t,this._aborted=!1,this._status=X.Waiting,this._sendRequest=null,this._attachmentsTotalBytes=0,this._deferred=new As,this._attachments&&(this._attachmentsTotalBytes=Object.values(this._attachments).reduce((r,o)=>r+o.size,0))}get roomId(){return this._data.roomId}get queueIndex(){return this._data.queueIndex}get eventType(){return this._data.eventType}get txnId(){return this._data.txnId}get remoteId(){return this._data.remoteId}get content(){return this._data.content}get relatedTxnId(){return this._data.relatedTxnId}get relatedEventId(){const e=rs(this.content);return e?bn(e):this._data.relatedEventId}setRelatedEventId(e){const t=rs(this.content);t?wa(t,e):this._data.relatedEventId=e}get data(){return this._data}getAttachment(e){return this._attachments&&this._attachments[e]}get needsSending(){return!this.remoteId&&!this.aborted}get needsEncryption(){return this._data.needsEncryption&&!this.aborted}get needsUpload(){return this._data.needsUpload&&!this.aborted}get isMissingAttachments(){return this.needsUpload&&!this._attachments}setEncrypting(){this._status=X.Encrypting,this._emitUpdate("status")}get contentForEncryption(){const e=Object.assign({},this._data.content);for(const t of eo)delete e[t];return e}_preserveContentFields(e){const t=this._data.content;for(const s of eo)t[s]!==void 0&&(e[s]=t[s])}setEncrypted(e,t){this._preserveContentFields(t),this._data.encryptedEventType=e,this._data.encryptedContent=t,this._data.needsEncryption=!1}setError(e){this._status=X.Error,this._error=e,this._emitUpdate("status")}setWaiting(){this._status=X.Waiting,this._emitUpdate("status")}get status(){return this._status}get error(){return this._error}get hasStartedSending(){return this._status===X.Sending||this._status===X.Sent}get attachmentsTotalBytes(){return this._attachmentsTotalBytes}get attachmentsSentBytes(){return this._attachments&&Object.values(this._attachments).reduce((e,t)=>e+t.sentBytes,0)}async uploadAttachments(e,t){if(!this.needsUpload)return;if(!this._attachments)throw new Error("attachments missing");if(this.needsEncryption){this._status=X.EncryptingAttachments,this._emitUpdate("status");for(const i of Object.values(this._attachments))if(await t.wrap("encrypt",()=>(t.set("size",i.size),i.encrypt())),this.aborted)throw new rt}this._status=X.UploadingAttachments,this._emitUpdate("status");const s=Object.entries(this._attachments);s.sort(([,i],[,r])=>i.size-r.size);for(const[i,r]of s)await t.wrap("upload",o=>(o.set("size",r.size),r.upload(e,()=>{this._emitUpdate("attachmentsSentBytes")},o))),r.applyToContent(i,this.content);this._data.needsUpload=!1}async abort(){var e;if(!this._aborted){if(this._aborted=!0,this._attachments)for(const t of Object.values(this._attachments))t.abort();(e=this._sendRequest)==null||e.abort(),await this._removeFromQueueCallback()}}get aborted(){return this._aborted}async send(e,t){this._status=X.Sending,this._emitUpdate("status");const s=this._data.encryptedEventType||this._data.eventType,i=this._data.encryptedContent||this._data.content;s===gt?this._sendRequest=e.redact(this.roomId,this._data.relatedEventId,this.txnId,i,{log:t}):this._sendRequest=e.send(this.roomId,s,this.txnId,i,{log:t});const r=await this._sendRequest.response();this._sendRequest=null,this._data.remoteId=r.event_id,this._deferred.resolve(r.event_id),t.set("id",this._data.remoteId),this._status=X.Sent,this._emitUpdate("status")}getRemoteId(){return this._deferred.promise}dispose(){if(this._attachments)for(const e of Object.values(this._attachments))e.dispose()}}class Ye extends ba{constructor(e,t){super(t),this._eventEntry=e,this._decryptionError=null,this._decryptionResult=null}clone(){const e=new Ye(this._eventEntry,this._fragmentIdComparer);return e.updateFrom(this),e}updateFrom(e){e._decryptionResult&&(this._decryptionResult=e._decryptionResult),e._decryptionError&&(this._decryptionError=e._decryptionError),this._contextForEntries=e.contextForEntries,this._contextEntry=e.contextEntry}get event(){return this._eventEntry.event}get fragmentId(){return this._eventEntry.fragmentId}get entryIndex(){return this._eventEntry.eventIndex}get content(){var e,t;return((t=(e=this._decryptionResult)==null?void 0:e.event)==null?void 0:t.content)||this._eventEntry.event.content}get prevContent(){return Qr(this._eventEntry.event)}get eventType(){var e,t;return((t=(e=this._decryptionResult)==null?void 0:e.event)==null?void 0:t.type)||this._eventEntry.event.type}get stateKey(){return this._eventEntry.event.state_key}get sender(){return this._eventEntry.event.sender}get displayName(){return this._eventEntry.displayName}get avatarUrl(){return this._eventEntry.avatarUrl}get timestamp(){return this._eventEntry.event.origin_server_ts}get id(){return this._eventEntry.event.event_id}setDecryptionResult(e){this._decryptionResult=e}get isEncrypted(){return this._eventEntry.event.type==="m.room.encrypted"}get isDecrypted(){var e;return!!((e=this._decryptionResult)!=null&&e.event)}get isVerified(){var e;return this.isEncrypted&&((e=this._decryptionResult)==null?void 0:e.isVerified)}get isUnverified(){var e;return this.isEncrypted&&((e=this._decryptionResult)==null?void 0:e.isUnverified)}setDecryptionError(e){this._decryptionError=e}get decryptionError(){return this._decryptionError}get relatedEventId(){return va(this.event)}get isRedacted(){return super.isRedacted||Xr(this._eventEntry.event)}get redactionReason(){var t,s;const e=(t=this._eventEntry.event.unsigned)==null?void 0:t.redacted_because;return e?(s=e.content)==null?void 0:s.reason:super.redactionReason}get annotations(){return this._eventEntry.annotations}get relation(){const e=this._eventEntry.event.content;return e&&rs(e)||rs(this.content)}get contextEventId(){return this.isReply||this.isReference?this.relatedEventId:null}}function Sa(n,e,t){return{fragmentId:n.fragmentId,eventIndex:n.eventIndex,roomId:e,event:t}}function Vi(n,e,t){t.isForward?n.push(e):n.unshift(e)}function lh(n,e,t){return t.isForward?n.concat(e):e.concat(n)}const Ke="m.room.member";class Q{constructor(e){this._data=e}static fromUserId(e,t,s){return new Q({roomId:e,userId:t,membership:s})}static fromMemberEvent(e,t){const s=t==null?void 0:t.state_key;if(typeof s!="string")return;const i=t.content,r=Qr(t),o=i==null?void 0:i.membership,c=(i==null?void 0:i.displayname)||(r==null?void 0:r.displayname),l=(i==null?void 0:i.avatar_url)||(r==null?void 0:r.avatar_url);return this._validateAndCreateMember(e,s,o,c,l)}static fromReplacingMemberEvent(e,t){const s=t&&t.state_key;if(typeof s!="string")return;const i=Qr(t);return this._validateAndCreateMember(e,s,i==null?void 0:i.membership,i==null?void 0:i.displayname,i==null?void 0:i.avatar_url)}static _validateAndCreateMember(e,t,s,i,r){if(typeof s=="string")return new Q({roomId:e,userId:t,membership:s,avatarUrl:r,displayName:i})}get membership(){return this._data.membership}get displayName(){return this._data.displayName}get name(){return this._data.displayName||this._data.userId}get avatarUrl(){return this._data.avatarUrl}get roomId(){return this._data.roomId}get userId(){return this._data.userId}serialize(){return this._data}equals(e){const t=this._data,s=e._data;return t.roomId===s.roomId&&t.userId===s.userId&&t.membership===s.membership&&t.displayName===s.displayName&&t.avatarUrl===s.avatarUrl}}class ka{constructor(e,t){this.member=e,this.previousMembership=t}get roomId(){return this.member.roomId}get userId(){return this.member.userId}get membership(){return this.member.membership}get wasInvited(){return this.previousMembership==="invite"&&this.membership!=="invite"}get hasLeft(){return this.previousMembership==="join"&&this.membership!=="join"}get hasJoined(){return this.previousMembership!=="join"&&this.membership==="join"}}function Sn(n){return typeof n=="number"}const hh=["event_id","type","room_id","user_id","sender","state_key","prev_state","content","unsigned","origin_server_ts"].reduce(function(n,e){return n[e]=1,n},{}),dh={"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}};function uh(n,e){for(const i of Object.keys(e))hh[i]||delete e[i];const{content:t}=e,s=dh[e.type];for(const i of Object.keys(t))s!=null&&s[i]||delete t[i];e.unsigned=e.unsigned||{},e.unsigned.redacted_because=n}function mh(n,e){const t=[];for(;Sn(n.previousId);){const s=e.get(n.previousId);if(!s)break;if(s.nextId!==n.id)throw new Error(`Previous fragment ${s.id} doesn't point back to ${n.id}`);e.delete(n.previousId),t.unshift(s),n=s}return t}function _h(n,e){const t=[];for(;Sn(n.nextId);){const s=e.get(n.nextId);if(!s)break;if(s.previousId!==n.id)throw new Error(`Next fragment ${s.id} doesn't point back to ${n.id}`);e.delete(n.nextId),t.push(s),n=s}return t}function ph(n){const e=new Map;for(let s of n)e.set(s.id,s);const t=[];for(;e.size;){const s=e.values().next().value;e.delete(s.id);const i=mh(s,e),r=_h(s,e),o=i.concat(s,r);t.push(o)}return t.map(s=>new gh(s))}class Kr{constructor(e,t,s){this.id=e,this.previousId=t,this.nextId=s}}class gh{constructor(e){this._idToSortIndex=new Map,e.forEach((t,s)=>{this._idToSortIndex.set(t.id,s)})}compare(e,t){const s=this._idToSortIndex.get(e);if(s===void 0)throw new Error(`first id ${e} isn't part of this island`);const i=this._idToSortIndex.get(t);if(i===void 0)throw new Error(`second id ${t} isn't part of this island`);return s-i}get fragmentIds(){return this._idToSortIndex.keys()}}class to extends Error{get name(){return"CompareError"}}class fh{constructor(e){this._fragmentsById=e.reduce((t,s)=>(t.set(s.id,s),t),new Map),this.rebuild(e)}_getIsland(e){const t=this._idToIsland.get(e);if(t===void 0)throw new to(`Unknown fragment id ${e}`);return t}compare(e,t){if(e===t)return 0;const s=this._getIsland(e),i=this._getIsland(t);if(s!==i)throw new to(`${e} and ${t} are on different islands, can't tell order`);return s.compare(e,t)}rebuild(e){const t=ph(e);this._idToIsland=new Map;for(let s of t)for(let i of s.fragmentIds)this._idToIsland.set(i,s)}add(e){const t=new Kr(e.id,e.previousId,e.nextId);this._fragmentsById.set(e.id,t),this.rebuild(this._fragmentsById.values())}append(e,t){const s=new Kr(e,t,null),i=this._fragmentsById.get(t);i&&(i.nextId=e),this._fragmentsById.set(e,s),this.rebuild(this._fragmentsById.values())}prepend(e,t){const s=new Kr(e,null,t),i=this._fragmentsById.get(t);i&&(i.previousId=e),this._fragmentsById.set(e,s),this.rebuild(this._fragmentsById.values())}}(function(){const e=document.createElement("link").relList;return e&&e.supports&&e.supports("modulepreload")?"modulepreload":"preload"})();function yh(n){return"objectStore"in n?`${n.objectStore.name}.${n.name}`:n.name}function wh(n){var e,t,s,i,r;return"objectStore"in n?(s=(t=(e=n.objectStore)==null?void 0:e.transaction)==null?void 0:t.db)==null?void 0:s.name:(r=(i=n.transaction)==null?void 0:i.db)==null?void 0:r.name}class Ia extends Ot{constructor(e,t,s=null){const i=t&&"source"in t?t.source:t,r=i?yh(i):"",o=i?wh(i):"";let c=`${e} on ${o}.${r}`;s&&(c+=": ",typeof s.name=="string"&&(c+=`(name: ${s.name}) `),typeof s.code=="number"&&(c+=`(code: ${s.code}) `)),s&&(c+=s.message),super(c,s),this.storeName=r,this.databaseName=o}}class kn extends Ia{constructor(e){const t=e.target,s=t.source,i=t.error;super("IDBRequest failed",s,i),this.errorEvent=e}preventTransactionAbort(){this.errorEvent.preventDefault()}}class lt extends Ia{constructor(e,t,s,i){super(`${e}(${i.map(r=>JSON.stringify(r)).join(", ")}) failed`,t,s)}}const so={done:!0},Lt={done:!1};function vr(n){const e=n.toString(16);return"0".repeat(8-e.length)+e}function en(n){return parseInt(n,16)}function In(n,e,t,s=window.indexedDB){const i=s.open(n,t);return i.onupgradeneeded=async r=>{const o=r.target,c=o.result,l=o.transaction,h=r.oldVersion;try{await e(c,l,h,t)}catch{try{l.abort()}catch{}}},Me(i)}function Me(n){return new Promise((e,t)=>{n.addEventListener("success",s=>{e(s.target.result)}),n.addEventListener("error",s=>{const i=new kn(s);t(i)})})}function Pi(n){return new Promise((e,t)=>{n.addEventListener("complete",()=>{e()}),n.addEventListener("abort",s=>{t(new rt)})})}function _e(n,e){return new Promise((t,s)=>{n.onerror=i=>{s(new kn(i))},n.onsuccess=i=>{const r=i.target.result;if(!r){t(!1);return}const o=e(r.value,r.key,r),c=o==null?void 0:o.done,l=o==null?void 0:o.jumpTo;c?t(!0):l?r.continue(l):r.continue()}}).catch(t=>{throw new Ot("iterateCursor failed",t)})}async function vh(n,e){const t=[];return await _e(n,s=>(t.push(s),{done:e(t)})),t}class io{constructor(e,t){this._target=e,this._transaction=t}get idbFactory(){return this._transaction.idbFactory}get IDBKeyRange(){return this._transaction.IDBKeyRange}get databaseName(){return this._transaction.databaseName}_openCursor(e,t){return e&&t?this._target.openCursor(e,t):e?this._target.openCursor(e):t?this._target.openCursor(null,t):this._target.openCursor()}supports(e){return this._target.supports(e)}count(e){return Me(this._target.count(e))}get(e){return Me(this._target.get(e))}getKey(e){return this._target.supports("getKey")?Me(this._target.getKey(e)):Me(this._target.get(e)).then(t=>{if(t){let s=this._target.keyPath;return typeof s=="string"&&(s=[s]),s.reduce((i,r)=>i[r],t)}})}reduce(e,t,s){return this._reduce(e,t,s,"next")}reduceReverse(e,t,s){return this._reduce(e,t,s,"prev")}selectLimit(e,t){return this._selectLimit(e,t,"next")}selectLimitReverse(e,t){return this._selectLimit(e,t,"prev")}selectWhile(e,t){return this._selectWhile(e,t,"next")}selectWhileReverse(e,t){return this._selectWhile(e,t,"prev")}async selectAll(e,t){const s=this._openCursor(e,t),i=[];return await _e(s,r=>(i.push(r),Lt)),i}selectFirst(e){return this._find(e,()=>!0,"next")}selectLast(e){return this._find(e,()=>!0,"prev")}find(e,t){return this._find(e,t,"next")}findReverse(e,t){return this._find(e,t,"prev")}async findMaxKey(e){const t=this._target.openKeyCursor(e,"prev");let s;return await _e(t,(i,r)=>(s=r,so)),s}async iterateValues(e,t){const s=this._target.openCursor(e,"next");await _e(s,(i,r,o)=>({done:t(i,r,o)}))}async iterateKeys(e,t){const s=this._target.openKeyCursor(e,"next");await _e(s,(i,r,o)=>({done:t(r,o)}))}async findExistingKeys(e,t,s){const i=(u,p)=>t?-this.idbFactory.cmp(u,p):this.idbFactory.cmp(u,p),r=e.slice().sort(i),o=r[0],c=r[r.length-1],l=t?"prev":"next",h=this._target.openKeyCursor(this.IDBKeyRange.bound(o,c),l);let a=0;await _e(h,(u,p,g)=>{for(;a=r.length?so:{done:!1,jumpTo:r[a]}})}_reduce(e,t,s,i){let r=s;const o=this._openCursor(e,i);return _e(o,c=>(r=t(r,c),Lt))}_selectLimit(e,t,s){return this._selectUntil(e,i=>i.length===t,s)}async _selectUntil(e,t,s){const i=this._openCursor(e,s),r=[];return await _e(i,o=>(r.push(o),{done:t(r,o)})),r}async _selectWhile(e,t,s){const i=this._openCursor(e,s),r=[];return await _e(i,o=>{const c=t(o);return c&&r.push(o),{done:!c}}),r}async iterateWhile(e,t){const s=this._openCursor(e,"next");await _e(s,i=>({done:!t(i)}))}async _find(e,t,s){const i=this._openCursor(e,s);let r;if(await _e(i,c=>{const l=t(c);return l&&(r=c),{done:l}}))return r}}const Mt=!1;function Ct(n,e,t){var r,o;const s=t==null?void 0:t.name,i=(o=(r=t==null?void 0:t.transaction)==null?void 0:r.db)==null?void 0:o.name;console.info(`${i}.${s}.${n}(${e.map(c=>JSON.stringify(c)).join(", ")})`)}class ro{constructor(e){this._qt=e}get keyPath(){return this._qtStore.keyPath}get _qtStore(){return"objectStore"in this._qt?this._qt.objectStore:this._qt}supports(e){return!!this._qt[e]}openKeyCursor(e,t){try{return this._qt.openKeyCursor?(Mt&&Ct("openKeyCursor",[e,t],this._qt),this._qt.openKeyCursor(e,t)):(Mt&&Ct("openCursor",[e,t],this._qt),this.openCursor(e,t))}catch(s){throw new lt("openKeyCursor",this._qt,s,[e,t])}}openCursor(e,t){try{return Mt&&Ct("openCursor",[],this._qt),this._qt.openCursor(e,t)}catch(s){throw new lt("openCursor",this._qt,s,[e,t])}}put(e,t){try{return Mt&&Ct("put",[e,t],this._qt),this._qtStore.put(e,t)}catch(s){throw new lt("put",this._qt,s,[e,t])}}add(e,t){try{return Mt&&Ct("add",[e,t],this._qt),this._qtStore.add(e,t)}catch(s){throw new lt("add",this._qt,s,[e,t])}}get(e){try{return Mt&&Ct("get",[e],this._qt),this._qt.get(e)}catch(t){throw new lt("get",this._qt,t,[e])}}getKey(e){try{return Mt&&Ct("getKey",[e],this._qt),this._qt.getKey(e)}catch(t){throw new lt("getKey",this._qt,t,[e])}}delete(e){try{return Mt&&Ct("delete",[e],this._qt),this._qtStore.delete(e)}catch(t){throw new lt("delete",this._qt,t,[e])}}clear(){try{return Mt&&Ct("clear",[],this._qt),this._qtStore.clear()}catch(e){throw new lt("delete",this._qt,e,[])}}count(e){try{return this._qt.count(e)}catch(t){throw new lt("count",this._qt,t,[e])}}index(e){try{return this._qtStore.index(e)}catch(t){throw new lt("index",this._qt,t,[e])}}get indexNames(){return Array.from(this._qtStore.indexNames)}}class Ma extends io{constructor(e,t){super(new ro(e),t)}get _idbStore(){return this._target}index(e){return new io(new ro(this._idbStore.index(e)),this._transaction)}put(e,t){const s=this._idbStore.put(e);this._prepareErrorLog(s,t,"put",void 0,e)}add(e,t){const s=this._idbStore.add(e);this._prepareErrorLog(s,t,"add",void 0,e)}async tryAdd(e,t){try{return await Me(this._idbStore.add(e)),!0}catch(s){if(s instanceof kn)return t.log({l:"could not write",id:this._getKeys(e),e:s},t.level.Warn),s.preventTransactionAbort(),!1;throw s}}delete(e,t){const s=this._idbStore.delete(e);this._prepareErrorLog(s,t,"delete",e,void 0)}clear(e){const t=this._idbStore.clear();this._prepareErrorLog(t,e,"delete",void 0,void 0)}_prepareErrorLog(e,t,s,i,r){t&&t.ensureRefId(),Me(e).catch(o=>{let c;r?c=this._getKeys(r):i&&(c=[i]),this._transaction.addWriteError(o,t,s,c)})}_getKeys(e){const t=[],{keyPath:s}=this._idbStore;try{t.push(this._readKeyPath(e,s))}catch{console.warn("could not read keyPath",s)}for(const i of this._idbStore.indexNames)try{const r=this._idbStore.index(i);t.push(this._readKeyPath(e,r.keyPath))}catch{console.warn("could not read index",i)}return t}_readKeyPath(e,t){if(Array.isArray(t)){let s=e;for(const i of t)if(typeof s=="object")s=s[i];else break;return s}else return e[t]}}function bh(n){return JSON.stringify(Ca(n))}function Sh(n){return Ea(JSON.parse(n))}function Ca(n){if(typeof n=="object"&&n!==null&&!Array.isArray(n)){if(n.byteLength)return{_type:n.constructor.name,value:Array.from(n)};let e={};for(const t in n)n.hasOwnProperty(t)&&(e[t]=Ca(n[t]));return e}else return n}function Ea(n){if(typeof n=="object"&&n!==null&&!Array.isArray(n)){if(typeof n._type=="string")switch(n._type){case"Int8Array":return Int8Array.from(n.value);case"Uint8Array":return Uint8Array.from(n.value);case"Uint8ClampedArray":return Uint8ClampedArray.from(n.value);case"Int16Array":return Int16Array.from(n.value);case"Uint16Array":return Uint16Array.from(n.value);case"Int32Array":return Int32Array.from(n.value);case"Uint32Array":return Uint32Array.from(n.value);case"Float32Array":return Float32Array.from(n.value);case"Float64Array":return Float64Array.from(n.value);case"BigInt64Array":return BigInt64Array.from(n.value);case"BigUint64Array":return BigUint64Array.from(n.value);default:return n.value}let e={};for(const t in n)n.hasOwnProperty(t)&&(e[t]=Ea(n[t]));return e}else return n}function Ra(n){return`${n}.session.`}function kh(n,e){const t=[];for(let s=0;s(t.startsWith(Oe)&&this._writeKeyToLocalStorage(t,e.value),!1))}async tryRestoreE2EEIdentityFromLocalStorage(e){let t=!1;const s=this._localStorageKeyPrefix,i=s+Oe;for(let r=0;r(n[n.All=1]="All",n[n.Debug=2]="Debug",n[n.Detail=3]="Detail",n[n.Info=4]="Info",n[n.Warn=5]="Warn",n[n.Error=6]="Error",n[n.Fatal=7]="Fatal",n[n.Off=8]="Off",n))(Ge||{});class br{constructor(e){this._parentFilter=e}filter(e,t){return!(this._parentFilter&&!this._parentFilter.filter(e,t)||this._min!==void 0&&!Array.isArray(t)&&e.logLevels(t(this.item))).then(Sr,Sr),this.item}get level(){return Ge}}class Ch{constructor(e){this.logger=e}discard(){}wrap(e,t){return this.run(t)}run(e){return e(this)}log(e){return this}set(e){return this}runDetached(e,t){return new Promise(s=>s(t(this))).then(Sr,Sr),this}wrapDetached(e,t){return this.refDetached()}refDetached(){}ensureRefId(){}get level(){return Ge}get duration(){return 0}catch(e){return e}child(){return this}finish(){}forceFinish(){}serialize(){}}const Eh=new Mh;function tt(n,e,t){return`${n}|${vr(e)}|${vr(t)}`}function Rh(n){const[e,t,s]=n.split("|");return{roomId:e,eventKey:new pe(en(t),en(s))}}function Zi(n,e){return`${n}|${e}`}function oo(n){const[e,t]=n.split("|");return{roomId:e,eventId:t}}class er{constructor(e,t,s,i,r=!1,o=!1){this._IDBKeyRange=e,this._only=t,this._lower=s,this._upper=i,this._lowerOpen=r,this._upperOpen=o}asIDBKeyRange(e){try{if(this._only)return this._IDBKeyRange.only(tt(e,this._only.fragmentId,this._only.eventIndex));if(this._lower&&!this._upper)return this._IDBKeyRange.bound(tt(e,this._lower.fragmentId,this._lower.eventIndex),tt(e,this._lower.fragmentId,ce.maxStorageKey),this._lowerOpen,!1);if(!this._lower&&this._upper)return this._IDBKeyRange.bound(tt(e,this._upper.fragmentId,ce.minStorageKey),tt(e,this._upper.fragmentId,this._upper.eventIndex),!1,this._upperOpen);if(this._lower&&this._upper)return this._IDBKeyRange.bound(tt(e,this._lower.fragmentId,this._lower.eventIndex),tt(e,this._upper.fragmentId,this._upper.eventIndex),this._lowerOpen,this._upperOpen)}catch(t){throw new Ot("IDBKeyRange failed with data: "+JSON.stringify(this),t)}}}class Th{constructor(e){this._timelineStore=e}onlyRange(e){return new er(this._timelineStore.IDBKeyRange,e)}upperBoundRange(e,t=!1){return new er(this._timelineStore.IDBKeyRange,void 0,void 0,e,void 0,t)}lowerBoundRange(e,t=!1){return new er(this._timelineStore.IDBKeyRange,void 0,e,void 0,t)}boundRange(e,t,s=!1,i=!1){return new er(this._timelineStore.IDBKeyRange,void 0,e,t,s,i)}async lastEvents(e,t,s){const i=pe.maxKey;return i.fragmentId=t,this.eventsBefore(e,i,s)}async firstEvents(e,t,s){const i=pe.minKey;return i.fragmentId=t,this.eventsAfter(e,i,s)}eventsAfter(e,t,s){const i=this.lowerBoundRange(t,!0).asIDBKeyRange(e);return this._timelineStore.selectLimit(i,s)}async eventsBefore(e,t,s){const i=this.upperBoundRange(t,!0).asIDBKeyRange(e),r=await this._timelineStore.selectLimitReverse(i,s);return r.reverse(),r}async getEventKeysForIds(e,t){const s=this._timelineStore.index("byEventId"),i=t.map(o=>Zi(e,o)),r=new Map;return await s.findExistingKeys(i,!1,(o,c)=>{const{eventId:l}=oo(o),{eventKey:h}=Rh(c);return r.set(l,h),!1}),r}async findFirstOccurringEventId(e,t){const s=this._timelineStore.index("byEventId"),i=t.map(l=>Zi(e,l)),r=new Array(i.length);let o;function c(){for(let l=0;l{const a=i.indexOf(l);return r[a]=h,o=c(),!!o}),o&&oo(o).eventId}tryInsert(e,t){return e.key=tt(e.roomId,e.fragmentId,e.eventIndex),e.eventIdKey=Zi(e.roomId,e.event.event_id),this._timelineStore.tryAdd(e,t)}update(e){this._timelineStore.put(e)}get(e,t){return this._timelineStore.get(tt(e,t.fragmentId,t.eventIndex))}getByEventId(e,t){return this._timelineStore.index("byEventId").get(Zi(e,t))}removeAllForRoom(e){const t=tt(e,ce.minStorageKey,ce.minStorageKey),s=tt(e,ce.maxStorageKey,ce.maxStorageKey),i=this._timelineStore.IDBKeyRange.bound(t,s);this._timelineStore.delete(i)}}const de="\0",ae="\u{10FFFF}";function ht(n,e,t,s){return`${n}|${e}|${t}|${s}`}function ao(n){const[e,t,s,i]=n.split("|");return{roomId:e,targetEventId:t,relType:s,sourceEventId:i}}class Ah{constructor(e){this._store=e}add(e,t,s,i){this._store.add({key:ht(e,t,s,i)})}remove(e,t,s,i){this._store.delete(ht(e,t,s,i))}removeAllForTarget(e,t){const s=this._store.IDBKeyRange.bound(ht(e,t,de,de),ht(e,t,ae,ae),!0,!0);this._store.delete(s)}removeAllForRoom(e){const t=this._store.IDBKeyRange.bound(ht(e,de,de,de),ht(e,ae,ae,ae),!0,!0);this._store.delete(t)}async getForTargetAndType(e,t,s){const i=this._store.IDBKeyRange.bound(ht(e,t,s,de),ht(e,t,s,ae),!0,!0);return(await this._store.selectAll(i)).map(o=>ao(o.key))}async getAllForTarget(e,t){const s=this._store.IDBKeyRange.bound(ht(e,t,de,de),ht(e,t,ae,ae),!0,!0);return(await this._store.selectAll(s)).map(r=>ao(r.key))}}function tr(n,e,t){return`${n}|${e}|${t}`}class xh{constructor(e){this._roomStateStore=e}get(e,t,s){const i=tr(e,t,s);return this._roomStateStore.get(i)}getAllForType(e,t){const s=this._roomStateStore.IDBKeyRange.bound(tr(e,t,""),tr(e,t,ae),!1,!0);return this._roomStateStore.selectAll(s)}set(e,t){const s=tr(e,t.type,t.state_key),i={roomId:e,event:t,key:s};this._roomStateStore.put(i)}removeAllForRoom(e){const t=this._roomStateStore.IDBKeyRange.bound(e,`${e}|${ae}`,!0,!0);this._roomStateStore.delete(t)}}function sr(n,e){return`${n}|${e}`}function Vh(n){const[e,t]=n.split("|");return{roomId:e,userId:t}}class Ta{constructor(e){this._roomMembersStore=e}get(e,t){return this._roomMembersStore.get(sr(e,t))}set(e){e.key=sr(e.roomId,e.userId),this._roomMembersStore.put(e)}getAll(e){const t=this._roomMembersStore.IDBKeyRange.lowerBound(sr(e,""));return this._roomMembersStore.selectWhile(t,s=>s.roomId===e)}async getAllUserIds(e){const t=[],s=this._roomMembersStore.IDBKeyRange.lowerBound(sr(e,""));return await this._roomMembersStore.iterateKeys(s,i=>{const r=Vh(i);return r.roomId===e?(t.push(r.userId),!1):!0}),t}removeAllForRoom(e){const t=this._roomMembersStore.IDBKeyRange.bound(e,`${e}|${ae}`,!0,!0);this._roomMembersStore.delete(t)}}function ir(n,e){return`${n}|${vr(e)}`}class Nh{constructor(e){this._store=e}_allRange(e){try{return this._store.IDBKeyRange.bound(ir(e,ce.minStorageKey),ir(e,ce.maxStorageKey))}catch(t){throw new Ot(`error from IDBKeyRange with roomId ${e}`,t)}}all(e){return this._store.selectAll(this._allRange(e))}liveFragment(e){return this._store.findReverse(this._allRange(e),t=>typeof t.nextId!="number"&&typeof t.nextToken!="string")}add(e){e.key=ir(e.roomId,e.id),this._store.add(e)}update(e){this._store.put(e)}get(e,t){return this._store.get(ir(e,t))}removeAllForRoom(e){this._store.delete(this._allRange(e))}}function ps(n,e){return`${n}|${vr(e)}`}function Dh(n){const[e,t]=n.split("|"),s=en(t);return{roomId:e,queueIndex:s}}class Uh{constructor(e){this._eventStore=e}async getMaxQueueIndex(e){const t=this._eventStore.IDBKeyRange.bound(ps(e,ce.minStorageKey),ps(e,ce.maxStorageKey),!1,!1),s=await this._eventStore.findMaxKey(t);if(s)return Dh(s).queueIndex}remove(e,t){const s=this._eventStore.IDBKeyRange.only(ps(e,t));this._eventStore.delete(s)}async exists(e,t){const s=this._eventStore.IDBKeyRange.only(ps(e,t));return!!await this._eventStore.getKey(s)}add(e){e.key=ps(e.roomId,e.queueIndex),this._eventStore.add(e)}update(e){this._eventStore.put(e)}getAll(){return this._eventStore.selectAll()}removeAllForRoom(e){const t=ps(e,ce.minStorageKey),s=ps(e,ce.maxStorageKey),i=this._eventStore.IDBKeyRange.bound(t,s);this._eventStore.delete(i)}}class Oh{constructor(e){this._store=e}get(e){return this._store.get(e)}set(e){this._store.put(e)}remove(e){this._store.delete(e)}}function gs(n,e){return`${n}|${e}`}function Ph(n){const[e,t]=n.split("|");return{userId:e,deviceId:t}}class Fh{constructor(e){this._store=e}async getAllForUserId(e){const t=this._store.IDBKeyRange.lowerBound(gs(e,de));return(await this._store.selectWhile(t,i=>i.deviceKey.user_id===e)).map(i=>i.deviceKey)}async getAllDeviceIds(e){const t=[],s=this._store.IDBKeyRange.lowerBound(gs(e,de));return await this._store.iterateKeys(s,i=>{const r=Ph(i);return r.userId===e?(t.push(r.deviceId),!1):!0}),t}async get(e,t){var s;return(s=await this._store.get(gs(e,t)))==null?void 0:s.deviceKey}set(e){this._store.put({key:gs(e.user_id,e.device_id),curve25519Key:_t(e),deviceKey:e})}async getByCurve25519Key(e){const t=await this._store.index("byCurve25519Key").get(e);return t==null?void 0:t.deviceKey}remove(e,t){this._store.delete(gs(e,t))}removeAllForUser(e){const t=this._store.IDBKeyRange.bound(gs(e,de),gs(e,ae),!0,!0);this._store.delete(t)}}function yi(n,e){return`${n}|${e}`}class Lh{constructor(e){this._store=e}async get(e,t){var s;return(s=await this._store.get(yi(e,t)))==null?void 0:s.crossSigningKey}set(e){this._store.put({key:yi(e.user_id,e.usage[0]),crossSigningKey:e})}remove(e,t){this._store.delete(yi(e,t))}removeAllForUser(e){const t=this._store.IDBKeyRange.bound(yi(e,de),yi(e,ae),!0,!0);this._store.delete(t)}}function wi(n,e){return`${n}|${e}`}function Kh(n){const[e,t]=n.split("|");return{senderKey:e,sessionId:t}}class Bh{constructor(e){this._store=e}async getSessionIds(e){const t=[],s=this._store.IDBKeyRange.lowerBound(wi(e,""));return await this._store.iterateKeys(s,i=>{const r=Kh(i);return r.senderKey===e?(t.push(r.sessionId),!1):!0}),t}getAll(e){const t=this._store.IDBKeyRange.lowerBound(wi(e,""));return this._store.selectWhile(t,s=>s.senderKey===e)}get(e,t){return this._store.get(wi(e,t))}set(e){e.key=wi(e.senderKey,e.sessionId),this._store.put(e)}remove(e,t){this._store.delete(wi(e,t))}}var Vr=(n=>(n[n.NotBackedUp=0]="NotBackedUp",n[n.BackedUp=1]="BackedUp",n))(Vr||{}),Hi=(n=>(n[n.DeviceMessage=1]="DeviceMessage",n[n.Backup=2]="Backup",n[n.Outbound=3]="Outbound",n))(Hi||{});function qs(n,e,t){return`${n}|${e}|${t}`}class $h{constructor(e){this._store=e}async has(e,t,s){const i=qs(e,t,s),r=await this._store.getKey(i);return i===r}get(e,t,s){return this._store.get(qs(e,t,s))}set(e){const t=e;t.key=qs(e.roomId,e.senderKey,e.sessionId),this._store.put(t)}removeAllForRoom(e){const t=this._store.IDBKeyRange.bound(qs(e,de,de),qs(e,ae,ae));this._store.delete(t)}countNonBackedUpSessions(){return this._store.index("byBackup").count(this._store.IDBKeyRange.only(0))}getFirstNonBackedUpSessions(e){return this._store.index("byBackup").selectLimit(this._store.IDBKeyRange.only(0),e)}async markAsBackedUp(e,t,s){const i=await this._store.get(qs(e,t,s));i&&(i.backup=1,this._store.put(i))}async markAllAsNotBackedUp(){const e=this._store.IDBKeyRange.only(1);let t=0;return await this._store.index("byBackup").iterateValues(e,(s,i,r)=>(s.backup=0,r.update(s),t+=1,!1)),t}}class jh{constructor(e){this._store=e}remove(e){this._store.delete(e)}get(e){return this._store.get(e)}set(e){this._store.put(e)}}function rr(n,e,t){return`${n}|${e}|${t}`}class qh{constructor(e){this._store=e}get(e,t,s){return this._store.get(rr(e,t,s))}set(e,t,s,i){i.key=rr(e,t,s),this._store.put(i)}removeAllForRoom(e){const t=this._store.IDBKeyRange.bound(rr(e,de,de),rr(e,ae,ae));this._store.delete(t)}}function Ci(n,e){return`${n}|${e}`}class Hh{constructor(e){this._store=e}getAll(){return this._store.selectAll()}async getAllByTypeAndScope(e,t){const s=Ci(t,e),i=[];return await this._store.index("byScopeAndType").iterateWhile(s,r=>r.scopeTypeKey!==s?!1:(i.push(r),!0)),i}add(e){e.scopeTypeKey=Ci(e.scope,e.type),this._store.add(e)}update(e){this._store.put(e)}remove(e){this._store.delete(e)}async removeAllForScope(e){const t=this._store.IDBKeyRange.bound(Ci(e,de),Ci(e,ae));await this._store.index("byScopeAndType").iterateValues(t,(i,r,o)=>(o.delete(),!0))}}class Wh{constructor(e){this._store=e}async get(e){return await this._store.get(e)}set(e){this._store.put(e)}async getAll(){return await this._store.selectAll()}}function Hs(n,e,t){return`${n}|${e}|${t}`}function co(n){const[e,t,s]=n.key.split("|");return{intent:e,roomId:t,callId:s,timestamp:n.timestamp}}class zh{constructor(e){this._callStore=e}async getByIntent(e){const t=this._callStore.IDBKeyRange.bound(Hs(e,de,de),Hs(e,ae,ae),!0,!0);return(await this._callStore.selectAll(t)).map(i=>co(i))}async getByIntentAndRoom(e,t){const s=this._callStore.IDBKeyRange.bound(Hs(e,t,de),Hs(e,t,ae),!0,!0);return(await this._callStore.selectAll(s)).map(r=>co(r))}add(e){const t={key:Hs(e.intent,e.roomId,e.callId),timestamp:e.timestamp};this._callStore.add(t)}remove(e,t,s){this._callStore.delete(Hs(e,t,s))}}class Gh{constructor(e){this._store=e}get(e){return this._store.get(e)}set(e,t){t.key=e,this._store.put(t)}remove(e){this._store.delete(e)}deleteAllSecrets(){this._store.clear()}}class Yh{constructor(e,t,s,i){this.error=e,this.refItem=t,this.operationName=s,this.keys=i}}class lo{constructor(e,t,s){this._txn=e,this._allowedStoreNames=t,this._stores={},this._storage=s,this._writeErrors=[]}get idbFactory(){return this._storage.idbFactory}get IDBKeyRange(){return this._storage.IDBKeyRange}get databaseName(){return this._storage.databaseName}get logger(){return this._storage.logger}_idbStore(e){if(!this._allowedStoreNames.includes(e))throw new Ot(`Invalid store for transaction: ${e}, only ${this._allowedStoreNames.join(", ")} are allowed.`);return new Ma(this._txn.objectStore(e),this)}_store(e,t){if(!this._stores[e]){const s=this._idbStore(e);this._stores[e]=t(s)}return this._stores[e]}get session(){return this._store(J.session,e=>new Mn(e,this._storage.localStorage))}get roomSummary(){return this._store(J.roomSummary,e=>new no(e))}get archivedRoomSummary(){return this._store(J.archivedRoomSummary,e=>new no(e))}get invites(){return this._store(J.invites,e=>new Ih(e))}get timelineFragments(){return this._store(J.timelineFragments,e=>new Nh(e))}get timelineEvents(){return this._store(J.timelineEvents,e=>new Th(e))}get timelineRelations(){return this._store(J.timelineRelations,e=>new Ah(e))}get roomState(){return this._store(J.roomState,e=>new xh(e))}get roomMembers(){return this._store(J.roomMembers,e=>new Ta(e))}get pendingEvents(){return this._store(J.pendingEvents,e=>new Uh(e))}get userIdentities(){return this._store(J.userIdentities,e=>new Oh(e))}get deviceKeys(){return this._store(J.deviceKeys,e=>new Fh(e))}get crossSigningKeys(){return this._store(J.crossSigningKeys,e=>new Lh(e))}get olmSessions(){return this._store(J.olmSessions,e=>new Bh(e))}get inboundGroupSessions(){return this._store(J.inboundGroupSessions,e=>new $h(e))}get outboundGroupSessions(){return this._store(J.outboundGroupSessions,e=>new jh(e))}get groupSessionDecryptions(){return this._store(J.groupSessionDecryptions,e=>new qh(e))}get operations(){return this._store(J.operations,e=>new Hh(e))}get accountData(){return this._store(J.accountData,e=>new Wh(e))}get calls(){return this._store(J.calls,e=>new zh(e))}get sharedSecrets(){return this._store(J.sharedSecrets,e=>new Gh(e))}async complete(e){try{await Pi(this._txn)}catch(t){throw this._writeErrors.length?(this._logWriteErrors(e),this._writeErrors[0].error):t}}getCause(e){return e instanceof Ot&&e.errcode==="AbortError"&&this._writeErrors.length?this._writeErrors[0].error:e}abort(e){try{this._txn.abort()}catch{e==null||e.set("couldNotAbortTxn",!0)}this._writeErrors.length&&this._logWriteErrors(e)}addWriteError(e,t,s,i){(e.errcode!=="AbortError"||this._writeErrors.length===0)&&this._writeErrors.push(new Yh(e,t,s,i))}_logWriteErrors(e){const t=i=>{e||i.set("allowedStoreNames",this._allowedStoreNames);for(const r of this._writeErrors)i.wrap({l:r.operationName,id:r.keys},o=>{r.refItem&&o.refDetached(r.refItem),o.catch(r.error)})},s=`${this._writeErrors.length} storage write operation(s) failed`;e?e.wrap(s,t):this.logger.run(s,t)}}const ho="782rh281re38-boguskey";class Jh{constructor(e,t,s,i,r,o){this._db=e,this.idbFactory=t,this.IDBKeyRange=s,this._hasWebkitEarlyCloseTxnBug=i,this.storeNames=J,this.localStorage=r,this.logger=o}_validateStoreNames(e){const t=e.findIndex(s=>!Oi.includes(s));if(t!==-1)throw new Ot(`Tried top, a transaction unknown store ${e[t]}`)}async readTxn(e){this._validateStoreNames(e);try{const t=this._db.transaction(e,"readonly");return this._hasWebkitEarlyCloseTxnBug&&await Me(t.objectStore(e[0]).get(ho)),new lo(t,e,this)}catch(t){throw new Ot("readTxn failed",t)}}async readWriteTxn(e){this._validateStoreNames(e);try{const t=this._db.transaction(e,"readwrite");return this._hasWebkitEarlyCloseTxnBug&&await Me(t.objectStore(e[0]).get(ho)),new lo(t,e,this)}catch(t){throw new Ot("readWriteTxn failed",t)}}close(){this._db.close()}get databaseName(){return this._db.name}}async function Qh(n){const e=n.transaction(Oi,"readonly"),t={};return await Promise.all(Oi.map(async s=>{const i=t[s]=[],r=e.objectStore(s);await _e(r.openCursor(),o=>(i.push(o),Lt))})),t}async function Xh(n,e){const t=n.transaction(Oi,"readwrite");for(const s of Oi){const i=t.objectStore(s);for(const r of e[s])i.add(r)}await Pi(t)}function Zh(n,e,t,s,i){let r=!1;if(t instanceof Uint8Array){const l=new n.PkSigning;i=l.init_with_seed(t),t=l,r=!0}const o=e.signatures||{};delete e.signatures;const c=e.unsigned;e.unsigned&&delete e.unsigned;try{const l=o[s]||{};return o[s]=l,l["ed25519:"+i]=t.sign(qi.stringify(e))}finally{e.signatures=o,c&&(e.unsigned=c),r&&t.free()}}class qt{constructor(e){this.options=e,this.ourUserId=e.ourUserId,this.ourUserDeviceId=e.ourUserDeviceId,this.otherUserId=e.otherUserId,this.log=e.log,this.olmSAS=e.olmSas,this.olmUtil=e.olmUtil,this.channel=e.channel,this.e2eeAccount=e.e2eeAccount,this.deviceTracker=e.deviceTracker,this.hsApi=e.hsApi,this.eventEmitter=e.eventEmitter}setNextStage(e){this._nextStage=e}get nextStage(){return this._nextStage}get otherUserDeviceId(){const e=this.channel.otherUserDeviceId;if(!e)throw new Error("Accessed otherUserDeviceId before it was set in channel!");return e}}var P=(n=>(n.Request="m.key.verification.request",n.Ready="m.key.verification.ready",n.Start="m.key.verification.start",n.Accept="m.key.verification.accept",n.Key="m.key.verification.key",n.Cancel="m.key.verification.cancel",n.Mac="m.key.verification.mac",n.Done="m.key.verification.done",n))(P||{}),A=(n=>(n.UserCancelled="m.user",n.TimedOut="m.timeout",n.UnknownTransaction="m.unknown_transaction",n.UnknownMethod="m.unknown_method",n.UnexpectedMessage="m.unexpected_message",n.KeyMismatch="m.key_mismatch",n.UserMismatch="m.user_mismatch",n.InvalidMessage="m.invalid_message",n.OtherDeviceAccepted="m.accepted",n.MismatchedCommitment="m.mismatched_commitment",n.MismatchedSAS="m.mismatched_sas",n))(A||{});const Aa=["curve25519-hkdf-sha256","curve25519"],xa=["sha256"],Va=["hkdf-hmac-sha256.v2","org.matrix.msc3783.hkdf-hmac-sha256","hkdf-hmac-sha256","hmac-sha256"],Na=["decimal","emoji"],ed=new Set(Na),td=[["\u{1F436}","dog"],["\u{1F431}","cat"],["\u{1F981}","lion"],["\u{1F40E}","horse"],["\u{1F984}","unicorn"],["\u{1F437}","pig"],["\u{1F418}","elephant"],["\u{1F430}","rabbit"],["\u{1F43C}","panda"],["\u{1F413}","rooster"],["\u{1F427}","penguin"],["\u{1F422}","turtle"],["\u{1F41F}","fish"],["\u{1F419}","octopus"],["\u{1F98B}","butterfly"],["\u{1F337}","flower"],["\u{1F333}","tree"],["\u{1F335}","cactus"],["\u{1F344}","mushroom"],["\u{1F30F}","globe"],["\u{1F319}","moon"],["\u2601\uFE0F","cloud"],["\u{1F525}","fire"],["\u{1F34C}","banana"],["\u{1F34E}","apple"],["\u{1F353}","strawberry"],["\u{1F33D}","corn"],["\u{1F355}","pizza"],["\u{1F382}","cake"],["\u2764\uFE0F","heart"],["\u{1F642}","smiley"],["\u{1F916}","robot"],["\u{1F3A9}","hat"],["\u{1F453}","glasses"],["\u{1F527}","spanner"],["\u{1F385}","santa"],["\u{1F44D}","thumbs up"],["\u2602\uFE0F","umbrella"],["\u231B","hourglass"],["\u23F0","clock"],["\u{1F381}","gift"],["\u{1F4A1}","light bulb"],["\u{1F4D5}","book"],["\u270F\uFE0F","pencil"],["\u{1F4CE}","paperclip"],["\u2702\uFE0F","scissors"],["\u{1F512}","lock"],["\u{1F511}","key"],["\u{1F528}","hammer"],["\u260E\uFE0F","telephone"],["\u{1F3C1}","flag"],["\u{1F682}","train"],["\u{1F6B2}","bicycle"],["\u2708\uFE0F","aeroplane"],["\u{1F680}","rocket"],["\u{1F3C6}","trophy"],["\u26BD","ball"],["\u{1F3B8}","guitar"],["\u{1F3BA}","trumpet"],["\u{1F514}","bell"],["\u2693\uFE0F","anchor"],["\u{1F3A7}","headphones"],["\u{1F4C1}","folder"],["\u{1F4CC}","pin"]];function sd(n){return[n[0]>>2,(n[0]&3)<<4|n[1]>>4,(n[1]&15)<<2|n[2]>>6,n[2]&63,n[3]>>2,(n[3]&3)<<4|n[4]>>4,(n[4]&15)<<2|n[5]>>6].map(t=>td[t])}const id={"hkdf-hmac-sha256":"calculate_mac","org.matrix.msc3783.hkdf-hmac-sha256":"calculate_mac_fixed_base64","hkdf-hmac-sha256.v2":"calculate_mac_fixed_base64","hmac-sha256":"calculate_mac_long_kdf"};function Da(n,e){return function(t,s,i){return i.wrap({l:"calculate MAC",method:e},()=>n[id[e]](t,s))}}class rd extends qt{async completeStage(){await this.log.wrap("SendDoneStage.completeStage",async e=>{await this.channel.send(P.Done,{},e),await this.channel.waitForEvent(P.Done),this.eventEmitter.emit("VerificationCompleted",this.otherUserDeviceId)})}}class nd extends qt{async completeStage(){await this.log.wrap("VerifyMacStage.completeStage",async e=>{const s=this.channel.acceptMessage.content.message_authentication_code,i=Da(this.olmSAS,s);await this.checkMAC(i,e),this.setNextStage(new rd(this.options))})}async checkMAC(e,t){const{content:s}=this.channel.getReceivedMessage(P.Mac),i="MATRIX_KEY_VERIFICATION_MAC"+this.otherUserId+this.otherUserDeviceId+this.ourUserId+this.ourUserDeviceId+this.channel.id,r=e(Object.keys(s.mac).sort().join(","),i+"KEY_IDS",t);if(s.keys!==r){t.log({l:"MAC verification failed for keys field",keys:s.keys,calculated:r}),this.channel.cancelVerification(A.KeyMismatch);return}await this.verifyKeys(s.mac,(o,c,l)=>{const h=e(c,i+o,t),a=l===h;return a||(t.log({l:"Mac verification failed for key",keyMac:l,calculatedMAC:h,keyId:o,key:c}),this.channel.cancelVerification(A.KeyMismatch)),a},t)}async verifyKeys(e,t,s){const i=this.otherUserId;for(const[r,o]of Object.entries(e)){const c=r.split(":",2)[1],l=await this.deviceTracker.deviceForId(i,c,this.hsApi,s);if(l){if(!t(r,ks(l),o))throw new Error(`MAC verification failed for key ${o}`)}else{const h=await this.deviceTracker.getCrossSigningKeyForUser(i,Et.Master,this.hsApi,s);if(!h)throw s.log({l:"Fetching msk failed",userId:i}),new Error("Fetching MSK for user failed!");const a=Qs(h);if(!(a&&t(r,a,o)))throw new Error(`MAC verification failed for key ${o}`)}}}}class od extends qt{async completeStage(){await this.log.wrap("SendMacStage.completeStage",async e=>{const s=this.channel.acceptMessage.content.message_authentication_code,i=Da(this.olmSAS,s);await this.sendMAC(i,e),await this.channel.waitForEvent(P.Mac),this.setNextStage(new nd(this.options))})}async sendMAC(e,t){const s={},i=[],r="MATRIX_KEY_VERIFICATION_MAC"+this.ourUserId+this.ourUserDeviceId+this.otherUserId+this.otherUserDeviceId+this.channel.id,o=`ed25519:${this.ourUserDeviceId}`,c=this.e2eeAccount.getUnsignedDeviceKey();s[o]=e(c.keys[o],r+o,t),i.push(o);const l=await this.deviceTracker.getCrossSigningKeyForUser(this.ourUserId,Et.Master,this.hsApi,t);if(!l)throw t.log({l:"Fetching msk failed",userId:this.ourUserId}),new Error("Fetching MSK for user failed!");const h=Qs(l);if(h){const u=`ed25519:${h}`;s[u]=e(h,r+u,t),i.push(u)}const a=e(i.sort().join(","),r+"KEY_IDS",t);await this.channel.send(P.Mac,{mac:s,keys:a},t)}}class pt extends Error{get name(){return"VerificationCancelledError"}get message(){return"Verification is cancelled!"}}const ad={"curve25519-hkdf-sha256":function(n,e,t){const s=`${n.our.userId}|${n.our.deviceId}|${n.our.publicKey}|`,i=`${n.their.userId}|${n.their.deviceId}|${n.their.publicKey}|`,r="MATRIX_KEY_VERIFICATION_SAS|"+(n.initiatedByMe?s+i:i+s)+n.id;return e.generate_bytes(r,t)},curve25519:function(n,e,t){const s=`${n.our.userId}${n.our.deviceId}`,i=`${n.their.userId}${n.their.deviceId}`,r="MATRIX_KEY_VERIFICATION_SAS"+(n.initiatedByMe?s+i:i+s)+n.id;return e.generate_bytes(r,t)}};class cd extends qt{async completeStage(){await this.log.wrap("CalculateSASStage.completeStage",async e=>{if(this.channel.initiatedByUs&&!await this.verifyHashCommitment(e))return;const t=new Promise((r,o)=>{this.resolve=r,this.reject=o});this.olmSAS.set_their_key(this.theirKey);const s=this.generateSASBytes();this.emoji=sd(Array.from(s)),this.eventEmitter.emit("EmojiGenerated",this);const i=this.channel.waitForEvent(P.Cancel);await Promise.race([t,i]),this.setNextStage(new od(this.options))})}async verifyHashCommitment(e){return await e.wrap("CalculateSASStage.verifyHashCommitment",async()=>{const t=this.channel.getReceivedMessage(P.Accept).content,i=this.channel.getReceivedMessage(P.Key).content.key+qi.stringify(this.channel.startMessage.content),r=t.commitment,o=this.olmUtil.sha256(i);return o!==r?(e.log({l:"Commitment mismatched!",received:r,calculated:o}),await this.channel.cancelVerification(A.MismatchedCommitment),!1):!0})}generateSASBytes(){const e=this.channel.acceptMessage.content.key_agreement_protocol,t=this.otherUserDeviceId;return ad[e]({our:{userId:this.ourUserId,deviceId:this.ourUserDeviceId,publicKey:this.olmSAS.get_pubkey()},their:{userId:this.otherUserId,deviceId:t,publicKey:this.theirKey},id:this.channel.id,initiatedByMe:this.channel.initiatedByUs},this.olmSAS,6)}async setEmojiMatch(e){e?this.resolve():(await this.channel.cancelVerification(A.MismatchedSAS),this.reject(new pt))}get theirKey(){const{content:e}=this.channel.getReceivedMessage(P.Key);return e.key}}class Ua extends qt{async completeStage(){await this.log.wrap("SendKeyStage.completeStage",async e=>{const t=this.olmSAS.get_pubkey();await this.channel.send(P.Key,{key:t},e),await this.channel.waitForEvent(P.Key),this.setNextStage(new cd(this.options))})}}function nr(n,e){return Array.isArray(n)?n.filter(t=>e.has(t)):[]}class ld extends qt{async completeStage(){await this.log.wrap("SendAcceptVerificationStage.completeStage",async e=>{const{content:t}=this.channel.startMessage,s=nr(Aa,new Set(t.key_agreement_protocols))[0],i=nr(xa,new Set(t.hashes))[0],r=nr(Va,new Set(t.message_authentication_codes))[0],o=nr(t.short_authentication_string,ed);if(!s||!i||!r||!o.length){await this.channel.cancelVerification(A.UnknownMethod);return}const l=this.olmSAS.get_pubkey()+qi.stringify(t),h={key_agreement_protocol:s,hash:i,message_authentication_code:r,short_authentication_string:o,commitment:this.olmUtil.sha256(l)};await this.channel.send(P.Accept,h,e),await this.channel.waitForEvent(P.Key),this.setNextStage(new Ua(this.options))})}}class Cn extends qt{constructor(){super(...arguments),this.allowSelection=!0}async completeStage(){await this.log.wrap("SelectVerificationMethodStage.completeStage",async e=>{await this.findDeviceName(e),this.eventEmitter.emit("SelectVerificationStage",this);const t=this.channel.waitForEvent(P.Start),s=this.channel.waitForEvent(P.Accept),{content:i}=await Promise.race([t,s]);i.method?(this.allowSelection=!1,this.hasSentStartMessage?(await this.hasSentStartMessage,await this.resolveStartConflict(e)):this.channel.setStartMessage(this.channel.getReceivedMessage(P.Start))):this.channel.setStartMessage(this.channel.getSentMessage(P.Start)),this.channel.initiatedByUs?(await s,this.setNextStage(new Ua(this.options))):this.setNextStage(new ld(this.options))})}async resolveStartConflict(e){await e.wrap("resolveStartConflict",async()=>{const t=this.channel.getReceivedMessage(P.Start),s=this.channel.getSentMessage(P.Start);if(t.content.method!==s.content.method){e.log({l:"Methods don't match for the start messages",received:t.content.method,sent:s.content.method}),await this.channel.cancelVerification(A.UnexpectedMessage);return}const i=this.ourUserId===this.otherUserId?this.ourUserDeviceId:this.ourUserId,r=this.ourUserId===this.otherUserId?this.otherUserDeviceId:this.otherUserId,o=i{var s;const t=await this.options.deviceTracker.deviceForId(this.otherUserId,this.otherUserDeviceId,this.options.hsApi,e);if(!t)throw e.log({l:"Cannot find device",userId:this.otherUserId,deviceId:this.otherUserDeviceId}),new Error("Cannot find device");this.otherDeviceName=(s=t.unsigned.device_display_name)!=null?s:t.device_id})}async selectEmojiMethod(e){if(!this.allowSelection)return;const t=new As;this.hasSentStartMessage=t.promise;const s={method:"m.sas.v1",from_device:this.ourUserDeviceId,key_agreement_protocols:Aa,hashes:xa,message_authentication_codes:Va,short_authentication_string:Na};await this.channel.send(P.Start,s,e),t.resolve()}}class hd extends qt{async completeStage(){await this.log.wrap("SendRequestVerificationStage.completeStage",async e=>{const t={from_device:this.ourUserDeviceId,methods:["m.sas.v1"]};await this.channel.send(P.Request,t,e),this.setNextStage(new Cn(this.options)),await this.channel.waitForEvent(P.Ready)})}}class dd extends qt{async completeStage(){await this.log.wrap("SendReadyStage.completeStage",async e=>{const t={from_device:this.ourUserDeviceId,methods:["m.sas.v1"]};await this.channel.send(P.Ready,t,e),this.setNextStage(new Cn(this.options))})}}var ud={exports:{}},md={},_d=Object.freeze(Object.defineProperty({__proto__:null,default:md},Symbol.toStringTag,{value:"Module"})),or=_a(_d);(function(n,e){// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt Apache-2.0 +var t=function(){var s={},i,r,o=(()=>{var l=typeof document!="undefined"&&document.currentScript?document.currentScript.src:void 0;return typeof __filename!="undefined"&&(l=l||__filename),function(h){h=h||{};var a;a||(a=typeof h!="undefined"?h:{});var u,p;a.ready=new Promise(function(d,m){u=d,p=m});var g;if(typeof window!="undefined")g=function(d){window.crypto.getRandomValues(d)};else if(n.exports){var f=or;g=function(d){var m=f.randomBytes(d.length);d.set(m)}}else throw Error("Cannot find global to attach library to");if(typeof OLM_OPTIONS!="undefined")for(var v in OLM_OPTIONS)OLM_OPTIONS.hasOwnProperty(v)&&(a[v]=OLM_OPTIONS[v]);a.onRuntimeInitialized=function(){le=a._olm_error(),s.PRIVATE_KEY_LENGTH=a._olm_pk_private_key_length(),i&&i()},a.onAbort=function(d){r&&r(d)};var M=Object.assign({},a),R=typeof window=="object",N=typeof importScripts=="function",F=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",T="",D,B,G,$e,Ns,di;F?(T=N?or.dirname(T)+"/":__dirname+"/",di=()=>{Ns||($e=or,Ns=or)},D=function(d,m){return di(),d=Ns.normalize(d),$e.readFileSync(d,m?void 0:"utf8")},G=d=>(d=D(d,!0),d.buffer||(d=new Uint8Array(d)),d),B=(d,m,_)=>{di(),d=Ns.normalize(d),$e.readFile(d,function(w,k){w?_(w):m(k.buffer)})},1{var m=new XMLHttpRequest;return m.open("GET",d,!1),m.send(null),m.responseText},N&&(G=d=>{var m=new XMLHttpRequest;return m.open("GET",d,!1),m.responseType="arraybuffer",m.send(null),new Uint8Array(m.response)}),B=(d,m,_)=>{var w=new XMLHttpRequest;w.open("GET",d,!0),w.responseType="arraybuffer",w.onload=()=>{w.status==200||w.status==0&&w.response?m(w.response):_()},w.onerror=_,w.send(null)}),a.print||console.log.bind(console);var as=a.printErr||console.warn.bind(console);Object.assign(a,M),M=null;var cs;a.wasmBinary&&(cs=a.wasmBinary),a.noExitRuntime,typeof WebAssembly!="object"&&je("no native wasm support detected");var Ds,Ue=!1,Us=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):void 0;function U(d,m){if(d){var _=re,w=d+m;for(m=d;_[m]&&!(m>=w);)++m;if(16k?w+=String.fromCharCode(k):(k-=65536,w+=String.fromCharCode(55296|k>>10,56320|k&1023))}}else w+=String.fromCharCode(k)}d=w}}else d="";return d}function zi(d,m,_,w){if(!(0=z){var Se=d.charCodeAt(++V);z=65536+((z&1023)<<10)|Se&1023}if(127>=z){if(_>=w)break;m[_++]=z}else{if(2047>=z){if(_+1>=w)break;m[_++]=192|z>>6}else{if(65535>=z){if(_+2>=w)break;m[_++]=224|z>>12}else{if(_+3>=w)break;m[_++]=240|z>>18,m[_++]=128|z>>12&63}m[_++]=128|z>>6&63}m[_++]=128|z&63}}return m[_]=0,_-k}function Ht(d,m,_){return zi(d,re,m,_)}function Wt(d){for(var m=0,_=0;_=w?m++:2047>=w?m+=2:55296<=w&&57343>=w?(m+=4,++_):m+=3}return m}var ui,Je,re,Os,ie,Ps,ls,hs;function mi(){var d=Ds.buffer;ui=d,a.HEAP8=Je=new Int8Array(d),a.HEAP16=Os=new Int16Array(d),a.HEAP32=ie=new Int32Array(d),a.HEAPU8=re=new Uint8Array(d),a.HEAPU16=new Uint16Array(d),a.HEAPU32=Ps=new Uint32Array(d),a.HEAPF32=ls=new Float32Array(d),a.HEAPF64=hs=new Float64Array(d)}var Fs=[],_i=[],vt=[];function zt(){var d=a.preRun.shift();Fs.unshift(d)}var Qe=0,bt=null;function je(d){throw a.onAbort&&a.onAbort(d),d="Aborted("+d+")",as(d),Ue=!0,d=new WebAssembly.RuntimeError(d+". Build with -sASSERTIONS for more info."),p(d),d}function ds(){return we.startsWith("data:application/octet-stream;base64,")}var we;if(we="olm.wasm",!ds()){var us=we;we=a.locateFile?a.locateFile(us,T):T+us}function pi(){var d=we;try{if(d==we&&cs)return new Uint8Array(cs);if(G)return G(d);throw"both async and sync fetching of the wasm failed"}catch(m){je(m)}}function gi(){if(!cs&&(R||N)){if(typeof fetch=="function"&&!we.startsWith("file://"))return fetch(we,{credentials:"same-origin"}).then(function(d){if(!d.ok)throw"failed to load wasm binary file at '"+we+"'";return d.arrayBuffer()}).catch(function(){return pi()});if(B)return new Promise(function(d,m){B(we,function(_){d(new Uint8Array(_))},m)})}return Promise.resolve().then(function(){return pi()})}var St;function at(d){for(;0>0];case"i8":return Je[d>>0];case"i16":return Os[d>>1];case"i32":return ie[d>>2];case"i64":return ie[d>>2];case"float":return ls[d>>2];case"double":return hs[d>>3];case"*":return Ps[d>>2];default:je("invalid type for getValue: "+m)}return null}function Xe(d){var m="i8";switch(m.endsWith("*")&&(m="*"),m){case"i1":Je[d>>0]=0;break;case"i8":Je[d>>0]=0;break;case"i16":Os[d>>1]=0;break;case"i32":ie[d>>2]=0;break;case"i64":St=[0,0],ie[d>>2]=St[0],ie[d+4>>2]=St[1];break;case"float":ls[d>>2]=0;break;case"double":hs[d>>3]=0;break;case"*":Ps[d>>2]=0;break;default:je("invalid type for setValue: "+m)}}function Gt(d,m,_){for(var w=0;w>0]=d.charCodeAt(w);_||(Je[m>>0]=0)}function Ks(d,m,_){return _=Array(0<_?_:Wt(d)+1),d=zi(d,_,0,_.length),m&&(_.length=d),_}var Gi={b:function(d,m,_){re.copyWithin(d,m,m+_)},a:function(d){var m=re.length;if(d>>>=0,2147483648=_;_*=2){var w=m*(1+.2/_);w=Math.min(w,d+100663296);var k=Math;w=Math.max(d,w),k=k.min.call(k,2147483648,w+(65536-w%65536)%65536);e:{try{Ds.grow(k-ui.byteLength+65535>>>16),mi();var V=1;break e}catch{}V=void 0}if(V)return!0}return!1}};(function(){function d(k){a.asm=k.exports,Ds=a.asm.c,mi(),_i.unshift(a.asm.d),Qe--,a.monitorRunDependencies&&a.monitorRunDependencies(Qe),Qe==0&&bt&&(k=bt,bt=null,k())}function m(k){d(k.instance)}function _(k){return gi().then(function(V){return WebAssembly.instantiate(V,w)}).then(function(V){return V}).then(k,function(V){as("failed to asynchronously prepare wasm: "+V),je(V)})}var w={a:Gi};if(Qe++,a.monitorRunDependencies&&a.monitorRunDependencies(Qe),a.instantiateWasm)try{return a.instantiateWasm(w,d)}catch(k){return as("Module.instantiateWasm callback failed with error: "+k),!1}return function(){return cs||typeof WebAssembly.instantiateStreaming!="function"||ds()||we.startsWith("file://")||F||typeof fetch!="function"?_(m):fetch(we,{credentials:"same-origin"}).then(function(k){return WebAssembly.instantiateStreaming(k,w).then(m,function(V){return as("wasm streaming compile failed: "+V),as("falling back to ArrayBuffer instantiation"),_(m)})})}().catch(p),{}})(),a.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.d).apply(null,arguments)},a._olm_get_library_version=function(){return(a._olm_get_library_version=a.asm.f).apply(null,arguments)},a._olm_error=function(){return(a._olm_error=a.asm.g).apply(null,arguments)},a._olm_account_last_error=function(){return(a._olm_account_last_error=a.asm.h).apply(null,arguments)},a.__olm_error_to_string=function(){return(a.__olm_error_to_string=a.asm.i).apply(null,arguments)},a._olm_account_last_error_code=function(){return(a._olm_account_last_error_code=a.asm.j).apply(null,arguments)},a._olm_session_last_error=function(){return(a._olm_session_last_error=a.asm.k).apply(null,arguments)},a._olm_session_last_error_code=function(){return(a._olm_session_last_error_code=a.asm.l).apply(null,arguments)},a._olm_utility_last_error=function(){return(a._olm_utility_last_error=a.asm.m).apply(null,arguments)},a._olm_utility_last_error_code=function(){return(a._olm_utility_last_error_code=a.asm.n).apply(null,arguments)},a._olm_account_size=function(){return(a._olm_account_size=a.asm.o).apply(null,arguments)},a._olm_session_size=function(){return(a._olm_session_size=a.asm.p).apply(null,arguments)},a._olm_utility_size=function(){return(a._olm_utility_size=a.asm.q).apply(null,arguments)},a._olm_account=function(){return(a._olm_account=a.asm.r).apply(null,arguments)},a._olm_session=function(){return(a._olm_session=a.asm.s).apply(null,arguments)},a._olm_utility=function(){return(a._olm_utility=a.asm.t).apply(null,arguments)},a._olm_clear_account=function(){return(a._olm_clear_account=a.asm.u).apply(null,arguments)},a._olm_clear_session=function(){return(a._olm_clear_session=a.asm.v).apply(null,arguments)},a._olm_clear_utility=function(){return(a._olm_clear_utility=a.asm.w).apply(null,arguments)},a._olm_pickle_account_length=function(){return(a._olm_pickle_account_length=a.asm.x).apply(null,arguments)},a._olm_pickle_session_length=function(){return(a._olm_pickle_session_length=a.asm.y).apply(null,arguments)},a._olm_pickle_account=function(){return(a._olm_pickle_account=a.asm.z).apply(null,arguments)},a._olm_pickle_session=function(){return(a._olm_pickle_session=a.asm.A).apply(null,arguments)},a._olm_unpickle_account=function(){return(a._olm_unpickle_account=a.asm.B).apply(null,arguments)},a._olm_unpickle_session=function(){return(a._olm_unpickle_session=a.asm.C).apply(null,arguments)},a._olm_create_account_random_length=function(){return(a._olm_create_account_random_length=a.asm.D).apply(null,arguments)},a._olm_create_account=function(){return(a._olm_create_account=a.asm.E).apply(null,arguments)},a._olm_account_identity_keys_length=function(){return(a._olm_account_identity_keys_length=a.asm.F).apply(null,arguments)},a._olm_account_identity_keys=function(){return(a._olm_account_identity_keys=a.asm.G).apply(null,arguments)},a._olm_account_signature_length=function(){return(a._olm_account_signature_length=a.asm.H).apply(null,arguments)},a._olm_account_sign=function(){return(a._olm_account_sign=a.asm.I).apply(null,arguments)},a._olm_account_one_time_keys_length=function(){return(a._olm_account_one_time_keys_length=a.asm.J).apply(null,arguments)},a._olm_account_one_time_keys=function(){return(a._olm_account_one_time_keys=a.asm.K).apply(null,arguments)},a._olm_account_mark_keys_as_published=function(){return(a._olm_account_mark_keys_as_published=a.asm.L).apply(null,arguments)},a._olm_account_max_number_of_one_time_keys=function(){return(a._olm_account_max_number_of_one_time_keys=a.asm.M).apply(null,arguments)},a._olm_account_generate_one_time_keys_random_length=function(){return(a._olm_account_generate_one_time_keys_random_length=a.asm.N).apply(null,arguments)},a._olm_account_generate_one_time_keys=function(){return(a._olm_account_generate_one_time_keys=a.asm.O).apply(null,arguments)},a._olm_account_generate_fallback_key_random_length=function(){return(a._olm_account_generate_fallback_key_random_length=a.asm.P).apply(null,arguments)},a._olm_account_generate_fallback_key=function(){return(a._olm_account_generate_fallback_key=a.asm.Q).apply(null,arguments)},a._olm_account_fallback_key_length=function(){return(a._olm_account_fallback_key_length=a.asm.R).apply(null,arguments)},a._olm_account_fallback_key=function(){return(a._olm_account_fallback_key=a.asm.S).apply(null,arguments)},a._olm_account_unpublished_fallback_key_length=function(){return(a._olm_account_unpublished_fallback_key_length=a.asm.T).apply(null,arguments)},a._olm_account_unpublished_fallback_key=function(){return(a._olm_account_unpublished_fallback_key=a.asm.U).apply(null,arguments)},a._olm_account_forget_old_fallback_key=function(){return(a._olm_account_forget_old_fallback_key=a.asm.V).apply(null,arguments)},a._olm_create_outbound_session_random_length=function(){return(a._olm_create_outbound_session_random_length=a.asm.W).apply(null,arguments)},a._olm_create_outbound_session=function(){return(a._olm_create_outbound_session=a.asm.X).apply(null,arguments)},a._olm_create_inbound_session=function(){return(a._olm_create_inbound_session=a.asm.Y).apply(null,arguments)},a._olm_create_inbound_session_from=function(){return(a._olm_create_inbound_session_from=a.asm.Z).apply(null,arguments)},a._olm_session_id_length=function(){return(a._olm_session_id_length=a.asm._).apply(null,arguments)},a._olm_session_id=function(){return(a._olm_session_id=a.asm.$).apply(null,arguments)},a._olm_session_has_received_message=function(){return(a._olm_session_has_received_message=a.asm.aa).apply(null,arguments)},a._olm_session_describe=function(){return(a._olm_session_describe=a.asm.ba).apply(null,arguments)},a._olm_matches_inbound_session=function(){return(a._olm_matches_inbound_session=a.asm.ca).apply(null,arguments)},a._olm_matches_inbound_session_from=function(){return(a._olm_matches_inbound_session_from=a.asm.da).apply(null,arguments)},a._olm_remove_one_time_keys=function(){return(a._olm_remove_one_time_keys=a.asm.ea).apply(null,arguments)},a._olm_encrypt_message_type=function(){return(a._olm_encrypt_message_type=a.asm.fa).apply(null,arguments)},a._olm_encrypt_random_length=function(){return(a._olm_encrypt_random_length=a.asm.ga).apply(null,arguments)},a._olm_encrypt_message_length=function(){return(a._olm_encrypt_message_length=a.asm.ha).apply(null,arguments)},a._olm_encrypt=function(){return(a._olm_encrypt=a.asm.ia).apply(null,arguments)},a._olm_decrypt_max_plaintext_length=function(){return(a._olm_decrypt_max_plaintext_length=a.asm.ja).apply(null,arguments)},a._olm_decrypt=function(){return(a._olm_decrypt=a.asm.ka).apply(null,arguments)},a._olm_sha256_length=function(){return(a._olm_sha256_length=a.asm.la).apply(null,arguments)},a._olm_sha256=function(){return(a._olm_sha256=a.asm.ma).apply(null,arguments)},a._olm_ed25519_verify=function(){return(a._olm_ed25519_verify=a.asm.na).apply(null,arguments)},a._olm_pk_encryption_last_error=function(){return(a._olm_pk_encryption_last_error=a.asm.oa).apply(null,arguments)},a._olm_pk_encryption_last_error_code=function(){return(a._olm_pk_encryption_last_error_code=a.asm.pa).apply(null,arguments)},a._olm_pk_encryption_size=function(){return(a._olm_pk_encryption_size=a.asm.qa).apply(null,arguments)},a._olm_pk_encryption=function(){return(a._olm_pk_encryption=a.asm.ra).apply(null,arguments)},a._olm_clear_pk_encryption=function(){return(a._olm_clear_pk_encryption=a.asm.sa).apply(null,arguments)},a._olm_pk_encryption_set_recipient_key=function(){return(a._olm_pk_encryption_set_recipient_key=a.asm.ta).apply(null,arguments)},a._olm_pk_key_length=function(){return(a._olm_pk_key_length=a.asm.ua).apply(null,arguments)},a._olm_pk_ciphertext_length=function(){return(a._olm_pk_ciphertext_length=a.asm.va).apply(null,arguments)},a._olm_pk_mac_length=function(){return(a._olm_pk_mac_length=a.asm.wa).apply(null,arguments)},a._olm_pk_encrypt_random_length=function(){return(a._olm_pk_encrypt_random_length=a.asm.xa).apply(null,arguments)},a._olm_pk_encrypt=function(){return(a._olm_pk_encrypt=a.asm.ya).apply(null,arguments)},a._olm_pk_decryption_last_error=function(){return(a._olm_pk_decryption_last_error=a.asm.za).apply(null,arguments)},a._olm_pk_decryption_last_error_code=function(){return(a._olm_pk_decryption_last_error_code=a.asm.Aa).apply(null,arguments)},a._olm_pk_decryption_size=function(){return(a._olm_pk_decryption_size=a.asm.Ba).apply(null,arguments)},a._olm_pk_decryption=function(){return(a._olm_pk_decryption=a.asm.Ca).apply(null,arguments)},a._olm_clear_pk_decryption=function(){return(a._olm_clear_pk_decryption=a.asm.Da).apply(null,arguments)},a._olm_pk_private_key_length=function(){return(a._olm_pk_private_key_length=a.asm.Ea).apply(null,arguments)},a._olm_pk_generate_key_random_length=function(){return(a._olm_pk_generate_key_random_length=a.asm.Fa).apply(null,arguments)},a._olm_pk_key_from_private=function(){return(a._olm_pk_key_from_private=a.asm.Ga).apply(null,arguments)},a._olm_pk_generate_key=function(){return(a._olm_pk_generate_key=a.asm.Ha).apply(null,arguments)},a._olm_pickle_pk_decryption_length=function(){return(a._olm_pickle_pk_decryption_length=a.asm.Ia).apply(null,arguments)},a._olm_pickle_pk_decryption=function(){return(a._olm_pickle_pk_decryption=a.asm.Ja).apply(null,arguments)},a._olm_unpickle_pk_decryption=function(){return(a._olm_unpickle_pk_decryption=a.asm.Ka).apply(null,arguments)},a._olm_pk_max_plaintext_length=function(){return(a._olm_pk_max_plaintext_length=a.asm.La).apply(null,arguments)},a._olm_pk_decrypt=function(){return(a._olm_pk_decrypt=a.asm.Ma).apply(null,arguments)},a._olm_pk_get_private_key=function(){return(a._olm_pk_get_private_key=a.asm.Na).apply(null,arguments)},a._olm_pk_signing_size=function(){return(a._olm_pk_signing_size=a.asm.Oa).apply(null,arguments)},a._olm_pk_signing=function(){return(a._olm_pk_signing=a.asm.Pa).apply(null,arguments)},a._olm_pk_signing_last_error=function(){return(a._olm_pk_signing_last_error=a.asm.Qa).apply(null,arguments)},a._olm_pk_signing_last_error_code=function(){return(a._olm_pk_signing_last_error_code=a.asm.Ra).apply(null,arguments)},a._olm_clear_pk_signing=function(){return(a._olm_clear_pk_signing=a.asm.Sa).apply(null,arguments)},a._olm_pk_signing_seed_length=function(){return(a._olm_pk_signing_seed_length=a.asm.Ta).apply(null,arguments)},a._olm_pk_signing_public_key_length=function(){return(a._olm_pk_signing_public_key_length=a.asm.Ua).apply(null,arguments)},a._olm_pk_signing_key_from_seed=function(){return(a._olm_pk_signing_key_from_seed=a.asm.Va).apply(null,arguments)},a._olm_pk_signature_length=function(){return(a._olm_pk_signature_length=a.asm.Wa).apply(null,arguments)},a._olm_pk_sign=function(){return(a._olm_pk_sign=a.asm.Xa).apply(null,arguments)},a._olm_inbound_group_session_size=function(){return(a._olm_inbound_group_session_size=a.asm.Ya).apply(null,arguments)},a._olm_inbound_group_session=function(){return(a._olm_inbound_group_session=a.asm.Za).apply(null,arguments)},a._olm_clear_inbound_group_session=function(){return(a._olm_clear_inbound_group_session=a.asm._a).apply(null,arguments)},a._olm_inbound_group_session_last_error=function(){return(a._olm_inbound_group_session_last_error=a.asm.$a).apply(null,arguments)},a._olm_inbound_group_session_last_error_code=function(){return(a._olm_inbound_group_session_last_error_code=a.asm.ab).apply(null,arguments)},a._olm_init_inbound_group_session=function(){return(a._olm_init_inbound_group_session=a.asm.bb).apply(null,arguments)},a._olm_import_inbound_group_session=function(){return(a._olm_import_inbound_group_session=a.asm.cb).apply(null,arguments)},a._olm_pickle_inbound_group_session_length=function(){return(a._olm_pickle_inbound_group_session_length=a.asm.db).apply(null,arguments)},a._olm_pickle_inbound_group_session=function(){return(a._olm_pickle_inbound_group_session=a.asm.eb).apply(null,arguments)},a._olm_unpickle_inbound_group_session=function(){return(a._olm_unpickle_inbound_group_session=a.asm.fb).apply(null,arguments)},a._olm_group_decrypt_max_plaintext_length=function(){return(a._olm_group_decrypt_max_plaintext_length=a.asm.gb).apply(null,arguments)},a._olm_group_decrypt=function(){return(a._olm_group_decrypt=a.asm.hb).apply(null,arguments)},a._olm_inbound_group_session_id_length=function(){return(a._olm_inbound_group_session_id_length=a.asm.ib).apply(null,arguments)},a._olm_inbound_group_session_id=function(){return(a._olm_inbound_group_session_id=a.asm.jb).apply(null,arguments)},a._olm_inbound_group_session_first_known_index=function(){return(a._olm_inbound_group_session_first_known_index=a.asm.kb).apply(null,arguments)},a._olm_inbound_group_session_is_verified=function(){return(a._olm_inbound_group_session_is_verified=a.asm.lb).apply(null,arguments)},a._olm_export_inbound_group_session_length=function(){return(a._olm_export_inbound_group_session_length=a.asm.mb).apply(null,arguments)},a._olm_export_inbound_group_session=function(){return(a._olm_export_inbound_group_session=a.asm.nb).apply(null,arguments)},a._olm_outbound_group_session_size=function(){return(a._olm_outbound_group_session_size=a.asm.ob).apply(null,arguments)},a._olm_outbound_group_session=function(){return(a._olm_outbound_group_session=a.asm.pb).apply(null,arguments)},a._olm_clear_outbound_group_session=function(){return(a._olm_clear_outbound_group_session=a.asm.qb).apply(null,arguments)},a._olm_outbound_group_session_last_error=function(){return(a._olm_outbound_group_session_last_error=a.asm.rb).apply(null,arguments)},a._olm_outbound_group_session_last_error_code=function(){return(a._olm_outbound_group_session_last_error_code=a.asm.sb).apply(null,arguments)},a._olm_pickle_outbound_group_session_length=function(){return(a._olm_pickle_outbound_group_session_length=a.asm.tb).apply(null,arguments)},a._olm_pickle_outbound_group_session=function(){return(a._olm_pickle_outbound_group_session=a.asm.ub).apply(null,arguments)},a._olm_unpickle_outbound_group_session=function(){return(a._olm_unpickle_outbound_group_session=a.asm.vb).apply(null,arguments)},a._olm_init_outbound_group_session_random_length=function(){return(a._olm_init_outbound_group_session_random_length=a.asm.wb).apply(null,arguments)},a._olm_init_outbound_group_session=function(){return(a._olm_init_outbound_group_session=a.asm.xb).apply(null,arguments)},a._olm_group_encrypt_message_length=function(){return(a._olm_group_encrypt_message_length=a.asm.yb).apply(null,arguments)},a._olm_group_encrypt=function(){return(a._olm_group_encrypt=a.asm.zb).apply(null,arguments)},a._olm_outbound_group_session_id_length=function(){return(a._olm_outbound_group_session_id_length=a.asm.Ab).apply(null,arguments)},a._olm_outbound_group_session_id=function(){return(a._olm_outbound_group_session_id=a.asm.Bb).apply(null,arguments)},a._olm_outbound_group_session_message_index=function(){return(a._olm_outbound_group_session_message_index=a.asm.Cb).apply(null,arguments)},a._olm_outbound_group_session_key_length=function(){return(a._olm_outbound_group_session_key_length=a.asm.Db).apply(null,arguments)},a._olm_outbound_group_session_key=function(){return(a._olm_outbound_group_session_key=a.asm.Eb).apply(null,arguments)},a._olm_sas_last_error=function(){return(a._olm_sas_last_error=a.asm.Fb).apply(null,arguments)},a._olm_sas_last_error_code=function(){return(a._olm_sas_last_error_code=a.asm.Gb).apply(null,arguments)},a._olm_sas_size=function(){return(a._olm_sas_size=a.asm.Hb).apply(null,arguments)},a._olm_sas=function(){return(a._olm_sas=a.asm.Ib).apply(null,arguments)},a._olm_clear_sas=function(){return(a._olm_clear_sas=a.asm.Jb).apply(null,arguments)},a._olm_create_sas_random_length=function(){return(a._olm_create_sas_random_length=a.asm.Kb).apply(null,arguments)},a._olm_create_sas=function(){return(a._olm_create_sas=a.asm.Lb).apply(null,arguments)},a._olm_sas_pubkey_length=function(){return(a._olm_sas_pubkey_length=a.asm.Mb).apply(null,arguments)},a._olm_sas_get_pubkey=function(){return(a._olm_sas_get_pubkey=a.asm.Nb).apply(null,arguments)},a._olm_sas_set_their_key=function(){return(a._olm_sas_set_their_key=a.asm.Ob).apply(null,arguments)},a._olm_sas_is_their_key_set=function(){return(a._olm_sas_is_their_key_set=a.asm.Pb).apply(null,arguments)},a._olm_sas_generate_bytes=function(){return(a._olm_sas_generate_bytes=a.asm.Qb).apply(null,arguments)},a._olm_sas_mac_length=function(){return(a._olm_sas_mac_length=a.asm.Rb).apply(null,arguments)},a._olm_sas_calculate_mac_fixed_base64=function(){return(a._olm_sas_calculate_mac_fixed_base64=a.asm.Sb).apply(null,arguments)},a._olm_sas_calculate_mac=function(){return(a._olm_sas_calculate_mac=a.asm.Tb).apply(null,arguments)},a._olm_sas_calculate_mac_long_kdf=function(){return(a._olm_sas_calculate_mac_long_kdf=a.asm.Ub).apply(null,arguments)},a._malloc=function(){return(a._malloc=a.asm.Vb).apply(null,arguments)},a._free=function(){return(a._free=a.asm.Wb).apply(null,arguments)};var Bs=a.stackSave=function(){return(Bs=a.stackSave=a.asm.Xb).apply(null,arguments)},$s=a.stackRestore=function(){return($s=a.stackRestore=a.asm.Yb).apply(null,arguments)},Ze=a.stackAlloc=function(){return(Ze=a.stackAlloc=a.asm.Zb).apply(null,arguments)};a.UTF8ToString=U,a.stringToUTF8=Ht,a.intArrayFromString=Ks,a.writeAsciiToMemory=Gt,a.ALLOC_STACK=1;var kt;bt=function d(){kt||js(),kt||(bt=d)};function js(){function d(){if(!kt&&(kt=!0,a.calledRun=!0,!Ue)){if(at(_i),u(a),a.onRuntimeInitialized&&a.onRuntimeInitialized(),a.postRun)for(typeof a.postRun=="function"&&(a.postRun=[a.postRun]);a.postRun.length;){var m=a.postRun.shift();vt.unshift(m)}at(vt)}}if(!(0[],(t,s)=>t.push(s))}function En(n,e,t,s){return n.reduce((i,r)=>{const o=e(r);let c=i.get(o);return c||(c=t(),i.set(o,c)),s(c,r),i},new Map)}function uo(n,e){return n.reduce((t,s)=>{const i=e(s);return t[i]?t[i]+=1:t[i]=1,t},{})}function Pe(){return Ir("t")}function Ir(n){const t=Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16);return n+"0".repeat(14-t.length)+t}function mo(n){return n.startsWith("t")&&n.length===15}function Fi(n){const e=ti(n,s=>s.device.user_id);return{messages:Array.from(e.entries()).reduce((s,[i,r])=>(s[i]=r.reduce((o,c)=>(o[c.device.device_id]=c.content,o),{}),s),{})}}function Br(n){typeof n=="function"?n():n.dispose()}function gd(n){return n&&(typeof n=="function"||typeof n.dispose=="function")}class li{constructor(){this._disposables=[]}track(e){if(!gd(e))throw new Error("Not a disposable");return this.isDisposed?(console.warn("Disposables already disposed, disposing new value"),Br(e),e):(this._disposables.push(e),e)}untrack(e){if(!this._disposables)return;const t=this._disposables.indexOf(e);t>=0&&this._disposables.splice(t,1)}dispose(){if(this._disposables){for(const e of this._disposables)Br(e);this._disposables=void 0}}get isDisposed(){return this._disposables===void 0}disposeTracked(e){if(e==null||this.isDisposed)return;const t=this._disposables.indexOf(e);if(t!==-1){const[s]=this._disposables.splice(t,1);Br(s)}else console.warn("disposable not found, did it leak?",e)}}class fd extends li{constructor(e,t){super(),this.sentMessages=new Map,this.receivedMessages=new Map,this.waitMap=new Map,this.hsApi=e.hsApi,this.deviceTracker=e.deviceTracker,this.otherUserId=e.otherUserId,this.ourDeviceId=e.ourUserDeviceId,this.clock=e.clock,this.log=e.log,this.deviceMessageHandler=e.deviceMessageHandler,this.track(this.deviceMessageHandler.disposableOn("message",async({unencrypted:s})=>{!s||await this.handleDeviceMessage(s)})),this.track(()=>{this.waitMap.forEach(s=>{s.reject(new pt)})}),t&&(this.id=t.content.transaction_id,this.receivedMessages.set(t.type,t),this.otherUserDeviceId=t.content.from_device)}get cancellation(){return this._cancellation}get isCancelled(){return!!this._cancellation}async send(e,t,s){await s.wrap("ToDeviceChannel.send",async()=>{if(this.isCancelled)throw new pt;if(e===P.Request){await this.handleRequestEventSpecially(e,t,s);return}Object.assign(t,{transaction_id:this.id});const i={messages:{[this.otherUserId]:{[this.otherUserDeviceId]:t}}};await this.hsApi.sendToDevice(e,i,Pe(),{log:s}).response(),this.sentMessages.set(e,{content:t})})}async handleRequestEventSpecially(e,t,s){await s.wrap("ToDeviceChannel.handleRequestEventSpecially",async()=>{const i=this.clock.now(),r=Pe();this.id=r,Object.assign(t,{timestamp:i,transaction_id:r});const o={messages:{[this.otherUserId]:{"*":t}}};await this.hsApi.sendToDevice(e,o,Pe(),{log:s}).response(),this.sentMessages.set(e,{content:t})})}getReceivedMessage(e){return this.receivedMessages.get(e)}getSentMessage(e){return this.sentMessages.get(e)}get acceptMessage(){var e;return(e=this.receivedMessages.get(P.Accept))!=null?e:this.sentMessages.get(P.Accept)}async handleDeviceMessage(e){await this.log.wrap("ToDeviceChannel.handleDeviceMessage",async t=>{if(!!e.type.startsWith("m.key.verification.")){if(e.content.transaction_id!==this.id){await this.cancelVerification(A.UnknownTransaction);return}if(this.resolveAnyWaits(e),this.receivedMessages.set(e.type,e),e.type===P.Ready){this.handleReadyMessage(e,t);return}if(e.type===P.Cancel){this._cancellation={code:e.content.code,cancelledByUs:!1},this.dispose();return}}})}async handleReadyMessage(e,t){const s=e.content.from_device;this.otherUserDeviceId=s;const r=(await this.deviceTracker.devicesForUsers([this.otherUserId],this.hsApi,t)).filter(h=>h.device_id!==s&&h.device_id!==this.ourDeviceId),o={code:A.OtherDeviceAccepted,reason:kr[A.OtherDeviceAccepted],transaction_id:this.id},c=r.reduce((h,a)=>(h[a.device_id]=o,h),{}),l={messages:{[this.otherUserId]:c}};await this.hsApi.sendToDevice(P.Cancel,l,Pe(),{log:t}).response()}async cancelVerification(e){await this.log.wrap("Channel.cancelVerification",async t=>{var i;if(this.isCancelled)throw new pt;const s={messages:{[this.otherUserId]:{[(i=this.otherUserDeviceId)!=null?i:"*"]:{code:e,reason:kr[e],transaction_id:this.id}}}};await this.hsApi.sendToDevice(P.Cancel,s,Pe(),{log:t}).response(),this._cancellation={code:e,cancelledByUs:!0},this.dispose()})}resolveAnyWaits(e){const{type:t}=e,s=this.waitMap.get(t);s&&(s.resolve(e),this.waitMap.delete(t))}waitForEvent(e){if(this.isCancelled)throw new pt;const t=this.receivedMessages.get(e);if(t)return Promise.resolve(t);const s=this.waitMap.get(e);if(s)return s.promise;const i=new As;return this.waitMap.set(e,i),i.promise}setStartMessage(e){this.startMessage=e,this._initiatedByUs=e.content.from_device===this.ourDeviceId}get initiatedByUs(){return this._initiatedByUs}}class yd extends li{constructor(e,t){var s,i;if(super(),this.sentMessages=new Map,this.receivedMessages=new Map,this.waitMap=new Map,this.otherUserId=e.otherUserId,this.ourUserId=e.ourUserId,this.ourDeviceId=e.ourUserDeviceId,this.log=e.log,this.room=e.room,this.subscribeToTimeline(),this.track(()=>{this.waitMap.forEach(r=>{r.reject(new pt)})}),t){this.id=t.id;const r=(i=(s=t.content)==null?void 0:s.msgtype)!=null?i:t.eventType;this.receivedMessages.set(r,t),this.otherUserDeviceId=t.content.from_device}}async subscribeToTimeline(){const e=await this.room.openTimeline();this.track(()=>e.release()),this.track(e.entries.subscribe({onAdd:async(t,s)=>{this.handleRoomMessage(s)},onRemove:()=>{},onUpdate:()=>{}}))}get cancellation(){return this._cancellation}get isCancelled(){return!!this._cancellation}async send(e,t,s){await s.wrap("RoomChannel.send",async i=>{if(this.isCancelled)throw new pt;if(e===P.Request){await this.handleRequestEventSpecially(e,t,s);return}!this.id||(await this.room.ensureMessageKeyIsShared(i),Object.assign(t,th(this.id)),await this.room.sendEvent(e,t,void 0,s),this.sentMessages.set(e,{content:t}))})}async handleRequestEventSpecially(e,t,s){await s.wrap("RoomChannel.handleRequestEventSpecially",async()=>{Object.assign(t,{body:`${this.otherUserId} 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:P.Request,to:this.otherUserId});const i=await this.room.sendEvent("m.room.message",t,void 0,s);this.id=await i.getRemoteId(),this.sentMessages.set(e,{content:t})})}getReceivedMessage(e){return this.receivedMessages.get(e)}getSentMessage(e){return this.sentMessages.get(e)}get acceptMessage(){var e;return(e=this.receivedMessages.get(P.Accept))!=null?e:this.sentMessages.get(P.Accept)}async handleRoomMessage(e){var s,i;const t=(i=(s=e.content)==null?void 0:s.msgtype)!=null?i:e.eventType;!(t!=null&&t.startsWith("m.key.verification"))||e.sender===this.ourUserId||e.isLoadedFromStorage||await this.log.wrap("RoomChannel.handleRoomMessage",async r=>{if(!this.id)throw new Error("Couldn't find event-id of request message!");if(va(e.event)!==this.id){await this.cancelVerification(A.UnknownTransaction);return}if(this.resolveAnyWaits(e),this.receivedMessages.set(e.eventType,e),e.eventType===P.Ready){const o=e.content.from_device;this.otherUserDeviceId=o;return}if(e.eventType===P.Cancel){this._cancellation={code:e.content.code,cancelledByUs:!1},this.dispose();return}})}async cancelVerification(e){await this.log.wrap("RoomChannel.cancelVerification",async t=>{if(t.log({reason:kr[e]}),this.isCancelled)throw new pt;const s={code:e,reason:kr[e]};await this.send(P.Cancel,s,t),this._cancellation={code:e,cancelledByUs:!0},this.dispose()})}resolveAnyWaits(e){const{eventType:t}=e,s=this.waitMap.get(t);s&&(s.resolve(e),this.waitMap.delete(t))}waitForEvent(e){if(this.isCancelled)throw new pt;const t=this.receivedMessages.get(e);if(t)return Promise.resolve(t);const s=this.waitMap.get(e);if(s)return s.promise;const i=new As;return this.waitMap.set(e,i),i.promise}setStartMessage(e){if(e.content["m.relates_to"])this.startMessage=e;else{const t=e.clone();t.content["m.relates_to"]=t.event.content["m.relates_to"],this.startMessage=t}this._initiatedByUs=e.content.from_device===this.ourDeviceId}get initiatedByUs(){return this._initiatedByUs}}class pr{constructor(e){this.startingMessage=e}get deviceId(){return this.startingMessage.content.from_device}get sender(){return this.startingMessage.sender}get id(){var e;return(e=this.startingMessage.content.transaction_id)!=null?e:this.startingMessage.eventId}async reject(e,t,s){const i=e.startVerification(this,t,s);await(i==null?void 0:i.abort())}}var Et=(n=>(n.Master="master",n.SelfSigning="self_signing",n.UserSigning="user_signing",n))(Et||{}),et=(n=>(n[n.Trusted=1]="Trusted",n[n.UserNotSigned=2]="UserNotSigned",n[n.UserSignatureMismatch=3]="UserSignatureMismatch",n[n.UserDeviceNotSigned=4]="UserDeviceNotSigned",n[n.UserDeviceSignatureMismatch=5]="UserDeviceSignatureMismatch",n[n.UserSetupError=6]="UserSetupError",n[n.OwnSetupError=7]="OwnSetupError",n))(et||{});class wd{constructor(e){this._isMasterKeyTrusted=!1,this.observedUsers=new Map,this.receivedSASVerifications=new Dt,this.storage=e.storage,this.secretFetcher=e.secretFetcher,this.platform=e.platform,this.deviceTracker=e.deviceTracker,this.olm=e.olm,this.olmUtil=e.olmUtil,this.hsApi=e.hsApi,this.ownUserId=e.ownUserId,this.deviceId=e.deviceId,this.e2eeAccount=e.e2eeAccount,this.deviceMessageHandler=e.deviceMessageHandler,this.handleSASDeviceMessage=this.handleSASDeviceMessage.bind(this),this.deviceMessageHandler.on("message",this.handleSASDeviceMessage)}async load(e){return await this.verifyMSKFrom4S(!1,e)!==0}async start(e){this.isMasterKeyTrusted||await this.verifyMSKFrom4S(!0,e)}async verifyMSKFrom4S(e,t){return await t.wrap("CrossSigning.verifyMSKFrom4S",async s=>{const i=await this.getSigningKey("master");if(!i)return s.set("failure","no_priv_msk"),0;const r=new this.olm.PkSigning;let o;try{o=r.init_with_seed(i)}finally{r.free()}const c=await this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"master",e?this.hsApi:void 0,s);if(!c)return s.set("failure","no_pub_msk"),1;const l=c&&Qs(c);return s.set({publishedMasterKey:l,derivedPublicKey:o}),this._isMasterKeyTrusted=!!l&&l===o,this._isMasterKeyTrusted?3:(s.set("failure","mismatch"),2)})}get isMasterKeyTrusted(){return this._isMasterKeyTrusted}startVerification(e,t,s){const i=s!=null?s:t;if(this.sasVerificationInProgress&&!this.sasVerificationInProgress.finished){i.log({sasVerificationAlreadyInProgress:!0});return}const r=e instanceof pr?e.sender:e,o=e instanceof pr?e.startingMessage:void 0;let c;return r===this.ownUserId?c=new fd({deviceTracker:this.deviceTracker,hsApi:this.hsApi,otherUserId:r,clock:this.platform.clock,deviceMessageHandler:this.deviceMessageHandler,ourUserDeviceId:this.deviceId,log:i},o):c=new yd({room:t,otherUserId:r,ourUserId:this.ownUserId,ourUserDeviceId:this.deviceId,log:i},o),this.sasVerificationInProgress=new pd({olm:this.olm,olmUtil:this.olmUtil,ourUserId:this.ownUserId,ourUserDeviceId:this.deviceId,otherUserId:r,log:i,channel:c,e2eeAccount:this.e2eeAccount,deviceTracker:this.deviceTracker,hsApi:this.hsApi,clock:this.platform.clock}),this.sasVerificationInProgress}async handleSASDeviceMessage({unencrypted:e}){!e||e.type!==P.Request&&e.type!==P.Start||await this.platform.logger.run("CrossSigning.handleSASDeviceMessage",async t=>{var c;const s=e.content.transaction_id,i=e.content.from_device,r=e.sender;if(!i||r!==this.ownUserId)return;if(!await this.areWeVerified(t)){const l=await this.deviceTracker.deviceForId(this.ownUserId,i,this.hsApi,t);if(!l||!await this.isOurUserDeviceTrusted(l,t))return}if(((c=this.sasVerificationInProgress)==null?void 0:c.channel.id)!==s)switch(e.type){case P.Cancel:this.receivedSASVerifications.remove(s);return;case P.Request:case P.Start:this.platform.logger.run("Create SASRequest",()=>{this.receivedSASVerifications.set(s,new pr(e))});return;default:return}})}async signOwnDevice(e){return e.wrap("CrossSigning.signOwnDevice",async t=>{if(!this._isMasterKeyTrusted){t.set("mskNotTrusted",!0);return}const s=this.e2eeAccount.getUnsignedDeviceKey();return this.signDeviceKey(s,t)})}async signDevice(e,t){return t.wrap("CrossSigning.signDevice",async s=>{this._isMasterKeyTrusted||s.set("mskNotTrusted",!0);const i=await e.verify()&&this._isMasterKeyTrusted;if(s.set("shouldSign",i),!i)return;const r=e.otherDeviceId;s.set("id",r);const o=await this.deviceTracker.deviceForId(this.ownUserId,r,this.hsApi,s);if(!!o)return delete o.signatures,this.signDeviceKey(o,s)})}async signUser(e,t){return t.wrap("CrossSigning.signUser",async s=>{const i=e.otherUserId;if(s.set("id",i),!this._isMasterKeyTrusted){s.set("mskNotTrusted",!0);return}if(i===this.ownUserId)return;const r=await e.verify();if(s.set("shouldSign",r),!r)return;const o=await this.deviceTracker.getCrossSigningKeyForUser(i,"master",this.hsApi,s);if(!o)return;const c=await this.getSigningKey("user_signing");if(!c)return;delete o.signatures,this.signKey(o,c);const l={[o.user_id]:{[Qs(o)]:o}};return await this.hsApi.uploadSignatures(l,{log:s}).response(),await this.deviceTracker.invalidateUserKeys(i),this.emitUserTrustUpdate(i,s),o})}async isOurUserDeviceTrusted(e,t){return await this.platform.logger.wrapOrRun(t,"CrossSigning.isOurUserDeviceTrusted",async s=>{const i=await this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"self_signing",this.hsApi,s);return i?this.hasValidSignatureFrom(e,i,s)===ne.Valid:!1})}areWeVerified(e){return this.platform.logger.wrapOrRun(e,"CrossSigning.areWeVerified",async t=>{const s=await this.deviceTracker.deviceForId(this.ownUserId,this.deviceId,this.hsApi,t);return this.isOurUserDeviceTrusted(s,e)})}getUserTrust(e,t){return t.wrap("CrossSigning.getUserTrust",async s=>{s.set("id",e);const i=f=>(s.set("result",f),f);if(!this.isMasterKeyTrusted)return i(7);const r=await s.wrap("get our msk",f=>this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"master",this.hsApi,f));if(!r)return i(7);const o=await s.wrap("get our usk",f=>this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"user_signing",this.hsApi,f));if(!o||s.wrap("verify our usk",f=>this.hasValidSignatureFrom(o,r,f))!==ne.Valid)return i(7);const l=await s.wrap("get their msk",f=>this.deviceTracker.getCrossSigningKeyForUser(e,"master",this.hsApi,f));if(!l)return i(2);const h=s.wrap("verify their msk",f=>this.hasValidSignatureFrom(l,o,f));if(h!==ne.Valid)return h===ne.NotSigned?i(2):i(3);const a=await s.wrap("get their ssk",f=>this.deviceTracker.getCrossSigningKeyForUser(e,"self_signing",this.hsApi,f));if(!a||s.wrap("verify their ssk",f=>this.hasValidSignatureFrom(a,l,f))!==ne.Valid)return i(6);const g=(await s.wrap("get their devices",f=>this.deviceTracker.devicesForUsers([e],this.hsApi,f))).reduce((f,v)=>s.wrap({l:"verify device",id:v.device_id},M=>{const R=this.hasValidSignatureFrom(v,a,M);return f===ne.Invalid||R===ne.Invalid?ne.Invalid:f===ne.NotSigned||R===ne.NotSigned?ne.NotSigned:f===ne.Valid||R===ne.Valid?ne.Valid:ne.Invalid}),ne.Valid);return g!==ne.Valid?g===ne.NotSigned?i(4):i(5):i(1)})}dispose(){this.deviceMessageHandler.off("message",this.handleSASDeviceMessage)}observeUserTrust(e,t){const s=this.observedUsers.get(e);if(s)return s;const i=new Ui(void 0,()=>{this.observedUsers.delete(e)});return this.observedUsers.set(e,i),t.wrapDetached("get user trust",async r=>{i.get()===void 0&&i.set(await this.getUserTrust(e,r))}),i}async signDeviceKey(e,t){const s=await this.getSigningKey("self_signing");if(!s)return;this.signKey(e,s);const i={[e.user_id]:{[e.device_id]:e}};return await this.hsApi.uploadSignatures(i,{log:t}).response(),await this.deviceTracker.invalidateUserKeys(this.ownUserId),this.emitUserTrustUpdate(this.ownUserId,t),e}async getSigningKey(e){const t=await this.secretFetcher.getSecret(`m.cross_signing.${e}`);if(t)return new Uint8Array(this.platform.encoding.base64.decode(t))}signKey(e,t){Zh(this.olm,e,t,this.ownUserId,"")}hasValidSignatureFrom(e,t,s){const i=Qs(t);return i?vn(this.olmUtil,t.user_id,i,i,e,s):ne.NotSigned}emitUserTrustUpdate(e,t){const s=this.observedUsers.get(e);s&&s.get()!==void 0&&(s.set(void 0),t.wrapDetached("update user trust",async i=>{s.set(await this.getUserTrust(e,i))}))}}function vd(n){if(!Array.isArray(n.usage)||n.usage.length!==1)return;const e=n.usage[0];if(!(e!=="master"&&e!=="self_signing"&&e!=="user_signing"))return e}const bd="ed25519",Sd=`${bd}:`;function Qs(n){const e=Object.keys(n.keys).filter(i=>i.startsWith(Sd));if(e.length!==1)return;const t=e[0];return n.keys[t]}function _o(n){return n.user_id}var Oa=(n=>(n[n.Outdated=0]="Outdated",n[n.UpToDate=1]="UpToDate",n))(Oa||{});function Pa(n,e){return{userId:n,roomIds:e?[e]:[],keysTrackingStatus:0}}function kd(n,e,t){if(n){if(!n.roomIds.includes(t))return n.roomIds.push(t),n}else return n=Pa(e,t),n}class Id{constructor(e){this._storage=e.storage,this._getSyncToken=e.getSyncToken,this._olmUtil=e.olmUtil,this._ownUserId=e.ownUserId,this._ownDeviceId=e.ownDeviceId}async writeDeviceChanges(e,t,s){const{userIdentities:i}=t;s.set("changed",e.length),await Promise.all(e.map(async r=>{const o=await i.get(r);o&&(s.log({l:"outdated",id:r}),o.keysTrackingStatus=0,i.set(o))}))}async writeMemberChanges(e,t,s,i){const r=[],o=[];return await Promise.all(Array.from(t.values()).map(async c=>{if(Xi(c.membership,s))await this._addRoomToUserIdentity(c.roomId,c.userId,i)&&r.push(c.userId);else if(Xi(c.previousMembership,s)){const{roomId:l}=c;if(c.userId===this._ownUserId){const h=await i.roomMembers.getAllUserIds(l);await Promise.all(h.map(a=>this._removeRoomFromUserIdentity(l,a,i)))}else await this._removeRoomFromUserIdentity(l,c.userId,i);o.push(c.userId)}})),{added:r,removed:o}}async trackRoom(e,t,s){if(e.isTrackingMembers||!e.isEncrypted)return;const i=await e.loadMemberList(void 0,s),r=await this._storage.readWriteTxn([this._storage.storeNames.roomSummary,this._storage.storeNames.userIdentities,this._storage.storeNames.deviceKeys]);try{let o;try{o=e.writeIsTrackingMembers(!0,r);const c=Array.from(i.members.values());s.set("members",c.length),await Promise.all(c.map(async l=>{Xi(l.membership,t)?await this._addRoomToUserIdentity(l.roomId,l.userId,r):await this._removeRoomFromUserIdentity(l.roomId,l.userId,r)}))}catch(c){throw r.abort(),c}await r.complete(),e.applyIsTrackingMembersChanges(o)}finally{i.release()}}async invalidateUserKeys(e){const t=await this._storage.readWriteTxn([this._storage.storeNames.userIdentities]),s=await t.userIdentities.get(e);s&&(s.keysTrackingStatus=0,t.userIdentities.set(s)),await t.complete()}async getCrossSigningKeyForUser(e,t,s,i){return await i.wrap({l:"DeviceTracker.getCrossSigningKeyForUser",id:e,usage:t},async r=>{const o=await this._storage.readTxn([this._storage.storeNames.userIdentities,this._storage.storeNames.crossSigningKeys]),c=await o.userIdentities.get(e);if(c&&c.keysTrackingStatus!==0)return await o.crossSigningKeys.get(e,t);if(!s)return;const l=await this._queryKeys([e],s,r);switch(t){case Et.Master:return l.masterKeys.get(e);case Et.SelfSigning:return l.selfSigningKeys.get(e);case Et.UserSigning:return l.userSigningKeys.get(e)}})}async writeHistoryVisibility(e,t,s,i){const r=[],o=[];return e.isTrackingMembers&&e.isEncrypted&&await i.wrap("rewriting userIdentities",async c=>{const l=await e.loadMemberList(s,c);try{const h=Array.from(l.members.values());c.set("members",h.length),await Promise.all(h.map(async a=>{Xi(a.membership,t)?await this._addRoomToUserIdentity(a.roomId,a.userId,s)&&r.push(a.userId):await this._removeRoomFromUserIdentity(a.roomId,a.userId,s)&&o.push(a.userId)}))}finally{l.release()}}),{added:r,removed:o}}async _addRoomToUserIdentity(e,t,s){const{userIdentities:i}=s,r=await i.get(t),o=kd(r,t,e);return o?(i.set(o),!0):!1}async _removeRoomFromUserIdentity(e,t,s){const{userIdentities:i,deviceKeys:r}=s,o=await i.get(t);return o?(o.roomIds=o.roomIds.filter(c=>c!==e),o.roomIds.length===0?(i.remove(t),r.removeAllForUser(t)):i.set(o),!0):!1}async _queryKeys(e,t,s){const i=await t.queryKeys({timeout:1e4,device_keys:e.reduce((a,u)=>(a[u]=[],a),{}),token:this._getSyncToken()},{log:s}).response(),r=s.wrap("master keys",a=>this._filterVerifiedCrossSigningKeys(i.master_keys,Et.Master,a)),o=s.wrap("self-signing keys",a=>this._filterVerifiedCrossSigningKeys(i.self_signing_keys,Et.SelfSigning,a)),c=s.wrap("user-signing keys",a=>this._filterVerifiedCrossSigningKeys(i.user_signing_keys,Et.UserSigning,a)),l=s.wrap("device keys",a=>this._filterVerifiedDeviceKeys(i.device_keys,a)),h=await this._storage.readWriteTxn([this._storage.storeNames.userIdentities,this._storage.storeNames.deviceKeys,this._storage.storeNames.crossSigningKeys]);try{for(const u of r.values())h.crossSigningKeys.set(u);for(const u of o.values())h.crossSigningKeys.set(u);for(const u of c.values())h.crossSigningKeys.set(u);let a=0;await Promise.all(Array.from(l.keys()).map(async u=>{let p=l.get(u);a+=p.length,p=await this._storeQueriedDevicesForUserId(u,p,h),l.set(u,p)})),s.set("devices",a)}catch(a){throw h.abort(),a}return await h.complete(),{deviceKeys:l,masterKeys:r,selfSigningKeys:o,userSigningKeys:c}}async _storeQueriedDevicesForUserId(e,t,s){const i=await s.deviceKeys.getAllDeviceIds(e);for(const l of i)t.every(h=>h.device_id!==l)&&s.deviceKeys.remove(e,l);const r=[],o=[];await Promise.all(t.map(async l=>{if(i.includes(l.device_id)){const h=await s.deviceKeys.get(l.user_id,l.device_id);if(h&&ks(h)!==ks(l)){r.push(h);return}}r.push(l),o.push(l)}));for(const l of o)s.deviceKeys.set(l);let c=await s.userIdentities.get(e);return c||(c=Pa(e)),c.keysTrackingStatus=1,s.userIdentities.set(c),r}_filterVerifiedCrossSigningKeys(e,t,s){const i=new Map;if(!e)return i;for(const[r,o]of Object.entries(e))s.wrap({l:r},c=>{this._validateCrossSigningKey(r,o,t,c)&&i.set(_o(o),o)});return i}_validateCrossSigningKey(e,t,s,i){return _o(t)!==e?(i.log({l:"user_id mismatch",userId:t.user_id}),!1):vd(t)!==s?(i.log({l:"usage mismatch",usage:t.usage}),!1):Qs(t)?!0:(i.log({l:"no ed25519 key",keys:t.keys}),!1)}_filterVerifiedDeviceKeys(e,t){const s=new Set,i=new Map;if(!e)return i;for(const[r,o]of Object.entries(e))t.wrap(r,c=>{const h=Object.entries(o).filter(([a,u])=>c.wrap(a,p=>{if(this._validateDeviceKey(r,a,u,p)){const g=_t(u);return s.has(g)?(t.log({l:"ignore device with duplicate curve25519 key",keys:u},t.level.Warn),!1):(s.add(g),!0)}else return!1})).map(([,a])=>a);i.set(r,h)});return i}_validateDeviceKey(e,t,s,i){const r=s.device_id,o=s.user_id;if(o!==e)return i.log("user_id mismatch"),!1;if(r!==t)return i.log("device_id mismatch"),!1;const c=ks(s),l=_t(s);if(typeof c!="string"||typeof l!="string")return i.log("ed25519 and/or curve25519 key invalid").set({deviceKey:s}),!1;const h=vn(this._olmUtil,o,r,c,s,i)===ne.Valid;return h||i.log({l:"ignore device with invalid signature",keys:s},i.level.Warn),h}async devicesForTrackedRoom(e,t,s){const i=await this._storage.readTxn([this._storage.storeNames.roomMembers,this._storage.storeNames.userIdentities]),r=await i.roomMembers.getAllUserIds(e);return await this._devicesForUserIdsInTrackedRoom(e,r,i,t,s)}async devicesForRoomMembers(e,t,s,i){const r=await this._storage.readTxn([this._storage.storeNames.userIdentities]);return await this._devicesForUserIdsInTrackedRoom(e,t,r,s,i)}async devicesForUsers(e,t,s){const i=await this._storage.readTxn([this._storage.storeNames.userIdentities]),r=[],o=[];return await Promise.all(e.map(async c=>{const l=await i.userIdentities.get(c);l&&l.keysTrackingStatus===1?r.push(l):(!l||l.keysTrackingStatus===0)&&o.push(c)})),this._devicesForUserIdentities(r,o,t,s)}async deviceForId(e,t,s,i){var h;const o=await(await this._storage.readTxn([this._storage.storeNames.userIdentities])).userIdentities.get(e);if((o==null?void 0:o.keysTrackingStatus)!==1){const{deviceKeys:a}=await this._queryKeys([e],s,i);return a.get(e).find(g=>g.device_id===t)}let l=await(await this._storage.readTxn([this._storage.storeNames.deviceKeys])).deviceKeys.get(e,t);if(l)i.set("existingDevice",!0);else{const a=await s.queryKeys({timeout:1e4,device_keys:{[e]:[t]},token:this._getSyncToken()},{log:i}).response(),p=(h=i.wrap("verify",v=>this._filterVerifiedDeviceKeys(a.device_keys,v)).get(e))==null?void 0:h.find(v=>v.device_id===t);if(!p)return;const g=await this._storage.readWriteTxn([this._storage.storeNames.deviceKeys]),f=await g.deviceKeys.get(e,t);if(f)l=f,i.set("existingDeviceAfterFetch",!0);else{try{g.deviceKeys.set(p),l=p,i.set("newDevice",!0)}catch(v){throw g.abort(),v}await g.complete()}}return l}async deviceForCurveKey(e,t,s,i){const r=await this._storage.readTxn([this._storage.storeNames.deviceKeys,this._storage.storeNames.userIdentities]),o=await r.userIdentities.get(e);if((o==null?void 0:o.keysTrackingStatus)!==1){const{deviceKeys:l}=await this._queryKeys([e],s,i);return l.get(e).find(u=>_t(u)===t)}return await r.deviceKeys.getByCurve25519Key(t)}async _devicesForUserIdsInTrackedRoom(e,t,s,i,r){const c=(await Promise.all(t.map(u=>s.userIdentities.get(u)))).filter(u=>u&&u.roomIds.includes(e)),l=c.filter(u=>u.keysTrackingStatus===1),h=c.filter(u=>u.keysTrackingStatus===0).map(u=>u.userId);let a=await this._devicesForUserIdentities(l,h,i,r);return a=a.filter(u=>!(u.user_id===this._ownUserId&&u.device_id===this._ownDeviceId)),a}async _devicesForUserIdentities(e,t,s,i){i.set("uptodate",e.length),i.set("outdated",t.length);let r;if(t.length){const{deviceKeys:h}=await this._queryKeys(t,s,i);r=h}const o=await this._storage.readTxn([this._storage.storeNames.deviceKeys]);let l=(await Promise.all(e.map(h=>o.deviceKeys.getAllForUserId(h.userId)))).reduce((h,a)=>h.concat(a),[]);if(r&&r.size)for(const h of r.values())l=l.concat(h);return l}async getDeviceByCurve25519Key(e,t){return await t.deviceKeys.getByCurve25519Key(e)}get ownDeviceId(){return this._ownDeviceId}}const Fa=[Cd,Ed,Rd,Td,Ad,xd,Vd,Nd,Dd,Ud,Od,Pd,Fd,Ld,Kd,Bd,$d,jd,qd];function Md(n){return{databaseName:n.name,get idbFactory(){throw new Error("unused")},get IDBKeyRange(){throw new Error("unused")},addWriteError(){}}}function Cd(n){n.createObjectStore("session",{keyPath:"key"}),n.createObjectStore("roomSummary",{keyPath:"roomId"}),n.createObjectStore("timelineFragments",{keyPath:"key"}),n.createObjectStore("timelineEvents",{keyPath:"key"}).createIndex("byEventId","eventIdKey",{unique:!0}),n.createObjectStore("roomState",{keyPath:"key"}),n.createObjectStore("pendingEvents",{keyPath:"key"})}async function Ed(n,e){const t=new Ta(n.createObjectStore("roomMembers",{keyPath:"key"})),s=e.objectStore("roomState");await _e(s.openCursor(),i=>{if(i.event.type===Ke){s.delete(i.key);const r=Q.fromMemberEvent(i.roomId,i.event);r&&t.set(r.serialize())}return Lt})}async function Rd(n,e,t){const s=e.objectStore("session");try{const r=await Me(s.get(1));if(r){s.delete(1);const{syncToken:o,syncFilterId:c,serverVersions:l}=r.value,h=new Mn(s,t);h.set("sync",{token:o,filterId:c}),h.set("serverVersions",l)}}catch(i){e.abort(),console.error("could not migrate session",i.stack)}}function Td(n){n.createObjectStore("userIdentities",{keyPath:"userId"}),n.createObjectStore("deviceIdentities",{keyPath:"key"}).createIndex("byCurve25519Key","curve25519Key",{unique:!0}),n.createObjectStore("olmSessions",{keyPath:"key"}),n.createObjectStore("inboundGroupSessions",{keyPath:"key"}),n.createObjectStore("outboundGroupSessions",{keyPath:"roomId"}),n.createObjectStore("groupSessionDecryptions",{keyPath:"key"}),n.createObjectStore("operations",{keyPath:"id"}).createIndex("byTypeAndScope","typeScopeKey",{unique:!1})}async function Ad(n,e){var r;const t=e.objectStore("roomSummary"),s=e.objectStore("roomState"),i=[];await _e(t.openCursor(),o=>(i.push(o),Lt));for(const o of i){const c=await Me(s.get(`${o.roomId}|m.room.encryption|`));c&&(o.encryption=(r=c==null?void 0:c.event)==null?void 0:r.content,delete o.isEncrypted,t.put(o))}}function xd(n){n.createObjectStore("accountData",{keyPath:"type"})}function Vd(n){n.createObjectStore("invites",{keyPath:"roomId"})}function Nd(n){n.createObjectStore("archivedRoomSummary",{keyPath:"summary.roomId"})}async function Dd(n,e){try{const t=e.objectStore("operations");t.deleteIndex("byTypeAndScope"),await _e(t.openCursor(),(s,i,r)=>{const{typeScopeKey:o}=s;delete s.typeScopeKey;const[c,l]=o.split("|");return s.scopeTypeKey=Ci(l,c),r.update(s),Lt}),t.createIndex("byScopeAndType","scopeTypeKey",{unique:!1})}catch(t){e.abort(),console.error("could not migrate operations",t.stack)}}function Ud(n){n.createObjectStore("timelineRelations",{keyPath:"key"})}function Od(){}async function Pd(n,e){const t=e.objectStore("session"),s=await Me(t.get("ssssKey"));s&&t.put({key:`${Oe}ssssKey`,value:s.value})}async function Fd(n,e,t,s){const i=e.objectStore("session"),r=new Mn(new Ma(i,Md(n)),t);r.writeE2EEIdentityToLocalStorage();const o=await r.tryRestoreE2EEIdentityFromLocalStorage(s);s.set("restored",o)}async function Ld(n,e){for(const t of n.objectStoreNames){const s=e.objectStore(t);switch(t){case"inboundGroupSessions":case"outboundGroupSessions":case"olmSessions":case"operations":continue;case"session":{await _e(s.openCursor(),(i,r,o)=>(r.startsWith(Oe)||o.delete(),Lt));break}default:{s.clear();break}}}}async function Kd(n,e,t,s){e.objectStore("inboundGroupSessions").createIndex("byBackup","backup",{unique:!1})}async function Bd(n,e,t,s){const i=e.objectStore("inboundGroupSessions");let r=0,o=0;await _e(i.openCursor(),(c,l,h)=>(c.session?(c.backup=Vr.NotBackedUp,c.source=Hi.DeviceMessage,h.update(c),r+=1):o+=1,Lt)),s.set("countWithoutSession",o),s.set("countWithSession",r)}function $d(n){n.createObjectStore("calls",{keyPath:"key"})}async function jd(n,e,t,s){n.createObjectStore("crossSigningKeys",{keyPath:"key"}),n.deleteObjectStore("deviceIdentities"),n.createObjectStore("deviceKeys",{keyPath:"key"}).createIndex("byCurve25519Key","curve25519Key",{unique:!0});const r=e.objectStore("userIdentities");let o=0;await _e(r.openCursor(),(c,l,h)=>(delete c.deviceTrackingStatus,delete c.crossSigningKeys,c.keysTrackingStatus=Oa.Outdated,h.update(c),o+=1,Lt)),s.set("marked_outdated",o)}function qd(n){n.createObjectStore("sharedSecrets",{keyPath:"key"})}async function Hd(n){const e="hydrogen_webkit_test_inactive_txn_bug";try{const t=await In(e,r=>{r.createObjectStore("test",{keyPath:"key"})},1,n),s=t.transaction(["test"],"readonly");await Me(s.objectStore("test").get("somekey")),await new Promise(r=>setTimeout(r,0));const i=t.transaction(["test"],"readwrite");await Promise.resolve(),i.objectStore("test").add({key:"somekey",value:"foo"}),await Pi(i),t.close()}catch(t){if(t.name==="TransactionInactiveError")return!0}return!1}const La=n=>`hydrogen_session_${n}`,$r=function(n,e,t,s){const i=(r,o,c,l)=>Gd(r,o,c,l,t,s);return In(La(n),i,Fa.length,e)};async function Wd(){var e,t;const n=this;if((t=(e=n==null?void 0:n.navigator)==null?void 0:e.storage)!=null&&t.persist)return await n.navigator.storage.persist();if(n!=null&&n.document.requestStorageAccess)try{return await n.document.requestStorageAccess(),!0}catch(s){return console.warn("requestStorageAccess threw an error:",s),!1}else return!1}class zd{constructor(e,t=window.indexedDB,s=window.IDBKeyRange,i=window.localStorage){this._serviceWorkerHandler=e,this._idbFactory=t,this._IDBKeyRange=s,this._localStorage=i}async create(e,t){var r;await((r=this._serviceWorkerHandler)==null?void 0:r.preventConcurrentSessionAccess(e)),Wd().then(o=>{o||t.log("no persisted storage, database can be evicted by browser",t.level.Warn)});const s=await Hd(this._idbFactory),i=await $r(e,this._idbFactory,this._localStorage,t);return new Jh(i,this._idbFactory,this._IDBKeyRange,s,this._localStorage,t.logger)}async delete(e){const t=La(e);try{kh(this._localStorage,t)}catch{}try{const s=this._idbFactory.deleteDatabase(t);await Me(s)}catch{}}async export(e,t){const s=await $r(e,this._idbFactory,this._localStorage,t);return await Qh(s)}async import(e,t,s){const i=await $r(e,this._idbFactory,this._localStorage,s);return await Xh(i,t)}}async function Gd(n,e,t,s,i,r){const o=t||0;return r.wrap({l:"storage migration",oldVersion:t,version:s},async c=>{for(let l=o;lh(n,e,i,a))}})}class Ka{constructor({roomId:e,ownUserId:t,fragmentIdComparer:s}){this._roomId=e,this._ownUserId=t,this._fragmentIdComparer=s}async writeRelation(e,t,s){const{relatedEventId:i}=e;if(i){const r=Xt(e.event);r&&r.rel_type&&t.timelineRelations.add(this._roomId,r.event_id,r.rel_type,e.id);const o=await t.timelineEvents.getByEventId(this._roomId,i);if(o){const c=await this._applyRelation(e,o,t,s);if(c)return c.map(l=>(t.timelineEvents.update(l),new Ye(l,this._fragmentIdComparer)))}}return null}async writeGapRelation(e,t,s,i){const r=new Ye(e,this._fragmentIdComparer),o=await this.writeRelation(r,s,i);if(t.isBackward&&!Xr(e.event)){const c=await s.timelineRelations.getAllForTarget(this._roomId,r.id);if(c.length)for(const l of c){const h=await s.timelineEvents.getByEventId(this._roomId,l.sourceEventId);if(h){const a=new Ye(h,this._fragmentIdComparer);await this._applyRelation(a,e,s,i)}}}return o}async _applyRelation(e,t,s,i){if(e.eventType===gt)return i.wrap("redact",async r=>{const o=t.event,c=Xt(o);if(this._applyRedaction(e.event,t,s,r)){const h=[t];if(c){const a=await this._reaggregateRelation(o,c,s,r);a&&h.push(a)}return h}return null});{const r=Xt(e.event);if(r&&!Xr(t.event)&&r.rel_type===ss&&i.wrap("react",l=>this._aggregateAnnotation(e.event,t,l)))return[t]}return null}_applyRedaction(e,t,s,i){const r=t.event;i.set("redactionId",e.event_id),i.set("id",r.event_id);const o=Xt(r);return o&&o.rel_type&&s.timelineRelations.remove(this._roomId,o.event_id,o.rel_type,r.event_id),s.timelineRelations.removeAllForTarget(this._roomId,r.event_id),uh(e,r),delete t.annotations,!0}_aggregateAnnotation(e,t){const s=Xt(e);if(!s)return!1;let{annotations:i}=t;i||(t.annotations=i={});let r=i[s.key];r||(i[s.key]=r={count:0,me:!1,firstTimestamp:Number.MAX_SAFE_INTEGER});const o=e.sender===this._ownUserId;return r.me=r.me||o,r.count+=1,r.firstTimestamp=Math.min(r.firstTimestamp,e.origin_server_ts),!0}async _reaggregateRelation(e,t,s,i){return t.rel_type===ss?i.wrap("reaggregate annotations",r=>this._reaggregateAnnotation(t.event_id,t.key,s,r)):null}async _reaggregateAnnotation(e,t,s,i){const r=await s.timelineEvents.getByEventId(this._roomId,e);if(!r||!r.annotations)return null;i.set("id",e);const o=await s.timelineRelations.getForTargetAndType(this._roomId,e,ss);return i.set("relations",o.length),delete r.annotations[t],Yd(r.annotations)&&delete r.annotations,await Promise.all(o.map(async c=>{const l=await s.timelineEvents.getByEventId(this._roomId,c.sourceEventId);l||i.log({l:"missing annotation",id:c.sourceEventId}),Xt(l.event).key===t&&this._aggregateAnnotation(l.event,r,i)})),r}}function Yd(n){for(const e in n)if(n.hasOwnProperty(e))return!1;return!0}class Kt{constructor(e){this.isForward=e}get isBackward(){return!this.isForward}asApiString(){return this.isForward?"f":"b"}reverse(){return this.isForward?Kt.Backward:Kt.Forward}static get Forward(){return Jd}static get Backward(){return Qd}}const Jd=new Kt(!0),Qd=new Kt(!1);class it extends fa{constructor(e,t,s){super(s),this._fragment=e,this._isFragmentStart=t}static start(e,t){return new it(e,!0,t)}static end(e,t){return new it(e,!1,t)}get started(){return this._isFragmentStart}get hasEnded(){return!this.started}get fragment(){return this._fragment}get fragmentId(){return this._fragment.id}get entryIndex(){return this.started?ce.minStorageKey:ce.maxStorageKey}get isGap(){return!!this.token&&!this.edgeReached}get token(){return this.started?this.fragment.previousToken:this.fragment.nextToken}set token(e){this.started?this.fragment.previousToken=e:this.fragment.nextToken=e}get edgeReached(){return this.started?this.fragment.startReached:this.fragment.endReached}set edgeReached(e){this.started?this.fragment.startReached=e:this.fragment.endReached=e}get linkedFragmentId(){return this.started?this.fragment.previousId:this.fragment.nextId}set linkedFragmentId(e){this.started?this.fragment.previousId=e:this.fragment.nextId=e}get hasLinkedFragment(){return Sn(this.linkedFragmentId)}get direction(){return this.started?Kt.Backward:Kt.Forward}withUpdatedFragment(e){return new it(e,this._isFragmentStart,this._fragmentIdComparer)}createNeighbourEntry(e){return new it(e,!this._isFragmentStart,this._fragmentIdComparer)}addLocalRelation(){}removeLocalRelation(){}}function Xd(n){const e=new Set;return n.filter(t=>e.has(t.event_id)?!1:(e.add(t.event_id),!0))}class Zd{constructor({roomId:e,fragmentIdComparer:t,memberWriter:s,relationWriter:i}){this._roomId=e,this._memberWriter=s,this._relationWriter=i,this._fragmentIdComparer=t,this._lastLiveKey=null}async load(e,t){const s=await e.timelineFragments.liveFragment(this._roomId);if(s){const[i]=await e.timelineEvents.lastEvents(this._roomId,s.id,1),r=i?i.eventIndex:pe.defaultLiveKey.eventIndex;this._lastLiveKey=new pe(s.id,r)}this._lastLiveKey&&t.set("live key",this._lastLiveKey.toString())}async _createLiveFragment(e,t){const s=await e.timelineFragments.liveFragment(this._roomId);if(s)return s;{t||(t=null);const i={roomId:this._roomId,id:pe.defaultLiveKey.fragmentId,previousId:null,nextId:null,previousToken:t,nextToken:null};return e.timelineFragments.add(i),this._fragmentIdComparer.add(i),i}}async _replaceLiveFragment(e,t,s,i){const r=await i.timelineFragments.get(this._roomId,e);if(!r)throw new Error(`old live fragment doesn't exist: ${e}`);r.nextId=t,i.timelineFragments.update(r);const o={roomId:this._roomId,id:t,previousId:e,nextId:null,previousToken:s,nextToken:null};return i.timelineFragments.add(o),this._fragmentIdComparer.append(t,e),{oldFragment:r,newFragment:o}}async _ensureLiveFragment(e,t,s,i,r){if(e){if(s.limited){const o=e.fragmentId;e=e.nextFragmentKey();const{oldFragment:c,newFragment:l}=await this._replaceLiveFragment(o,e.fragmentId,s.prev_batch,i);t.push(it.end(c,this._fragmentIdComparer)),t.push(it.start(l,this._fragmentIdComparer)),r.log({l:"live fragment",limited:!0,id:e.fragmentId})}}else{let o=await this._createLiveFragment(i,s.prev_batch);e=new pe(o.id,pe.defaultLiveKey.eventIndex),t.push(it.start(o,this._fragmentIdComparer)),r.log({l:"live fragment",first:!0,id:e.fragmentId})}return e}async _writeStateEvents(e,t,s){let i=0;for(const r of e)r.type!==Ke&&(t.roomState.set(this._roomId,r),i+=1);s.set("stateEvents",i)}async _writeTimeline(e,t,s,i,r,o){const c=[],l=[];if(e!=null&&e.length){i=await this._ensureLiveFragment(i,c,t,r,o),o.set("timelineEvents",e.length);let h=0;for(const a of e){i=i.nextKey();const u=Sa(i,this._roomId,a);let p=await s.lookupMemberAtEvent(a.sender,a,r);if(p&&(u.displayName=p.displayName,u.avatarUrl=p.avatarUrl),!await r.timelineEvents.tryInsert(u,o))continue;const f=new Ye(u,this._fragmentIdComparer);c.push(f);const v=await this._relationWriter.writeRelation(f,r,o);v&&l.push(...v),typeof a.state_key=="string"&&a.type!==Ke&&(h+=1,r.roomState.set(this._roomId,a))}o.set("timelineStateEventCount",h)}return{currentKey:i,entries:c,updatedEntries:l}}async _handleRejoinOverlap(e,t,s){if(this._lastLiveKey){const{fragmentId:i}=this._lastLiveKey,[r]=await t.timelineEvents.lastEvents(this._roomId,i,1);if(r){const o=r.event.event_id,{events:c}=e,l=c.findIndex(h=>h.event_id===o);if(l!==-1)return s.set("overlap_event_id",o),Object.assign({},e,{limited:!1,events:c.slice(l+1)})}}return e.limited?e:(s.set("force_limited_without_overlap",!0),Object.assign({},e,{limited:!0}))}async writeSync(e,t,s,i,r){let{timeline:o}=e;r.set("isRejoin",t),t&&(o=await this._handleRejoinOverlap(o,i,r));let c;Array.isArray(o==null?void 0:o.events)&&(c=Xd(o.events));const{state:l}=e;let h;Array.isArray(l==null?void 0:l.events)&&(h=l.events);const a=this._memberWriter.prepareMemberSync(h,c,s);h&&await this._writeStateEvents(h,i,r);const{currentKey:u,entries:p,updatedEntries:g}=await this._writeTimeline(c,o,a,this._lastLiveKey,i,r),f=await a.write(i);return{entries:p,updatedEntries:g,newLiveKey:u,memberChanges:f,memberSync:a}}afterSync(e){this._lastLiveKey=e}get lastMessageKey(){return this._lastLiveKey}}class Ba{constructor(e){this.limit=e,this._entries=[]}get size(){return this._entries.length}_get(e){return this._getByIndexAndMoveUp(this._entries.findIndex(e))}_getByIndexAndMoveUp(e){if(e!==-1){const t=this._entries[e];return e>0&&(this._entries.splice(e,1),this._entries.unshift(t)),t}}_set(e,t){let s=t?this._entries.findIndex(t):-1;this._entries.unshift(e),s===-1?this._entries.length>this.limit&&(s=this._entries.length-1):s+=1,s!==-1&&(this.onEvictEntry(this._entries[s]),this._entries.splice(s,1))}onEvictEntry(e){}}class $a extends Ba{constructor(e,t){super(e),this._keyFn=t}get(e){return this._get(t=>this._keyFn(t)===e)}set(e){const t=this._keyFn(e);this._set(e,s=>this._keyFn(s)===t)}}class eu{constructor(e){this._roomId=e,this._cache=new $a(5,t=>t.userId)}prepareMemberSync(e,t,s){return new tu(this,e,t,s)}async _writeMember(e,t){let s=this._cache.get(e.userId);if(!s){const i=await t.roomMembers.get(this._roomId,e.userId);i&&(s=new Q(i))}if(!s||!s.equals(e))return t.roomMembers.set(e.serialize()),this._cache.set(e),new ka(e,s==null?void 0:s.membership)}async lookupMember(e,t){let s=this._cache.get(e);if(!s){const i=await t.roomMembers.get(this._roomId,e);i&&(s=new Q(i),this._cache.set(s))}return s}}class tu{constructor(e,t,s,i){this._memberWriter=e,this._timelineEvents=s,this._hasFetchedMembers=i,this._newStateMembers=null,t&&(this._newStateMembers=this._stateEventsToMembers(t))}get _roomId(){return this._memberWriter._roomId}_stateEventsToMembers(e){let t;for(const s of e)if(s.type===Ke){const i=Q.fromMemberEvent(this._roomId,s);i&&(t||(t=new Map),t.set(i.userId,i))}return t}_timelineEventsToMembers(e){let t;for(let s=e.length-1;s>=0;s--){const i=e[s],r=i.state_key;if(i.type===Ke&&!(t!=null&&t.has(r))){const o=Q.fromMemberEvent(this._roomId,i);o&&(t||(t=new Map),t.set(o.userId,o))}}return t}async lookupMemberAtEvent(e,t,s){var r;let i;return this._timelineEvents&&(i=this._findPrecedingMemberEventInTimeline(e,t),i)||(i=(r=this._newStateMembers)==null?void 0:r.get(e),i)?i:await this._memberWriter.lookupMember(e,s)}async write(e){const t=new Map;let s;if(this._timelineEvents&&(s=this._timelineEventsToMembers(this._timelineEvents)),this._newStateMembers){for(const i of this._newStateMembers.values())if(!(s!=null&&s.has(i.userId))){const r=await this._memberWriter._writeMember(i,e);r&&(!this._hasFetchedMembers&&!r.previousMembership&&(r.previousMembership=i.membership),t.set(r.userId,r))}}if(s)for(const i of s.values()){const r=await this._memberWriter._writeMember(i,e);r&&t.set(r.userId,r)}return t}_findPrecedingMemberEventInTimeline(e,t){let s=-1;for(let i=this._timelineEvents.length-1;i>=0;i--)if(this._timelineEvents[i].event_id===t.event_id){s=i;break}for(let i=s-1;i>=0;i--){const r=this._timelineEvents[i];if(r.type===Ke&&r.state_key===e){const o=Q.fromMemberEvent(this._roomId,r);if(o)return o}}}}class su{constructor({roomId:e,storage:t,fragmentIdComparer:s,relationWriter:i}){this._roomId=e,this._storage=t,this._fragmentIdComparer=s,this._relationWriter=i}async _findOverlappingEvents(e,t,s,i){const r=t.map(h=>h.event_id),o=await s.timelineEvents.getEventKeysForIds(this._roomId,r);i.set("existingEvents",o.size);const c=t.filter(h=>!o.has(h.event_id));i.set("nonOverlappingEvents",c.length);let l;if(e.hasLinkedFragment){i.set("linkedFragmentId",e.linkedFragmentId);for(const h of o.values())if(h.fragmentId===e.linkedFragmentId){i.set("foundLinkedFragment",!0);const a=await s.timelineFragments.get(this._roomId,e.linkedFragmentId);l=e.createNeighbourEntry(a);break}}return{nonOverlappingEvents:c,neighbourFragmentEntry:l}}async _findFragmentEdgeEventKey(e,t){const{fragmentId:s,direction:i}=e,r=await this._findFragmentEdgeEvent(s,i,t);return r?new pe(r.fragmentId,r.eventIndex):pe.defaultFragmentKey(e.fragmentId)}async _findFragmentEdgeEvent(e,t,s){if(t.isBackward){const[i]=await s.timelineEvents.firstEvents(this._roomId,e,1);return i}else{const[i]=await s.timelineEvents.lastEvents(this._roomId,e,1);return i}}async _storeEvents(e,t,s,i,r,o){const c=[],l=[];let h=t;for(let a=0;a=0&&h=0&&hnew Ye(u,i));if(o=lh(o,a,t),o.length{const c=await this._storage.readTxn(this.readTxnStores);return await this._readFrom(e,t,s,r,c,o)},i)}readFromEnd(e,t=null,s){return new po(async(i,r)=>{const o=t||await this._storage.readTxn(this.readTxnStores),c=await o.timelineFragments.liveFragment(this._roomId);let l;if(!c)l=[];else{this._fragmentIdComparer.add(c);const h=it.end(c,this._fragmentIdComparer),a=h.asEventKey();l=await this._readFrom(a,Kt.Backward,e,i,o,r),l.unshift(h)}return l},s)}async readById(e,t){let s=[this._storage.storeNames.timelineEvents];this._decryptEntries&&s.push(this._storage.storeNames.inboundGroupSessions);const i=await this._storage.readTxn(s),r=await i.timelineEvents.getByEventId(this._roomId,e);if(r){const o=new Ye(r,this._fragmentIdComparer);return this._decryptEntries&&await this._decryptEntries([o],i,t).complete(),o}}async _readFrom(e,t,s,i,r,o){const c=await iu(this._roomId,e,t,s,this._fragmentIdComparer,r);if(this._decryptEntries){i.decryptRequest=this._decryptEntries(c,r,o);try{await i.decryptRequest.complete()}finally{i.decryptRequest=null}}return c}}class ru extends Ye{get fragmentId(){throw new Error("Cannot access fragmentId for non-persisted EventEntry")}get entryIndex(){throw new Error("Cannot access entryIndex for non-persisted EventEntry")}get isNonPersisted(){return!0}get isRedacting(){return!1}get isRedacted(){return super.isRedacting}}class qa{constructor(e){this._retentionCount=1,this._freeCallback=e}retain(){this._retentionCount+=1}release(){this._retentionCount-=1,this._retentionCount===0&&this._freeCallback()}}class nu{constructor(e){this._userId=e}get id(){return this._userId}}class Mr extends qa{constructor({roomId:e,storage:t,closeCallback:s,fragmentIdComparer:i,pendingEvents:r,clock:o,powerLevelsObservable:c,hsApi:l}){super(()=>{this.dispose()}),this._roomId=e,this._storage=t,this._closeCallback=s,this._fragmentIdComparer=i,this._disposables=new li,this._pendingEvents=r,this._clock=o,this._remoteEntries=new fn((h,a)=>h.compare(a)),this._ownMember=null,this._timelineReader=new ja({roomId:this._roomId,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer}),this._readerRequest=null,this._allEntries=null,this._contextEntriesNotInTimeline=new Map,this._decryptEntries=null,this._hsApi=l,this.initializePowerLevels(c)}initializePowerLevels(e){e&&(this._powerLevels=e.get(),this._disposables.track(e.subscribe(t=>this._powerLevels=t)))}async load(e,t,s){const i=await this._storage.readTxn(this._timelineReader.readTxnStores.concat(this._storage.storeNames.roomMembers,this._storage.storeNames.roomState)),r=await i.roomMembers.get(this._roomId,e.id);r?this._ownMember=new Q(r):this._ownMember=Q.fromUserId(this._roomId,e.id,t);const o=this._disposables.track(this._timelineReader.readFromEnd(20,i,s));try{const c=await o.complete();this._loadContextEntriesWhereNeeded(c),this._setupEntries(c)}finally{this._disposables.disposeTracked(o)}}_setupEntries(e){this._remoteEntries.setManySorted(e),this._pendingEvents?this._localEntries=new ul(this._pendingEvents,t=>this._mapPendingEventToEntry(t),(t,s)=>{t.notifyUpdate(s)},t=>this._applyAndEmitLocalRelationChange(t,s=>s.removeLocalRelation(t))):this._localEntries=new gn,this._allEntries=new ca(this._remoteEntries,this._localEntries)}async _mapPendingEventToEntry(e){let t;e.eventType===gt&&(t=await this._getOrLoadEntry(e.relatedTxnId,e.relatedEventId));const s=new ah({pendingEvent:e,member:this._ownMember,clock:this._clock,redactingEntry:t});return this._loadContextEntriesWhereNeeded([s]),this._applyAndEmitLocalRelationChange(s,i=>i.addLocalRelation(s)),s}_applyAndEmitLocalRelationChange(e,t){var i,r;const s=o=>{const c=t(o);return c||!1};if(this._findAndUpdateEntryById(e.pendingEvent.relatedTxnId,e.relatedEventId,s),e.redactingEntry){const o=(i=e.redactingEntry.pendingEvent)==null?void 0:i.relatedTxnId;this._findAndUpdateEntryById(o,e.redactingEntry.relatedEventId,s),(r=e.redactingEntry.contextForEntries)==null||r.forEach(c=>this._emitUpdateForEntry(c,"contextEntry"))}}_findAndUpdateEntryById(e,t,s){let i=!1;e&&(i=this._localEntries.findAndUpdate(r=>r.id===e,s)),!i&&t&&this._remoteEntries.findAndUpdate(r=>r.id===t,s)}async getOwnAnnotationEntry(e,t){const s=await this._storage.readWriteTxn([this._storage.storeNames.timelineEvents,this._storage.storeNames.timelineRelations]),i=await s.timelineRelations.getForTargetAndType(this._roomId,e,ss);for(const r of i){const o=await s.timelineEvents.getByEventId(this._roomId,r.sourceEventId);if(o&&o.event.sender===this._ownMember.userId&&Xt(o.event).key===t){const c=new Ye(o,this._fragmentIdComparer);return this._addLocalRelationsToNewRemoteEntries([c]),c}}return null}updateOwnMember(e){this._ownMember=e}_addLocalRelationsToNewRemoteEntries(e){var t;if(!!((t=this._localEntries)!=null&&t.hasSubscriptions))for(const s of this._localEntries){if(s.relatedEventId){const i=e.find(r=>r.id===s.relatedEventId);i==null||i.addLocalRelation(s)}if(s.redactingEntry){const i=s.redactingEntry.relatedEventId,r=e.find(o=>o.id===i);r==null||r.addLocalRelation(s)}}}static _entryUpdater(e,t){var s;return(s=e.contextForEntries)==null||s.forEach(i=>i.setContextEntry(t)),t.updateFrom(e),t}replaceEntries(e){var t;this._addLocalRelationsToNewRemoteEntries(e);for(const s of e)try{this._remoteEntries.getAndUpdate(s,Mr._entryUpdater);const i=this._contextEntriesNotInTimeline.get(s.id);i&&(Mr._entryUpdater(i,s),this._contextEntriesNotInTimeline.set(s.id,s)),(t=s.contextForEntries)==null||t.forEach(r=>this._emitUpdateForEntry(r,"contextEntry"))}catch(i){if(i.name==="CompareError")continue;throw i}}addEntries(e){this._addLocalRelationsToNewRemoteEntries(e),this._updateEntriesFetchedFromHomeserver(e),this._moveEntryToRemoteEntries(e),this._loadContextEntriesWhereNeeded(e),this._remoteEntries.setManySorted(e)}_updateEntriesFetchedFromHomeserver(e){var t;for(const s of e){const i=this._contextEntriesNotInTimeline.get(s.relatedEventId);(i==null?void 0:i.isNonPersisted)&&(i==null?void 0:i.addLocalRelation(s))&&((t=i.contextForEntries)==null||t.forEach(r=>this._emitUpdateForEntry(r,"contextEntry")))}}_moveEntryToRemoteEntries(e){for(const t of e){const s=this._contextEntriesNotInTimeline.get(t.id);s&&(s.contextForEntries.forEach(i=>{i.setContextEntry(t),this._emitUpdateForEntry(i,"contextEntry")}),this._contextEntriesNotInTimeline.delete(t.id))}}_emitUpdateForEntry(e,t){const s=e.isPending?e.id:null,i=e.isPending?null:e.id;this._findAndUpdateEntryById(s,i,()=>t)}async _loadContextEntriesWhereNeeded(e){for(const t of e){if(!t.contextEventId)continue;const s=t.contextEventId;let i=e.find(r=>r.id===s);i||(i=this._findLoadedEventById(s)),i?(t.setContextEntry(i),this._emitUpdateForEntry(i,"context-added")):this._loadContextEntryNotInTimeline(t)}}async _loadContextEntryNotInTimeline(e){const t=e.contextEventId;let s=await this._getEventFromStorage(t);s||(s=await this._getEventFromHomeserver(t)),s&&(this._contextEntriesNotInTimeline.set(t,s),e.setContextEntry(s),this._emitUpdateForEntry(e,"contextEntry"))}_findLoadedEventById(e){var t;return(t=this.getByEventId(e))!=null?t:this._contextEntriesNotInTimeline.get(e)}async _getEventFromStorage(e){return await this._timelineReader.readById(e)}async _getEventFromHomeserver(e){const t=await this._hsApi.context(this._roomId,e,0).response(),s=t.event.sender,i=t.state.find(c=>c.type===Ke&&c.user_id===s),r={event:t.event,displayName:i.content.displayname,avatarUrl:i.content.avatar_url},o=new ru(r,this._fragmentIdComparer);return this._decryptEntries&&await this._decryptEntries([o]).complete(),o}async loadAtTop(e){if(this._disposables.isDisposed)return!0;const t=this._remoteEntries.array.find(i=>!!i.eventType);if(!t)return!0;const s=this._disposables.track(this._timelineReader.readFrom(t.asEventKey(),Kt.Backward,e));try{const i=await s.complete();return this.addEntries(i),i.lengthnew Q(i))}async function au({summary:n,syncToken:e,roomId:t,hsApi:s,storage:i,setChangedMembersMap:r},o){const c=new Map;r(c);const l=await s.members(t,{at:e},{log:o}).response(),h=await i.readWriteTxn([i.storeNames.roomSummary,i.storeNames.roomMembers]);let a,u;try{a=n.writeHasFetchedMembers(!0,h);const{roomMembers:p}=h,g=l.chunk;if(!Array.isArray(g))throw new Error("malformed");o.set("members",g.length),u=await Promise.all(g.map(async f=>{const v=f==null?void 0:f.state_key;if(!v)throw new Error("malformed");const M=c.get(v);if(M)return M;{const R=Q.fromMemberEvent(t,f);return R&&p.set(R.serialize()),R}}))}catch(p){throw h.abort(),p}finally{r(null)}return await h.complete(),n.applyChanges(a),u}async function cu(n,e){const{summary:t}=n;return t.data.hasFetchedMembers?ou(n):e.wrapOrRun(n.log,"fetchMembers",s=>au(n,s))}async function lu(n,e){const t=await hu(n),{summary:s}=n;return!s.data.hasFetchedMembers&&!t?e.wrapOrRun(n.log,"fetchMember",i=>du(n,i)):t}async function hu({roomId:n,userId:e,storage:t}){const i=await(await t.readTxn([t.storeNames.roomMembers])).roomMembers.get(n,e);return i?new Q(i):null}async function du({roomId:n,userId:e,hsApi:t,storage:s},i){let r;try{r=await t.state(n,"m.room.member",e,{log:i}).response()}catch(l){if(l.name==="HomeServerError"&&l.errcode==="M_NOT_FOUND")return null;throw l}const o=new Q({roomId:n,userId:e,membership:r.membership,avatarUrl:r.avatar_url,displayName:r.displayname}),c=await s.readWriteTxn([s.storeNames.roomMembers]);try{c.roomMembers.set(o.serialize())}catch(l){throw c.abort(),l}return await c.complete(),o}class uu extends qa{constructor({members:e,closeCallback:t}){super(t),this._members=new Dt;for(const s of e)this._members.add(s.userId,s)}afterSync(e){for(const[t,s]of e.entries())this._members.set(t,s.member)}get members(){return this._members}}function tn(n,e,t){const s=e.joinCount+e.inviteCount-1;if(n.length>=s)if(n.length>1){const i=n[n.length-1];return n.slice(0,n.length-1).map(o=>o.name).join(", ")+" and "+i.name}else{const i=n[0];return i?i.name:(t.log({l:"could get get other member name",length:n.length,otherMember:!!i,otherMemberMembership:i==null?void 0:i.membership}),"Unknown DM Name")}else return n.lengthi.name).join(", ")+` and ${s} others`:null}class Rn{constructor(e){this._roomId=e,this._members=new Map}async calculateChanges(e,t,s){const i=new Map,r=[];for(const o of this._members.keys())e.indexOf(o)===-1&&r.push(o);for(const[o,c]of t.entries())(this._members.has(o)||e.indexOf(o)!==-1)&&i.set(o,c.member);for(const o of e)if(!this._members.has(o)&&!i.has(o)){const c=await s.roomMembers.get(this._roomId,o);if(c){const l=new Q(c);i.set(l.userId,l)}}return{updatedHeroMembers:i.values(),removedUserIds:r}}applyChanges({updatedHeroMembers:e,removedUserIds:t},s,i){for(const o of t)this._members.delete(o);for(const o of e)t.includes(o.userId)||this._members.set(o.userId,o);const r=Array.from(this._members.values()).sort((o,c)=>o.name.localeCompare(c.name));this._roomName=tn(r,s,i)}get roomName(){return this._roomName}get roomAvatarUrl(){if(this._members.size===1)for(const e of this._members.values())return e.avatarUrl;return null}get roomAvatarColorId(){if(this._members.size===1)for(const e of this._members.keys())return e;return null}}class mu{constructor(e){this._map=new Map,this._notifyEmpty=e}observe(e,t=null){let s=this._map.get(e);return s||(s=new _u(this,t,e),this._map.set(e,s)),s}updateEvents(e){for(let t=0;t{this.hasSubscriptions||(this._eventMap._remove(this._id),this._eventMap=null)})}subscribe(e){if(!this._eventMap)throw new Error("ObservedEvent expired, subscribe right after calling room.observeEvent()");return super.subscribe(e)}onUnsubscribeLast(){this._eventMap._remove(this._id),this._eventMap=null,super.onUnsubscribeLast()}update(e){this._entry=e,this.emit(this._entry)}get(){return this._entry}}function pu(n){return n||Eh.item}const gu="m.room.power_levels",fu=50;class gr{constructor({powerLevelEvent:e,createEvent:t,ownUserId:s,membership:i}){this._plEvent=e,this._createEvent=t,this._ownUserId=s,this._membership=i}canRedactFromSender(e){return e===this._ownUserId&&this._membership==="join"?!0:this.canRedact}canSendType(e){return this._myLevel>=this._getEventTypeLevel(e)}get canRedact(){return this._myLevel>=this._getActionLevel("redact")}get _myLevel(){return this._membership!=="join"?Number.MIN_SAFE_INTEGER:this.getUserLevel(this._ownUserId)}getUserLevel(e){var t,s,i,r;if(this._plEvent){let o=(s=(t=this._plEvent.content)==null?void 0:t.users)==null?void 0:s[e];if(typeof o!="number"&&(o=(i=this._plEvent.content)==null?void 0:i.users_default),typeof o=="number")return o}else if(this._createEvent&&e===((r=this._createEvent.content)==null?void 0:r.creator))return 100;return 0}_getActionLevel(e){var s,i;const t=(i=(s=this._plEvent)==null?void 0:s.content)==null?void 0:i[e];return typeof t=="number"?t:fu}_getEventTypeLevel(e){var s,i,r,o,c;const t=(r=(i=(s=this._plEvent)==null?void 0:s.content)==null?void 0:i.events)==null?void 0:r[e];if(typeof t=="number")return t;{const l=(c=(o=this._plEvent)==null?void 0:o.content)==null?void 0:c.events_default;return typeof l=="number"?l:0}}}class yu extends Dt{constructor(e){super(),this.type=e}async load(e,t){const s=await t.roomState.getAllForType(e,this.type);for(let i=0;i{this._roomStateObservers.delete(e)})}async _eventIdsToEntries(e,t){const s=[];return await Promise.all(e.map(async i=>{const r=await t.timelineEvents.getByEventId(this._roomId,i);r&&s.push(new Ye(r,this._fragmentIdComparer))})),s}_getAdditionalTimelineRetryEntries(e,t){let s=this._roomEncryption.filterUndecryptedEventEntriesForKeys(this._timeline.remoteEntries,t);const i=e.reduce((r,o)=>(r.add(o.id),r),new Set);return s=s.filter(r=>!i.has(r.id)),s}async notifyRoomKey(e,t,s){var o;if(!this._roomEncryption)return;const i=await this._storage.readTxn([this._storage.storeNames.timelineEvents,this._storage.storeNames.inboundGroupSessions]);let r=await this._eventIdsToEntries(t,i);if(this._timeline){const c=this._getAdditionalTimelineRetryEntries(r,[e]);r=r.concat(c)}if(r.length){await this._decryptEntries(ts.Retry,r,i,s).complete(),(o=this._timeline)==null||o.replaceEntries(r);const l=this._summary.data.applyTimelineEntries(r,!1,!1);await this._summary.writeAndApplyData(l,this._storage)&&this._emitUpdate()}}_setEncryption(e){return e&&!this._roomEncryption?(this._roomEncryption=e,this._timeline&&this._timeline.enableEncryption(this._decryptEntries.bind(this,ts.Timeline)),!0):!1}_decryptEntries(e,t,s,i=null){return new bu(async(o,c)=>{if(s||(s=await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions])),o.cancelled)return;const l=t.filter(f=>f.eventType===vu).map(f=>f.event);if(o.preparation=await this._roomEncryption.prepareDecryptAll(l,null,e,s),o.cancelled)return;const h=await o.preparation.decrypt();if(o.preparation=null,o.cancelled)return;const a=[this._storage.storeNames.groupSessionDecryptions],u=this._isTimelineOpen;u&&a.push(this._storage.storeNames.deviceKeys);const p=await this._storage.readWriteTxn(a);let g;try{g=await h.write(p,c),u&&await g.verifyKnownSenders(p)}catch(f){throw p.abort(),f}await p.complete(),g.applyToEntries(t),this._observedEvents&&this._observedEvents.updateEvents(t),u&&g.hasUnverifiedSenders&&c.wrapDetached("fetch unknown senders keys",async f=>{var R,N;const v=await g.fetchAndVerifyRemainingSenders(this._hsApi,f),M=[];v.applyToEntries(t,F=>M.push(F)),(R=this._timeline)==null||R.replaceEntries(M),(N=this._observedEvents)==null||N.updateEvents(M)})},pu(i))}async _getSyncRetryDecryptEntries(e,t,s){let r=(await Promise.all(e.map(async o=>{const c=await t.getEventIdsForMissingKey(o,s);if(c)return this._eventIdsToEntries(c,s)}))).reduce((o,c)=>c?o.concat(c):o,[]);if(this._timeline){const c=this._getAdditionalTimelineRetryEntries(r,e).map(l=>l.clone());r=r.concat(c)}return r}async load(e,t,s){s.set("id",this.id);try{if(e&&this._summary.load(e),this._summary.data.encryption){const i=this._createRoomEncryption(this,this._summary.data.encryption);this._setEncryption(i)}if(this._summary.data.needsHeroes){this._heroes=new Rn(this._roomId);const i=await this._heroes.calculateChanges(this._summary.data.heroes,[],t);this._heroes.applyChanges(i,this._summary.data,s)}}catch(i){throw new ha(`Could not load room ${this._roomId}`,i)}}async observeMember(e){this._observedMembers||(this._observedMembers=new Map);const t=this._observedMembers.get(e);if(t)return t;const s=await lu({summary:this._summary,roomId:this._roomId,userId:e,storage:this._storage,hsApi:this._hsApi},this._platform.logger);if(!s)return null;const i=new Ui(s,()=>this._observedMembers.delete(e));return this._observedMembers.set(e,i),i}async loadMemberList(e=void 0,t=null){if(this._memberList)return this._memberList.retain(),this._memberList;{const s=await cu({summary:this._summary,roomId:this._roomId,hsApi:this._hsApi,storage:this._storage,txn:e,syncToken:this._getSyncToken(),setChangedMembersMap:i=>this._changedMembersDuringSync=i,log:t},this._platform.logger);return this._memberList=new uu({members:s,closeCallback:()=>{this._memberList=null}}),this._memberList}}fillGap(e,t,s=null){return this._platform.logger.wrapOrRun(s,"fillGap",async i=>{if(i.set("id",this.id),i.set("fragment",e.fragmentId),i.set("dir",e.direction.asApiString()),e.edgeReached){i.set("edgeReached",!0);return}const r=await this._hsApi.messages(this._roomId,{from:e.token,dir:e.direction.asApiString(),limit:t,filter:{lazy_load_members:!0,include_redundant_members:!0}},{log:i}).response(),o=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents,this._storage.storeNames.timelineEvents,this._storage.storeNames.timelineRelations,this._storage.storeNames.timelineFragments]);let c,l;try{c=await this._writeGapFill(r.chunk,o,i);const h=new Ka({roomId:this._roomId,fragmentIdComparer:this._fragmentIdComparer,ownUserId:this._user.id});l=await new su({roomId:this._roomId,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer,relationWriter:h}).writeFragmentFill(e,r,e.token,o,i)}catch(h){throw o.abort(),h}await o.complete(),this._roomEncryption&&await this._decryptEntries(ts.Timeline,l.entries,null,i).complete();for(const h of l.fragments)this._fragmentIdComparer.add(h);c&&this._applyGapFill(c),this._timeline&&(this._timeline.replaceEntries(l.updatedEntries),this._timeline.addEntries(l.entries))})}async _writeGapFill(e,t,s){}_applyGapFill(){}get name(){if(this._heroes)return this._heroes.roomName;const e=this._summary.data;return e.name?e.name:e.canonicalAlias?e.canonicalAlias:null}get id(){return this._roomId}get avatarUrl(){return this._summary.data.avatarUrl?this._summary.data.avatarUrl:this._heroes?this._heroes.roomAvatarUrl:null}get avatarColorId(){return this._roomId}get lastMessageTimestamp(){return this._summary.data.lastMessageTimestamp}get isLowPriority(){const e=this._summary.data.tags;return!!(e&&e["m.lowpriority"])}get isEncrypted(){return!!this._summary.data.encryption}get isJoined(){return this.membership==="join"}get isLeft(){return this.membership==="leave"}get canonicalAlias(){return this._summary.data.canonicalAlias}get joinedMemberCount(){return this._summary.data.joinCount}get mediaRepository(){return this._mediaRepository}get membership(){return this._summary.data.membership}get user(){return this._user}isDirectMessageForUserId(e){if(this._summary.data.dmUserId===e)return!0;{const{heroes:t,joinCount:s,inviteCount:i}=this._summary.data;if(t&&t.includes(e)&&s+i===2)return!0}return!1}async _loadPowerLevels(){const e=await this._storage.readTxn([this._storage.storeNames.roomState]),t=await e.roomState.get(this._roomId,"m.room.power_levels","");if(t)return new gr({powerLevelEvent:t.event,ownUserId:this._user.id,membership:this.membership});const s=await e.roomState.get(this._roomId,"m.room.create","");if(s)return new gr({createEvent:s.event,ownUserId:this._user.id,membership:this.membership});{const i=this.membership;return new gr({ownUserId:this._user.id,membership:i})}}async observePowerLevels(){this._powerLevelLoading&&await this._powerLevelLoading;let e=this._powerLevels;if(!e){this._powerLevelLoading=this._loadPowerLevels();const t=await this._powerLevelLoading;e=new Ui(t,()=>{this._powerLevels=null}),this._powerLevels=e,this._powerLevelLoading=null}return e}enableKeyBackup(e){var t;(t=this._roomEncryption)==null||t.enableKeyBackup(e),this._timeline&&e&&this._platform.logger.run("enableKeyBackup",s=>this._roomEncryption.restoreMissingSessionsFromBackup(this._timeline.remoteEntries,s))}get _isTimelineOpen(){return!!this._timeline}_emitUpdate(){this.emit("change"),this._emitCollectionChange(this)}async openTimeline(e=null){return await this._platform.logger.wrapOrRun(e,"open timeline",async t=>{this._timelineLoadPromise&&await this._timelineLoadPromise;let s;if(this._timelineLoadPromise=new Promise(i=>{s=()=>{this._timelineLoadPromise=null,i()}}),t.set("id",this.id),this._timeline)return t.log({l:"Returning existing timeline"}),s(),this._timeline.retain(),this._timeline;this._timeline=new Mr({roomId:this.id,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer,pendingEvents:this._getPendingEvents(),closeCallback:()=>{this._timeline=null,this._roomEncryption&&this._roomEncryption.notifyTimelineClosed()},clock:this._platform.clock,logger:this._platform.logger,powerLevelsObservable:await this.observePowerLevels(),hsApi:this._hsApi});try{this._roomEncryption&&this._timeline.enableEncryption(this._decryptEntries.bind(this,ts.Timeline)),await this._timeline.load(this._user,this.membership,t)}catch(i){throw this._timeline.dispose(),i}finally{s()}return this._timeline.retain(),this._timeline})}_getPendingEvents(){return null}observeEvent(e){this._observedEvents||(this._observedEvents=new mu(()=>{this._observedEvents=null}));let t=null;this._timeline&&(t=this._timeline.getByEventId(e));const s=this._observedEvents.observe(e,t);return t||this._readEventById(e).then(i=>{s.update(i)}).catch(i=>{console.warn(`could not load event ${e} from storage`,i)}),s}async _readEventById(e){return await new ja({roomId:this._roomId,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer}).readById(e)}dispose(){var e;(e=this._roomEncryption)==null||e.dispose()}}class bu{constructor(e,t){this._cancelled=!1,this.preparation=null,this._promise=t.wrap("decryptEntries",s=>e(this,s))}complete(){return this._promise}get cancelled(){return this._cancelled}dispose(){this._cancelled=!0,this.preparation&&this.preparation.dispose()}}class Su{constructor({roomId:e,storage:t,hsApi:s,pendingEvents:i}){i=i||[],this._roomId=e,this._storage=t,this._hsApi=s,this._pendingEvents=new fn((r,o)=>r.queueIndex-o.queueIndex),this._pendingEvents.setManyUnsorted(i.map(r=>this._createPendingEvent(r))),this._isSending=!1,this._offline=!1,this._roomEncryption=null,this._currentQueueIndex=0}_createPendingEvent(e,t=null){const s=new ch({data:e,remove:()=>this._removeEvent(s),emitUpdate:i=>this._pendingEvents.update(s,i),attachments:t});return s}enableEncryption(e){this._roomEncryption=e}_sendLoop(e){this._isSending=!0,this._sendLoopLogItem=e.runDetached("send queue flush",async t=>{try{for(const s of this._pendingEvents)await t.wrap("send event",async i=>{i.set("queueIndex",s.queueIndex);try{this._currentQueueIndex=s.queueIndex,await this._sendEvent(s,i)}catch(r){r instanceof Ut?(this._offline=!0,i.set("offline",!0),s.setWaiting()):(i.catch(r),r.name==="HomeServerError"&&(r.statusCode===400||r.statusCode===403||r.statusCode===404)?(i.set("remove",!0),await s.abort()):s.setError(r))}finally{this._currentQueueIndex=0}})}finally{this._isSending=!1,this._sendLoopLogItem=null}})}async _sendEvent(e,t){if(e.needsUpload&&(await t.wrap("upload attachments",s=>e.uploadAttachments(this._hsApi,s)),await this._tryUpdateEvent(e)),e.needsEncryption){e.setEncrypting();const s=e.contentForEncryption,{type:i,content:r}=await t.wrap("encrypt",o=>this._roomEncryption.encrypt(e.eventType,s,this._hsApi,o));e.setEncrypted(i,r),await this._tryUpdateEvent(e)}if(e.needsSending){await e.send(this._hsApi,t);const s=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);try{await this._tryUpdateEventWithTxn(e,s),await this._resolveRemoteIdInPendingRelations(e.txnId,e.remoteId,s)}catch(i){throw s.abort(),i}await s.complete()}}async _resolveRemoteIdInPendingRelations(e,t,s){const i=this._pendingEvents.array.filter(r=>r.relatedTxnId===e&&r.relatedEventId!==t);for(const r of i)r.setRelatedEventId(t),await this._tryUpdateEventWithTxn(r,s);return i}async removeRemoteEchos(e,t,s){const i=[];for(const r of e){const o=r.unsigned&&r.unsigned.transaction_id;let c;if(o?c=this._pendingEvents.array.findIndex(l=>l.txnId===o):c=this._pendingEvents.array.findIndex(l=>l.remoteId===r.event_id),c!==-1){const l=this._pendingEvents.get(c),h=r.event_id;s.log({l:"removeRemoteEcho",queueIndex:l.queueIndex,remoteId:h,txnId:o}),t.pendingEvents.remove(l.roomId,l.queueIndex),i.push(l),await this._resolveRemoteIdInPendingRelations(o,h,t)}}return i}async _removeEvent(e){if(this._pendingEvents.array.indexOf(e)!==-1){const s=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);try{s.pendingEvents.remove(e.roomId,e.queueIndex)}catch{s.abort()}await s.complete();const i=this._pendingEvents.array.indexOf(e);i!==-1&&this._pendingEvents.remove(i)}e.dispose()}emitRemovals(e){for(const t of e){const s=this._pendingEvents.array.indexOf(t);s!==-1&&this._pendingEvents.remove(s),t.dispose()}}resumeSending(e){this._offline=!1,this._pendingEvents.length&&e.wrap("resumeSending",t=>{t.set("id",this._roomId),t.set("pendingEvents",this._pendingEvents.length),this._isSending||this._sendLoop(t),this._sendLoopLogItem&&t.refDetached(this._sendLoopLogItem)})}async enqueueEvent(e,t,s,i){const r=rs(t);let o=null;if(r){const c=bn(r);if(mo(c)&&(o=c,wa(r,null)),r.rel_type===ss&&this._pendingEvents.array.some(h=>{const a=rs(h.content);return h.eventType===e&&a&&a.key===r.key&&(h.relatedTxnId===o||a.event_id===r.event_id)})){i.set("already_annotating",!0);return}}return await this._enqueueEvent(e,t,s,o,null,i)}async _enqueueEvent(e,t,s,i,r,o){const c=await this._createAndStoreEvent(e,t,i,r,s);return this._pendingEvents.set(c),o.set("queueIndex",c.queueIndex),o.set("pendingEvents",this._pendingEvents.length),!this._isSending&&!this._offline&&this._sendLoop(o),this._sendLoopLogItem&&o.refDetached(this._sendLoopLogItem),c}async enqueueRedaction(e,t,s){if(this._pendingEvents.array.some(c=>c.eventType===gt&&(c.relatedTxnId===e||c.relatedEventId===e))){s.set("already_redacting",!0);return}let r,o;if(mo(e)){r=e;const c=e,l=this._pendingEvents.array.find(h=>h.txnId===c);if(l&&!l.remoteId&&l.status!==X.Sending){s.set("remove",r),await l.abort();return}else if(l)o=l.remoteId;else return}else{o=e;const c=this._pendingEvents.array.find(l=>l.remoteId===o);c&&(r=c.txnId)}s.set("relatedTxnId",r),s.set("relatedEventId",o),await this._enqueueEvent(gt,{reason:t},null,r,o,s)}get pendingEvents(){return this._pendingEvents}async _tryUpdateEvent(e){const t=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);try{this._tryUpdateEventWithTxn(e,t)}catch(s){throw t.abort(),s}await t.complete()}async _tryUpdateEventWithTxn(e,t){await t.pendingEvents.exists(e.roomId,e.queueIndex)&&t.pendingEvents.update(e.data)}async _createAndStoreEvent(e,t,s,i,r){const o=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);let c;try{const l=o.pendingEvents,h=await l.getMaxQueueIndex(this._roomId)||0,u=Math.max(h,this._currentQueueIndex)+1,p=e!==gt&&e!==Zl&&!!this._roomEncryption;c=this._createPendingEvent({roomId:this._roomId,queueIndex:u,eventType:e,content:t,relatedTxnId:s,relatedEventId:i,txnId:Pe(),needsEncryption:p,needsUpload:!!r},r),l.add(c.data)}catch(l){throw o.abort(),l}return await o.complete(),c}dispose(){for(const e of this._pendingEvents)e.dispose()}}class Wa{constructor({filename:e,blob:t,platform:s}){this._filename=e,this._unencryptedBlob=t,this._transferredBlob=this._unencryptedBlob,this._platform=s,this._mxcUrl=null,this._encryptionInfo=null,this._uploadRequest=null,this._aborted=!1,this._error=null,this._sentBytes=0}get size(){return this._transferredBlob.size}get sentBytes(){return this._sentBytes}abort(){var e;(e=this._uploadRequest)==null||e.abort()}get localPreview(){return this._unencryptedBlob}async encrypt(){if(this._encryptionInfo)throw new Error("already encrypted");const{info:e,blob:t}=await Vl(this._platform,this._transferredBlob);this._transferredBlob=t,this._encryptionInfo=e}async upload(e,t,s){this._uploadRequest=e.uploadAttachment(this._transferredBlob,this._filename,{uploadProgress:r=>{this._sentBytes=r,t()},log:s});const{content_uri:i}=await this._uploadRequest.response();this._mxcUrl=i}applyToContent(e,t){if(!this._mxcUrl)throw new Error("upload has not finished");let s=e.substr(0,e.lastIndexOf("url"));ar(`${s}info.size`,t,this._transferredBlob.size),ar(`${s}info.mimetype`,t,this._unencryptedBlob.mimeType),this._encryptionInfo?ar(`${s}file`,t,Object.assign(this._encryptionInfo,{mimetype:this._unencryptedBlob.mimeType,url:this._mxcUrl})):ar(`${s}url`,t,this._mxcUrl)}dispose(){this._unencryptedBlob.dispose(),this._transferredBlob.dispose()}}function ar(n,e,t){const s=n.split(".");let i=e;for(let o=0;op.event)))),u=u.filter(p=>(p==null?void 0:p.type)===ku),u.length&&(h=await c.prepareDecryptAll(u,s,ts.Sync,i))}return{roomEncryption:c,summaryChanges:o,decryptPreparation:h,decryptChanges:null,retryEntries:l}}async afterPrepareSync(e,t){e.decryptPreparation&&await t.wrap("decrypt",async s=>{s.set("id",this.id),e.decryptChanges=await e.decryptPreparation.decrypt(),e.decryptPreparation=null},t.level.Detail)}async writeSync(e,t,{summaryChanges:s,decryptChanges:i,roomEncryption:r,retryEntries:o},c,l){var D;l.set("id",this.id);const h=s.isNewJoin(this._summary.data);h&&(c.roomState.removeAllForRoom(this.id),c.roomMembers.removeAllForRoom(this.id));const{entries:a,updatedEntries:u,newLiveKey:p,memberChanges:g,memberSync:f}=await l.wrap("syncWriter",B=>this._syncWriter.writeSync(e,h,s.hasFetchedMembers,c,B),l.level.Detail);let v;i&&(v=await l.wrap("decryptChanges",B=>i.write(c,B)),l.set("decryptionResults",v.results.size),l.set("decryptionErrors",v.errors.size),this._isTimelineOpen&&await v.verifyKnownSenders(c),v.applyToEntries(a),o!=null&&o.length&&(v.applyToEntries(o),u.push(...o))),l.set("newEntries",a.length),l.set("updatedEntries",u.length);let M;r&&(M=await r.writeSync(e,g,c,l),l.set("shouldFlushKeyShares",M.shouldFlush));const R=a.concat(u);s=s.applyTimelineEntries(R,t,!this._isTimelineOpen,this._user.id),s.membership!=="join"?c.roomSummary.remove(this.id):s=this._summary.writeData(s,c),s&&l.set("summaryChanges",s.changedKeys(this._summary.data));let N;s!=null&&s.needsHeroes&&(this._heroes||(this._heroes=new Rn(this._roomId)),N=await this._heroes.calculateChanges(s.heroes,g,c));let F;Array.isArray((D=e.timeline)==null?void 0:D.events)&&(F=await this._sendQueue.removeRemoteEchos(e.timeline.events,c,l));const T=this._getPowerLevelsEvent(e);return await this._runRoomStateHandlers(e,f,c,l),{roomResponse:e,summaryChanges:s,roomEncryption:r,newEntries:a,updatedEntries:u,newLiveKey:p,removedPendingEvents:F,memberChanges:g,heroChanges:N,powerLevelsEvent:T,encryptionChanges:M,decryption:v}}afterSync(e,t){const{summaryChanges:s,newEntries:i,updatedEntries:r,newLiveKey:o,removedPendingEvents:c,memberChanges:l,powerLevelsEvent:h,heroChanges:a,roomEncryption:u,roomResponse:p,encryptionChanges:g}=e;if(t.set("id",this.id),this._syncWriter.afterSync(o),this._setEncryption(u),this._roomEncryption&&this._roomEncryption.afterSync(g),l.size){if(this._changedMembersDuringSync)for(const[v,M]of l.entries())this._changedMembersDuringSync.set(v,M.member);if(this._memberList&&this._memberList.afterSync(l),this._roomStateHandler.updateRoomMembers(this,l),this._observedMembers&&this._updateObservedMembers(l),this._timeline){for(const[v,M]of l.entries())if(v===this._user.id){this._timeline.updateOwnMember(M.member);break}}}let f=!1;if(s&&(this._summary.applyChanges(s),this._summary.data.needsHeroes||(this._heroes=null),f=!0),this._heroes&&a){const v=this.name;this._heroes.applyChanges(a,this._summary.data,t),v!==this.name&&(f=!0)}h&&this._updatePowerLevels(h),f&&this._emitUpdate(),this._timeline&&(this._timeline.replaceEntries(r),this._timeline.addEntries(i)),this._observedEvents&&(this._observedEvents.updateEvents(r),this._observedEvents.updateEvents(i)),c&&this._sendQueue.emitRemovals(c),this._emitSyncRoomState(p)}_updateObservedMembers(e){for(const[t,s]of e){const i=this._observedMembers.get(t);i&&i.set(s.member)}}_getPowerLevelsEvent(e){let t;return Js(e,s=>{s.state_key===""&&s.type===gu&&(t=s)}),t}_updatePowerLevels(e){if(this._powerLevels){const t=new gr({powerLevelEvent:e,ownUserId:this._user.id,membership:this.membership});this._powerLevels.set(t)}}async afterSyncCompleted({encryptionChanges:e,decryption:t,newEntries:s,updatedEntries:i},r){const o=e==null?void 0:e.shouldFlush,c=this._isTimelineOpen&&(t==null?void 0:t.hasUnverifiedSenders);(o||c)&&await r.wrap({l:"room",id:this.id},async l=>{const h=[];if(o&&h.push(this._roomEncryption.flushPendingRoomKeyShares(this._hsApi,null,l)),c){const a=l.wrap("verify senders",async u=>{var v,M;const p=await t.fetchAndVerifyRemainingSenders(this._hsApi,u),g=[],f=R=>g.push(R);p.applyToEntries(s,f),p.applyToEntries(i,f),u.set("verifiedEntries",g.length),(v=this._timeline)==null||v.replaceEntries(g),(M=this._observedEvents)==null||M.updateEvents(g)});h.push(a)}await Promise.all(h)})}start(e,t){if(this._roomEncryption){const s=e==null?void 0:e.get("share_room_key");s&&t.wrapDetached("flush room keys",i=>(i.set("id",this.id),this._roomEncryption.flushPendingRoomKeyShares(this._hsApi,s,i)))}this._sendQueue.resumeSending(t)}async load(e,t,s){try{await super.load(e,t,s),await this._syncWriter.load(t,s)}catch(i){throw new ha(`Could not load room ${this._roomId}`,i)}}async _writeGapFill(e,t,s){return await this._sendQueue.removeRemoteEchos(e,t,s)}_applyGapFill(e){this._sendQueue.emitRemovals(e)}sendEvent(e,t,s,i=null){return this._platform.logger.wrapOrRun(i,"send",r=>(r.set("id",this.id),this._sendQueue.enqueueEvent(e,t,s,r)))}sendRedaction(e,t,s=null){return this._platform.logger.wrapOrRun(s,"redact",i=>(i.set("id",this.id),this._sendQueue.enqueueRedaction(e,t,i)))}async ensureMessageKeyIsShared(e=null){if(!!this._roomEncryption)return this._platform.logger.wrapOrRun(e,"ensureMessageKeyIsShared",t=>(t.set("id",this.id),this._roomEncryption.ensureMessageKeyIsShared(this._hsApi,t)))}get avatarColorId(){var e;return((e=this._heroes)==null?void 0:e.roomAvatarColorId)||this._roomId}get isUnread(){return this._summary.data.isUnread}get notificationCount(){return this._summary.data.notificationCount}get highlightCount(){return this._summary.data.highlightCount}get isTrackingMembers(){return this._summary.data.isTrackingMembers}async _getLastEventId(){var t;const e=this._syncWriter.lastMessageKey;if(e){const i=await(await this._storage.readTxn([this._storage.storeNames.timelineEvents])).timelineEvents.get(this._roomId,e);return(t=i==null?void 0:i.event)==null?void 0:t.event_id}}async clearUnread(e=null,t=!0){if(this.isUnread||this.notificationCount)return await this._platform.logger.wrapOrRun(e,"clearUnread",async s=>{s.set("id",this.id);const i=await this._storage.readWriteTxn([this._storage.storeNames.roomSummary]);let r;try{r=this._summary.writeClearUnread(i)}catch(o){throw i.abort(),o}await i.complete(),this._summary.applyChanges(r),this._emitUpdate();try{const o=t&&await this._getLastEventId();o&&await this._hsApi.receipt(this._roomId,"m.read",o)}catch(o){if(o.name!=="ConnectionError")throw o}})}leave(e=null){return this._platform.logger.wrapOrRun(e,"leave room",async t=>{t.set("id",this.id),await this._hsApi.leave(this.id,{log:t}).response()})}async inviteUser(e,t){if(!e)throw new Error("userId is null/undefined");await this._hsApi.invite(this.id,e,t).response()}_getPendingEvents(){return this._sendQueue.pendingEvents}_runRoomStateHandlers(e,t,s,i){const r=[];return Js(e,o=>{r.push(this._roomStateHandler.handleRoomState(this,o,t,s,i))}),Promise.all(r)}_emitSyncRoomState(e){Js(e,t=>{for(const s of this._roomStateObservers)s.handleStateEvent(t)})}writeIsTrackingMembers(e,t){return this._summary.writeIsTrackingMembers(e,t)}applyIsTrackingMembersChanges(e){this._summary.applyChanges(e)}createAttachment(e,t){return new Wa({blob:e,filename:t,platform:this._platform})}dispose(){super.dispose(),this._sendQueue.dispose()}}class Mu extends Ha{constructor(e){super(e),this._releaseCallback=e.releaseCallback,this._forgetCallback=e.forgetCallback,this._retentionCount=1,this._kickDetails=null,this._kickedBy=null}retain(){this._retentionCount+=1}release(){this._retentionCount-=1,this._retentionCount===0&&this._releaseCallback()}async _getKickAuthor(e,t){const s=await t.roomMembers.get(this.id,e);return s?new Q(s):Q.fromUserId(this.id,e,"join")}async load(e,t,s){const{summary:i,kickDetails:r}=e;return this._kickDetails=r,this._kickDetails&&(this._kickedBy=await this._getKickAuthor(this._kickDetails.sender,t)),super.load(i,t,s)}async writeSync(e,t,s,i,r){if(r.set("id",this.id),s==="leave"){const o=Cu(t,this._user.id);if(o||e){const c=o||this._kickDetails;let l;o&&(l=await this._getKickAuthor(o.sender,i));const h=e||this._summary.data;return i.archivedRoomSummary.set({summary:h.serialize(),kickDetails:c}),{kickDetails:c,kickedBy:l,summaryData:h}}}else s==="join"&&i.archivedRoomSummary.remove(this.id);return{}}afterSync({summaryData:e,kickDetails:t,kickedBy:s},i){i.set("id",this.id),e&&this._summary.applyChanges(e),t&&(this._kickDetails=t),s&&(this._kickedBy=s),this._emitUpdate()}get isKicked(){var e;return((e=this._kickDetails)==null?void 0:e.membership)==="leave"}get isBanned(){var e;return((e=this._kickDetails)==null?void 0:e.membership)==="ban"}get kickedBy(){return this._kickedBy}get kickReason(){var e;return(e=this._kickDetails)==null?void 0:e.reason}isArchived(){return!0}forget(e=null){return this._platform.logger.wrapOrRun(e,"forget room",async t=>{t.set("id",this.id),await this._hsApi.forget(this.id,{log:t}).response();const s=this._storage.storeNames,i=await this._storage.readWriteTxn([s.roomState,s.archivedRoomSummary,s.roomMembers,s.timelineEvents,s.timelineFragments,s.timelineRelations,s.pendingEvents,s.inboundGroupSessions,s.groupSessionDecryptions,s.operations]);i.roomState.removeAllForRoom(this.id),i.archivedRoomSummary.remove(this.id),i.roomMembers.removeAllForRoom(this.id),i.timelineEvents.removeAllForRoom(this.id),i.timelineFragments.removeAllForRoom(this.id),i.timelineRelations.removeAllForRoom(this.id),i.pendingEvents.removeAllForRoom(this.id),i.inboundGroupSessions.removeAllForRoom(this.id),i.groupSessionDecryptions.removeAllForRoom(this.id),await i.operations.removeAllForScope(this.id),await i.complete(),this._retentionCount=0,this._releaseCallback(),this._forgetCallback(this.id)})}join(e=null){return this._platform.logger.wrapOrRun(e,"rejoin archived room",async t=>{await this._hsApi.join(this.id,{log:t}).response()})}}function Cu(n,e){var s,i;let t;if(Js(n,r=>{r.type===Ke&&r.state_key===e&&r.sender!==r.state_key&&(t=r)}),t)return{membership:(s=t.content)==null?void 0:s.membership,reason:(i=t.content)==null?void 0:i.reason,sender:t.sender}}async function Eu(n,e,t){const s=await Promise.all(n.map(async i=>{const r=await e.profile(i,{log:t}).response();return new Ru(i,r.displayname,r.avatar_url)}));return s.sort((i,r)=>i.name.localeCompare(r.name)),s}class Ru{constructor(e,t,s){this.userId=e,this.displayName=t,this.avatarUrl=s}get name(){return this.displayName||this.userId}}class Tu{constructor(e){this.userId=e}get displayName(){}get name(){return this.userId}get avatarUrl(){}}function Au(n){switch(n){case Le.DirectMessage:case Le.Private:return!0;case Le.Public:return!1}}function xu(n){switch(n){case Le.DirectMessage:return"trusted_private_chat";case Le.Private:return"private_chat";case Le.Public:return"public_chat"}}class Vu extends $t{constructor(e,t,s,i,r,o){var c;if(super(),this.id=e,this.options=t,this.updateCallback=s,this.mediaRepository=i,this.platform=r,this.profiles=[],this._isCancelled=!1,this.isEncrypted=t.isEncrypted===void 0?Au(t.type):t.isEncrypted,t.name)this._calculatedName=t.name;else{const l={joinCount:1,inviteCount:((c=t.invites)==null?void 0:c.length)||0},h=(t.invites||[]).map(a=>new Tu(a));this._calculatedName=tn(h,l,o)}}async create(e,t){try{let s;if(this.options.avatar){const{avatar:o}=this.options,c=new Wa({filename:o.name,blob:o.blob,platform:this.platform});await c.upload(e,()=>{},t),s={info:o.info},c.applyToContent("url",s)}const i={is_direct:this.options.type===Le.DirectMessage,preset:xu(this.options.type),initial_state:[]};this.options.name&&(i.name=this.options.name),this.options.topic&&(i.topic=this.options.topic),this.options.invites&&(i.invite=this.options.invites),this.options.alias&&(i.room_alias_name=this.options.alias),this.options.isFederationDisabled===!0&&(i.creation_content={"m.federate":!1}),this.options.powerLevelContentOverride&&(i.power_level_content_override=this.options.powerLevelContentOverride),this.isEncrypted&&i.initial_state.push(Hl()),s&&i.initial_state.push({type:"m.room.avatar",state_key:"",content:s});const r=await e.createRoom(i,{log:t}).response();this._roomId=r.room_id}catch(s){this._error=s}this.emitChange()}async loadProfiles(e,t){try{if(!this.options.name&&this.options.invites){this.profiles=await Eu(this.options.invites,e,t);const s={joinCount:1,inviteCount:this.options.invites.length};this._calculatedName=tn(this.profiles,s,t),this.emitChange()}}catch{}}emitChange(e){this.updateCallback(this,e),this.emit("change")}get avatarColorId(){var e,t,s;return(s=(t=(e=this.options.invites)==null?void 0:e[0])!=null?t:this._roomId)!=null?s:this.id}get avatarUrl(){var e,t;return(t=(e=this.profiles)==null?void 0:e[0])==null?void 0:t.avatarUrl}get avatarBlobUrl(){var e,t;return(t=(e=this.options.avatar)==null?void 0:e.blob)==null?void 0:t.url}get roomId(){return this._roomId}get name(){return this._calculatedName}get isBeingCreated(){return!0}get error(){return this._error}cancel(){this._isCancelled||(this.dispose(),this._isCancelled=!0,this.emitChange("isCancelled"))}get isCancelled(){return this._isCancelled}dispose(){this.options.avatar&&this.options.avatar.blob.dispose()}async adjustDirectMessageMapIfNeeded(e,t,s,i){if(!this.options.invites||this.options.type!==Le.DirectMessage)return;const r=this.options.invites[0],o="m.direct";await i.wrap("set "+o,async c=>{try{const l=await t.readWriteTxn([t.storeNames.accountData]);let h;try{h=await l.accountData.get(o),h||(h={type:o,content:{}});const a=h.content;let u=a[r];u||(a[r]=u=[]),u.push(this._roomId),l.accountData.set(h),await l.complete()}catch(a){throw l.abort(),a}await s.setAccountData(e.id,o,h.content,{log:c}).response()}catch(l){c.catch(l)}})}}class Nu extends $t{constructor({roomId:e,user:t,hsApi:s,mediaRepository:i,emitCollectionRemove:r,emitCollectionUpdate:o,platform:c}){super(),this._roomId=e,this._user=t,this._hsApi=s,this._emitCollectionRemove=r,this._emitCollectionUpdate=o,this._mediaRepository=i,this._platform=c,this._inviteData=null,this._accepting=!1,this._rejecting=!1,this._accepted=!1,this._rejected=!1}get isInvite(){return!0}get id(){return this._roomId}get name(){return this._inviteData.name||this._inviteData.canonicalAlias}get isDirectMessage(){return this._inviteData.isDirectMessage}get avatarUrl(){return this._inviteData.avatarUrl}get avatarColorId(){return this._inviteData.avatarColorId||this.id}get timestamp(){return this._inviteData.timestamp}get isEncrypted(){return this._inviteData.isEncrypted}get inviter(){return this._inviter}isDirectMessageForUserId(e){return this.isDirectMessage&&this._inviter.userId===e}get isPublic(){return this._inviteData.joinRule==="public"}get canonicalAlias(){return this._inviteData.canonicalAlias}async accept(e=null){await this._platform.logger.wrapOrRun(e,"acceptInvite",async t=>{this._accepting=!0,this._emitChange("accepting"),await this._hsApi.join(this._roomId,{log:t}).response()})}async reject(e=null){await this._platform.logger.wrapOrRun(e,"rejectInvite",async t=>{this._rejecting=!0,this._emitChange("rejecting"),await this._hsApi.leave(this._roomId,{log:t}).response()})}get accepting(){return this._accepting}get accepted(){return this._accepted}get rejecting(){return this._rejecting}get rejected(){return this._rejected}get mediaRepository(){return this._mediaRepository}_emitChange(e){this.emit("change"),this._emitCollectionUpdate(this,e)}load(e,t){t.set("id",this.id),this._inviteData=e,this._inviter=e.inviter?new Q(e.inviter):null}async writeSync(e,t,s,i){var r;if(e==="invite"){i.set("id",this.id),i.set("add",!0);const o=(r=t.invite_state)==null?void 0:r.events;if(!Array.isArray(o))return null;const c=this._createSummaryData(o);let l;!c.name&&!c.canonicalAlias&&(l=await this._createHeroes(o,i));const h=this._getMyInvite(o);if(!h)return null;const a=this._getInviter(h,o),u=this._createData(o,h,a,c,l);return s.invites.set(u),{inviteData:u,inviter:a}}else return i.set("id",this.id),i.set("membership",e),s.invites.remove(this.id),{removed:!0,membership:e}}afterSync(e,t){t.set("id",this.id),e&&(e.removed?(this._accepting=!1,this._rejecting=!1,e.membership==="join"?this._accepted=!0:this._rejected=!0,this.emit("change")):(this._inviteData=e.inviteData,this._inviter=e.inviter))}_createData(e,t,s,i,r){const o=r?r.roomName:i.name,c=r?r.roomAvatarUrl:i.avatarUrl,l=(r==null?void 0:r.roomAvatarColorId)||this.id;return{roomId:this.id,isEncrypted:!!i.encryption,isDirectMessage:i.isDirectMessage,name:o,avatarUrl:c,avatarColorId:l,canonicalAlias:i.canonicalAlias,timestamp:this._platform.clock.now(),joinRule:this._getJoinRule(e),inviter:s==null?void 0:s.serialize()}}_createSummaryData(e){return e.reduce((t,s)=>ga(t,s,this._user.id),new Rt(null,this.id))}async _createHeroes(e,t){const s=e.filter(a=>a.type===Ke),i=s.filter(a=>a.state_key!==this._user.id),r=i.reduce((a,u)=>{const p=Q.fromMemberEvent(this.id,u);return a.set(p.userId,new ka(p,null)),a},new Map),o=i.map(a=>a.state_key),c=new Rn(this.id),l=await c.calculateChanges(o,r,null),h=new Rt(null,this.id);return h.joinCount=s.reduce((a,u)=>{var p;return a+(((p=u.content)==null?void 0:p.membership)==="join"?1:0)},0),h.inviteCount=s.reduce((a,u)=>{var p;return a+(((p=u.content)==null?void 0:p.membership)==="invite"?1:0)},0),c.applyChanges(l,h,t),c}_getMyInvite(e){return e.find(t=>t.type===Ke&&t.state_key===this._user.id)}_getInviter(e,t){const s=t.find(i=>i.type===Ke&&i.state_key===e.sender);if(s)return Q.fromMemberEvent(this.id,s)}_getJoinRule(e){var s;const t=e.find(i=>i.type==="m.room.join_rules");return t?(s=t.content)==null?void 0:s.join_rule:null}}class bs{constructor(e){this._description=e}static httpPusher(e,t,s,i){return new bs({kind:"http",append:!0,data:Object.assign({},i,{url:e+"/_matrix/push/v1/notify"}),pushkey:s,app_id:t,app_display_name:"Hydrogen",device_display_name:"Hydrogen",lang:"en"})}static createDefaultPayload(e){return{session_id:e}}async enable(e,t){try{t.set("endpoint",new URL(this._description.data.endpoint).host)}catch{t.set("endpoint",null)}await e.setPusher(this._description,{log:t}).response()}async disable(e,t){const s=Object.assign({},this._description,{kind:null});await e.setPusher(s,{log:t}).response()}serialize(){return this._description}equals(e){return this._description.app_id!==e._description.app_id||this._description.pushkey!==e._description.pushkey?!1:JSON.stringify(this._description.data)===JSON.stringify(e._description.data)}}class Du extends $t{constructor({storage:e,callHandler:t}){super(),this._storage=e,this._olmDecryption=null,this._megolmDecryption=null,this._callHandler=t,this._senderDeviceCache=new $a(10,s=>s.curve25519Key)}enableEncryption({olmDecryption:e,megolmDecryption:t}){this._olmDecryption=e,this._megolmDecryption=t}obtainSyncLock(e){var t;return(t=this._olmDecryption)==null?void 0:t.obtainDecryptionLock(e)}async prepareSync(e,t,s,i){i.set("messageTypes",uo(e,c=>c.type));const r=e.filter(c=>c.type==="m.room.encrypted");if(this._emitUnencryptedEvents(e),!this._olmDecryption){i.log("can't decrypt, encryption not enabled",i.level.Warn);return}const o=r.filter(c=>{var l;return((l=c.content)==null?void 0:l.algorithm)===wn});if(o.length){const c=await this._olmDecryption.decryptAll(o,t,s);i.set("decryptedTypes",uo(c.results,h=>{var a;return(a=h.event)==null?void 0:a.type}));for(const h of c.errors)i.child("decrypt_error").catch(h);const l=this._megolmDecryption.roomKeysFromDeviceMessages(c.results,i);return new Uu(c,l)}}async writeSync(e,t){return e.olmDecryptChanges.write(t),{hasNewRoomKeys:(await Promise.all(e.newRoomKeys.map(r=>this._megolmDecryption.writeRoomKey(r,t)))).some(r=>!!r),decryptionResults:e.olmDecryptChanges.results}}async afterSyncCompleted(e,t,s,i){if(await i.wrap("Verifying fingerprint of encrypted toDevice messages",async r=>{for(const o of e){const c=o.event.sender,l=await t.deviceForCurveKey(c,o.senderCurve25519Key,s,r);o.setDevice(l),o.isVerified?this.emit("message",{encrypted:o}):r.log({l:"could not verify olm fingerprint key matches, ignoring",ed25519Key:o.device.ed25519Key,claimedEd25519Key:o.claimedEd25519Key,deviceId:l.deviceId,userId:l.userId})}}),this._callHandler){const r=e.filter(o=>{var c;return this._callHandler.handlesDeviceMessageEventType((c=o.event)==null?void 0:c.type)});r.length&&await i.wrap("process call signalling messages",async o=>{for(const c of r){const l=await t.deviceForId(c.event.sender,c.event.content.device_id,s,o);c.setDevice(l),c.isVerified?this._callHandler.handleDeviceMessage(c.event,c.userId,c.deviceId,o):o.log({l:"could not verify olm fingerprint key matches, ignoring",ed25519Key:c.device.ed25519Key,claimedEd25519Key:c.claimedEd25519Key,deviceId:l.deviceId,userId:l.userId})}})}}_emitUnencryptedEvents(e){const t=e.filter(s=>s.type!=="m.room.encrypted");for(const s of t)this.emit("message",{unencrypted:s})}}class Uu{constructor(e,t){this.olmDecryptChanges=e,this.newRoomKeys=t,this.newKeysByRoom=ti(t,s=>s.roomId)}}const Ei=Oe+"olmAccount",sn=Oe+"areDeviceKeysUploaded",fr=Oe+"serverOTKCount";async function go(n,e,t,s,i){const r=n.pickle(e),o=await i.readWriteTxn([i.storeNames.session]);try{o.session.add(Ei,r),o.session.add(sn,t),o.session.add(fr,s)}catch(c){throw o.abort(),c}await o.complete()}class Is{static async load({olm:e,pickleKey:t,hsApi:s,userId:i,deviceId:r,olmWorker:o,txn:c}){const l=await c.session.get(Ei);if(l){const h=new e.Account,a=await c.session.get(sn);h.unpickle(t,l);const u=await c.session.get(fr);return new Is({pickleKey:t,hsApi:s,account:h,userId:i,deviceId:r,areDeviceKeysUploaded:a,serverOTKCount:u,olm:e,olmWorker:o})}}static async adoptDehydratedDevice({olm:e,dehydratedDevice:t,pickleKey:s,hsApi:i,userId:r,olmWorker:o,storage:c}){const l=t.adoptUnpickledOlmAccount(),h=JSON.parse(l.one_time_keys()),u=Object.entries(h.curve25519).length,p=!0;return await go(l,s,p,u,c),new Is({pickleKey:s,hsApi:i,account:l,userId:r,deviceId:t.deviceId,areDeviceKeysUploaded:p,serverOTKCount:u,olm:e,olmWorker:o})}static async create({olm:e,pickleKey:t,hsApi:s,userId:i,deviceId:r,olmWorker:o,storage:c}){const l=new e.Account;o?await o.createAccountAndOTKs(l,l.max_number_of_one_time_keys()):(l.create(),l.generate_one_time_keys(l.max_number_of_one_time_keys()));const h=!1,a=0;return c&&await go(l,t,h,a,c),new Is({pickleKey:t,hsApi:s,account:l,userId:i,deviceId:r,areDeviceKeysUploaded:h,serverOTKCount:a,olm:e,olmWorker:o})}constructor({pickleKey:e,hsApi:t,account:s,userId:i,deviceId:r,areDeviceKeysUploaded:o,serverOTKCount:c,olm:l,olmWorker:h}){this._olm=l,this._pickleKey=e,this._hsApi=t,this._account=s,this._userId=i,this._deviceId=r,this._areDeviceKeysUploaded=o,this._serverOTKCount=c,this._olmWorker=h,this._identityKeys=JSON.parse(this._account.identity_keys())}get identityKeys(){return this._identityKeys}setDeviceId(e){this._deviceId=e}async uploadKeys(e,t,s){var o;const i=JSON.parse(this._account.one_time_keys()),r=Object.entries(i.curve25519);if(r.length||!this._areDeviceKeysUploaded){const c={};if(!this._areDeviceKeysUploaded){s.set("identity",!0);const a=JSON.parse(this._account.identity_keys());c.device_keys=this._deviceKeysPayload(a)}r.length&&(s.set("otks",!0),c.one_time_keys=this._oneTimeKeysPayload(r));const l=t?this._deviceId:void 0,h=await this._hsApi.uploadKeys(l,c,{log:s}).response();this._serverOTKCount=(o=h==null?void 0:h.one_time_key_counts)==null?void 0:o.signed_curve25519,s.set("serverOTKCount",this._serverOTKCount),await this._updateSessionStorage(e,a=>{r.length&&(this._account.mark_keys_as_published(),a==null||a.set(Ei,this._account.pickle(this._pickleKey)),a==null||a.set(fr,this._serverOTKCount)),this._areDeviceKeysUploaded||(this._areDeviceKeysUploaded=!0,a==null||a.set(sn,this._areDeviceKeysUploaded))})}}async generateOTKsIfNeeded(e,t){const s=this._account.max_number_of_one_time_keys(),i=Math.floor(s/2);if(this._serverOTKCount0&&await t.wrap("generate otks",h=>{h.set("max",s),h.set("server",this._serverOTKCount),h.set("unpublished",c),h.set("new",l),h.set("limit",i),this._account.generate_one_time_keys(l),this._updateSessionStorage(e,a=>{a.set(Ei,this._account.pickle(this._pickleKey))})}),!0}return!1}createInboundOlmSession(e,t){const s=new this._olm.Session;try{return s.create_inbound_from(this._account,e,t),s}catch(i){throw s.free(),i}}async createOutboundOlmSession(e,t){const s=new this._olm.Session;try{return this._olmWorker?await this._olmWorker.createOutboundOlmSession(this._account,s,e,t):s.create_outbound(this._account,e,t),s}catch(i){throw s.free(),i}}writeRemoveOneTimeKey(e,t){this._account.remove_one_time_keys(e),t.session.set(Ei,this._account.pickle(this._pickleKey))}writeSync(e,t,s){const i=e.signed_curve25519;if(Number.isSafeInteger(i)&&i!==this._serverOTKCount)return t.session.set(fr,i),s.set("otkCount",i),i}afterSync(e){Number.isSafeInteger(e)&&(this._serverOTKCount=e)}_keysAsSignableObject(e){const t={user_id:this._userId,device_id:this._deviceId,algorithms:[wn,ft],keys:{}};for(const[s,i]of Object.entries(e))t.keys[`${s}:${this._deviceId}`]=i;return t}getUnsignedDeviceKey(){const e=JSON.parse(this._account.identity_keys());return this._keysAsSignableObject(e)}_deviceKeysPayload(e){const t=this._keysAsSignableObject(e);return this.signObject(t),t}_oneTimeKeysPayload(e){const t={};for(const[s,i]of e){const r={key:i};this.signObject(r),t[`signed_curve25519:${s}`]=r}return t}async _updateSessionStorage(e,t){if(e){const s=await e.readWriteTxn([e.storeNames.session]);try{await t(s.session)}catch(i){throw s.abort(),i}await s.complete()}else await t(void 0)}signObject(e){const t=e.signatures||{},s=e.unsigned;delete e.signatures,delete e.unsigned,t[this._userId]=t[this._userId]||{},t[this._userId]["ed25519:"+this._deviceId]=this._account.sign(qi.stringify(e)),e.signatures=t,s!==void 0&&(e.unsigned=s)}pickleWithKey(e){return this._account.pickle(e)}dispose(){this._account.free(),this._account=void 0}}class Tn{constructor(e,t){this._id=e,this._keyDescription=t}get id(){return this._id}get passphraseParams(){var e;return(e=this._keyDescription)==null?void 0:e.passphrase}get algorithm(){var e;return(e=this._keyDescription)==null?void 0:e.algorithm}async isCompatible(e,t){if(this.algorithm==="m.secret_storage.v1.aes-hmac-sha2"){const s=this._keyDescription;if(s.mac){const i=await Ou(e.binaryKey,s.iv,t);return s.mac===i}else if(s.passphrase){const i=e.description._keyDescription;return i.passphrase?s.passphrase.algorithm===i.passphrase.algorithm&&s.passphrase.iterations===i.passphrase.iterations&&s.passphrase.salt===i.passphrase.salt:!1}}return!1}}class Wi{constructor(e,t){this._keyDescription=e,this._binaryKey=t}withDescription(e){return new Wi(e,this._binaryKey)}get description(){return this._keyDescription}get id(){return this._keyDescription.id}get binaryKey(){return this._binaryKey}get algorithm(){return this._keyDescription.algorithm}}async function Ou(n,e,t){const{crypto:s,encoding:i}=t,{utf8:r,base64:o}=i,{derive:c,aes:l,hmac:h}=s,a=o.decode(e),u=new Uint8Array(8),p="\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",g=r.encode(""),f=await c.hkdf(n,u,g,"SHA-256",512),v=f.slice(0,32),M=f.slice(32),R=await l.encryptCTR({key:v,iv:a,data:r.encode(p)}),N=await h.compute(M,R,"SHA-256");return o.encode(N)}const Pu=5e5,Fu=256;async function Lu(n,e,t){const{passphraseParams:s}=n;if(!s)throw new Error("not a passphrase key");if(s.algorithm!=="m.pbkdf2")throw new Error(`Unsupported passphrase algorithm: ${s.algorithm}`);const{utf8:i}=t.encoding,r=await t.crypto.derive.pbkdf2(i.encode(e),s.iterations||Pu,i.encode(s.salt),"SHA-512",s.bits||Fu);return new Wi(n,r)}const vi=[139,1];function Ku(n,e,t,s){const i=s.encoding.base58.decode(e.replace(/ /g,""));let r=0;for(const c of i)r^=c;if(r!==0)throw new Error("Incorrect parity");for(let c=0;c{switch(e==null?void 0:e.event.type){case"m.secret.request":{await this._respondToRequest(e);break}case"m.secret.send":{const{secret:s}=e.event.content,i=await this.shouldAcceptSecret(e);i&&this.writeSecretToStorage(i,s);break}}}),await this.aesEncryption.load()}async _respondToRequest(e){await this.logger.run("SharedSecret.respondToRequest",async t=>{if(!await this.shouldRespondToRequest(e,t))return;const s=e.event.content,i=s.request_id,r=s.requesting_device_id,o=s.name,c=await this.secretFetcher.getSecret(o);if(!c){t.log({l:"Secret not available to share"});return}const l={secret:c,request_id:i},h=await this.deviceTracker.deviceForId(this.ourUserId,r,this.hsApi,t);if(!h){t.log({l:"Cannot find device",deviceId:r});return}const a=await t.wrap("olm encrypt",p=>this.olmEncryption.encrypt("m.secret.send",l,[h],this.hsApi,p)),u=Fi(a);await this.hsApi.sendToDevice("m.room.encrypted",u,Pe(),{log:t}).response()})}async shouldRespondToRequest(e,t){return t.wrap("SecretSharing.shouldRespondToRequest",async()=>{if(e.event.content.requesting_device_id===this.deviceTracker.ownDeviceId)return!1;const s=this.crossSigning.get();if(!s)return t.log({crossSigningNotAvailable:!0}),!1;const i=e.event.content;if(e.event.sender!==this.ourUserId||!(i.name&&i.action&&i.requesting_device_id&&i.request_id)||i.action==="request_cancellation")return!1;const r=i.requesting_device_id,o=await this.deviceTracker.deviceForId(this.ourUserId,r,this.hsApi,t);return o?await s.isOurUserDeviceTrusted(o,t)?!0:(t.log({l:"Device not trusted, returning"}),!1):(t.log({l:"Device could not be acquired",deviceId:r}),!1)})}async shouldAcceptSecret(e){const t=this.crossSigning.get();if(!t)return;const s=e.device;if(!s||!await t.isOurUserDeviceTrusted(s))return;const r=e.event.content.request_id,o=this.waitMap.get(r);if(o){const{name:a,deferred:u}=o;return u.resolve(e),this.waitMap.delete(r),await this.removeStoredRequestId(r),a}const l=await(await this.storage.readTxn([this.storage.storeNames.session])).session.get(bi),h=l==null?void 0:l[r];if(h)return await this.removeStoredRequestId(r),h}async removeStoredRequestId(e){const t=await this.storage.readWriteTxn([this.storage.storeNames.session]),s=await t.session.get(bi);s&&(delete s[e],t.session.set(bi,s))}async checkSecretValidity(e){const t=this.crossSigning.get();!await(t==null?void 0:t.areWeVerified(e))&&(await this.storage.readWriteTxn([this.storage.storeNames.sharedSecrets])).sharedSecrets.deleteAllSecrets()}async getLocallyStoredSecret(e){const s=await(await this.storage.readTxn([this.storage.storeNames.sharedSecrets])).sharedSecrets.get(e);if(s)return await this.aesEncryption.decrypt(s.encrypted)}requestSecret(e,t){return t.wrap("SharedSecret.requestSecret",async s=>{const i=Pe(),r=this.trackSecretRequest(i,e);return await this.sendRequestForSecret(e,i,s),await this.writeRequestIdToStorage(i,e),new ju(r)})}async writeRequestIdToStorage(e,t){var r;const s=await this.storage.readWriteTxn([this.storage.storeNames.session]),i=(r=await s.session.get(bi))!=null?r:{};i[e]=t,s.session.set(bi,i)}async writeSecretToStorage(e,t){const s=await this.aesEncryption.encrypt(t);(await this.storage.readWriteTxn([J.sharedSecrets])).sharedSecrets.set(e,{encrypted:s})}trackSecretRequest(e,t){const s=new As;return this.waitMap.set(e,{deferred:s,name:t}),s.promise}async sendRequestForSecret(e,t,s){const i={action:"request",name:e,request_id:t,requesting_device_id:this.deviceTracker.ownDeviceId};let r=await this.deviceTracker.devicesForUsers([this.ourUserId],this.hsApi,s);r=r.filter(l=>l.device_id!==this.deviceTracker.ownDeviceId);const o=await s.wrap("olm encrypt",l=>this.olmEncryption.encrypt("m.secret.request",i,r,this.hsApi,l)),c=Fi(o);await this.hsApi.sendToDevice("m.room.encrypted",c,Pe(),{log:s}).response()}setSecretFetcher(e){this.secretFetcher=e}}class ju{constructor(e){this.receivedSecretPromise=e}async waitForResponse(e=30){const t=new Promise((i,r)=>{setTimeout(r,e*1e3)});return(await Promise.race([this.receivedSecretPromise,t])).event.content.secret}}class qu{constructor(e,t,s){this.storage=e,this.crypto=t,this.encoding=s}async load(){var r;const e=`${Oe}localAESKey`,t=await this.storage.readTxn([J.session]);let{key:s,iv:i}=(r=await t.session.get(e))!=null?r:{};s||(s=await this.crypto.aes.generateKey("jwk"),i=await this.crypto.aes.generateIV(),(await this.storage.readWriteTxn([J.session])).session.set(e,{key:s,iv:i})),this.key=s,this.iv=i}async encrypt(e){const t=this.encoding.utf8.encode(e);return await this.crypto.aes.encryptCTR({jwkKey:this.key,iv:this.iv,data:t})}async decrypt(e){const t=await this.crypto.aes.decryptCTR({jwkKey:this.key,iv:this.iv,data:e});return this.encoding.utf8.decode(t)}}class cr extends Error{constructor(e,t){super(e),this.reason=t}}class Hu{constructor({key:e,platform:t,storage:s}){this._key=e,this._platform=t,this._storage=s}async hasValidKeyForAnyAccountData(){const t=await(await this._storage.readTxn([this._storage.storeNames.accountData])).accountData.getAll();for(const s of t)try{const i=await this._decryptAccountData(s);return!0}catch(i){if(i instanceof cr&&i.reason!==0)throw i;continue}return!1}async readSecret(e){const s=await(await this._storage.readTxn([this._storage.storeNames.accountData])).accountData.get(e);if(!!s)return await this._decryptAccountData(s)}async _decryptAccountData(e){var s,i;const t=(i=(s=e==null?void 0:e.content)==null?void 0:s.encrypted)==null?void 0:i[this._key.id];if(!t)throw new cr(`Secret ${e.type} is not encrypted for key ${this._key.id}`,0);if(this._key.algorithm==="m.secret_storage.v1.aes-hmac-sha2")return await this._decryptAESSecret(e.type,t);throw new cr(`Unsupported algorithm for key ${this._key.id}: ${this._key.algorithm}`,2)}async _decryptAESSecret(e,t){const{base64:s,utf8:i}=this._platform.encoding,r=await this._platform.crypto.derive.hkdf(this._key.binaryKey,new Uint8Array(8).buffer,i.encode(e),"SHA-256",512),o=r.slice(0,32),c=r.slice(32),l=s.decode(t.ciphertext);if(!await this._platform.crypto.hmac.verify(c,s.decode(t.mac),l,"SHA-256"))throw new cr("Bad MAC",1);const a=await this._platform.crypto.aes.decryptCTR({key:o,iv:s.decode(t.iv),data:l});return i.decode(a)}}const An=`${Oe}ssssKey`,fo=`${Oe}keyBackupVersion`;var mt=(n=>(n[n.RecoveryKey=0]="RecoveryKey",n[n.Passphrase=1]="Passphrase",n))(mt||{});async function za(n){var r;const e=await n.readTxn([n.storeNames.accountData]),t=await e.accountData.get("m.secret_storage.default_key"),s=(r=t==null?void 0:t.content)==null?void 0:r.key;if(!s)return;const i=await e.accountData.get(`m.secret_storage.key.${s}`);if(!!i)return new Tn(s,i.content)}async function Wu(n,e,t){const s=await t.session.get(fo);return t.session.set(fo,e),t.session.set(An,{id:n.id,binaryKey:n.binaryKey}),s}async function zu(n){const e=await n.session.get(An);if(!e)return;const t=await n.accountData.get(`m.secret_storage.key.${e.id}`);if(t)return new Wi(new Tn(e.id,t.content),e.binaryKey)}async function Gu(n){n.session.remove(An)}async function Yu(n,e,t,s,i){const r=await za(t);if(!r)throw new Error("Could not find a default secret storage key in account data");return await Ga(n,e,r,s,i)}async function Ga(n,e,t,s,i){let r;if(n===1)r=await Lu(t,e,s);else if(n===0)r=Ku(t,e,i,s);else throw new Error(`Invalid type: ${n}`);return r}async function Ju(n,e,t){const s=await za(e);if(await(s==null?void 0:s.isCompatible(n,t)))return n.withDescription(s)}const Ya="org.matrix.msc2697.v1.olm.libolm_pickle";async function Qu(n,e,t,s){try{const i=await n.getDehydratedDevice({log:s}).response();if(i.device_data.algorithm===Ya)return new Zu(i,e,t)}catch(i){i.name!=="HomeServerError"&&(s.error=i);return}}async function Xu(n,e,t,s,i){var c;const o=(await e.createDehydratedDevice({device_data:{algorithm:Ya,account:n.pickleWithKey(t.binaryKey.slice()),passphrase:((c=t.description)==null?void 0:c.passphraseParams)||{}},initial_device_display_name:s}).response()).device_id;return n.setDeviceId(o),await n.uploadKeys(void 0,!0,i),o}class Zu{constructor(e,t,s){this._dehydratedDevice=e,this._olm=t,this._platform=s}async decrypt(e,t){const s=new Tn("dehydrated_device",this._dehydratedDevice.device_data.passphrase),i=await Ga(e,t,s,this._platform,this._olm),r=new this._olm.Account;try{const o=this._dehydratedDevice.device_data.account;return r.unpickle(i.binaryKey.slice(),o),new em(this._dehydratedDevice,r,i)}catch(o){if(r.free(),o.message==="OLM.BAD_ACCOUNT_KEY")return;throw o}}get deviceId(){return this._dehydratedDevice.device_id}}class em{constructor(e,t,s){this._dehydratedDevice=e,this._account=t,this._key=s}async claim(e,t){try{return(await e.claimDehydratedDevice(this.deviceId,{log:t}).response()).success}catch{return!1}}adoptUnpickledOlmAccount(){const e=this._account;return this._account=void 0,e}get deviceId(){return this._dehydratedDevice.device_id}get key(){return this._key}dispose(){var e;(e=this._account)==null||e.free(),this._account=void 0}}class Ja{tryTake(){return this._promise?!1:(this._promise=new Promise(e=>{this._resolve=e}),!0)}async take(){for(;!this.tryTake();)await this.released()}get isTaken(){return!!this._promise}release(){if(this._resolve){this._promise=void 0;const e=this._resolve;this._resolve=void 0,e()}}released(){return this._promise}}class Qa{constructor(e){this.locks=e}release(){for(const e of this.locks)e.release()}}function Xa(n,e,t,s){return{session:n.pickle(s),sessionId:n.session_id(),senderKey:e,lastUsed:t}}class Cr{constructor(e,t,s,i=!1){this.data=e,this.pickleKey=t,this.olm=s,this.isNew=i,this.isModified=i}static create(e,t,s,i,r){const o=Xa(t,e,r,i);return new Cr(o,i,s,!0)}get id(){return this.data.sessionId}load(){const e=new this.olm.Session;return e.unpickle(this.pickleKey,this.data.session),e}unload(e){e.free()}save(e){this.data.session=e.pickle(this.pickleKey),this.isModified=!0}}class Za{constructor(e,t,s,i){this.event=e,this.senderCurve25519Key=t,this.claimedEd25519Key=s,this.encryptedEvent=i}setDevice(e){this.device=e}get isVerified(){return this.device?ks(this.device)===this.claimedEd25519Key:!1}get isUnverified(){return this.device?!this.isVerified:!0}get userId(){var e;return(e=this.device)==null?void 0:e.user_id}get deviceId(){var e;return(e=this.device)==null?void 0:e.device_id}get isVerificationUnknown(){return!this.device}}var Er=(n=>(n[n.PreKey=0]="PreKey",n[n.Normal=1]="Normal",n))(Er||{});const yo=4;function ec(n){n.sort((e,t)=>t.data.lastUsed-e.data.lastUsed)}class tm{constructor(e,t,s,i,r,o){this.account=e,this.pickleKey=t,this.now=s,this.ownUserId=i,this.olm=r,this.senderKeyLock=o}async obtainDecryptionLock(e){var i;const t=new Set;for(const r of e){const o=(i=r.content)==null?void 0:i.sender_key;o&&t.add(o)}const s=await Promise.all(Array.from(t).map(r=>this.senderKeyLock.takeLock(r)));return new Qa(s)}async decryptAll(e,t,s){try{const i=ti(e,a=>{var u;return(u=a.content)==null?void 0:u.sender_key}),r=this.now(),o=await Promise.all(Array.from(i.entries()).map(([a,u])=>this._decryptAllForSenderKey(a,u,r,s))),c=o.reduce((a,u)=>a.concat(u.results),[]),l=o.reduce((a,u)=>a.concat(u.errors),[]),h=o.map(a=>a.senderKeyDecryption);return new im(h,c,l,this.account,t)}catch(i){throw t.release(),i}}async _decryptAllForSenderKey(e,t,s,i){const r=await this._getSessions(e,i),o=new sm(e,r,s),c=[],l=[];for(const h of t)try{const a=this._decryptForSenderKey(o,h,s);c.push(a)}catch(a){l.push(a)}return{results:c,errors:l,senderKeyDecryption:o}}_decryptForSenderKey(e,t,s){const i=e.senderKey,r=this._getMessageAndValidateEvent(t);let o;try{o=e.decrypt(r)}catch(c){throw new fe("OLM_BAD_ENCRYPTED_MESSAGE",t,{senderKey:i,error:c.message})}if(typeof o!="string"&&r.type===Er.PreKey){let c;try{c=this._createSessionAndDecrypt(i,r,s)}catch(l){throw new fe(`Could not create inbound olm session: ${l.message}`,t,{senderKey:i,error:l})}e.addNewSession(c.session),o=c.plaintext}if(typeof o=="string"){let c;try{c=JSON.parse(o)}catch(l){throw new fe("PLAINTEXT_NOT_JSON",t,{plaintext:o,error:l})}return this._validatePayload(c,t),new Za(c,i,c.keys.ed25519)}else throw new fe("OLM_NO_MATCHING_SESSION",t,{knownSessionIds:e.sessions.map(c=>c.id)})}_createSessionAndDecrypt(e,t,s){let i;const r=this.account.createInboundOlmSession(e,t.body);try{i=r.decrypt(t.type,t.body);const o=Cr.create(e,r,this.olm,this.pickleKey,s);return o.unload(r),{session:o,plaintext:i}}catch(o){throw r.free(),o}}_getMessageAndValidateEvent(e){var i;const t=(i=e.content)==null?void 0:i.ciphertext;if(!t)throw new fe("OLM_MISSING_CIPHERTEXT",e);const s=t==null?void 0:t[this.account.identityKeys.curve25519];if(!s)throw new fe("OLM_NOT_INCLUDED_IN_RECIPIENTS",e);return s}async _getSessions(e,t){const i=(await t.olmSessions.getAll(e)).map(r=>new Cr(r,this.pickleKey,this.olm));return ec(i),i}_validatePayload(e,t){var s,i,r;if(e.sender!==t.sender)throw new fe("OLM_FORWARDED_MESSAGE",t,{sentBy:t.sender,encryptedBy:e.sender});if(e.recipient!==this.ownUserId)throw new fe("OLM_BAD_RECIPIENT",t,{recipient:e.recipient});if(((s=e.recipient_keys)==null?void 0:s.ed25519)!==this.account.identityKeys.ed25519)throw new fe("OLM_BAD_RECIPIENT_KEY",t,{key:(i=e.recipient_keys)==null?void 0:i.ed25519});if(!e.type)throw new fe("missing type on payload",t,{payload:e});if(typeof((r=e.keys)==null?void 0:r.ed25519)!="string")throw new fe("Missing or invalid claimed ed25519 key on payload",t,{payload:e})}}class sm{constructor(e,t,s){this.senderKey=e,this.sessions=t,this.timestamp=s}addNewSession(e){this.sessions.unshift(e)}decrypt(e){for(const t of this.sessions){const s=this.decryptWithSession(t,e);if(typeof s=="string")return ec(this.sessions),s}}getModifiedSessions(){return this.sessions.filter(e=>e.isModified)}get hasNewSessions(){return this.sessions.some(e=>e.isNew)}decryptWithSession(e,t){if(t.type===void 0||t.body===void 0)throw new Error("Invalid message without type or body");const s=e.load();try{if(t.type===Er.PreKey&&!s.matches_inbound(t.body))return;try{const i=s.decrypt(t.type,t.body);return e.save(s),e.data.lastUsed=this.timestamp,i}catch(i){if(t.type===Er.PreKey)throw new Error(`Error decrypting prekey message with existing session id ${e.id}: ${i.message}`);return}}finally{e.unload(s)}}}class im{constructor(e,t,s,i,r){this.senderKeyDecryptions=e,this.results=t,this.errors=s,this.account=i,this.lock=r}get hasNewSessions(){return this.senderKeyDecryptions.some(e=>e.hasNewSessions)}write(e){try{for(const t of this.senderKeyDecryptions){for(const s of t.getModifiedSessions())if(e.olmSessions.set(s.data),s.isNew){const i=s.load();try{this.account.writeRemoveOneTimeKey(i,e)}finally{s.unload(i)}}if(t.sessions.length>yo){const{senderKey:s,sessions:i}=t;for(let r=i.length-1;r>=yo;r-=1){const o=i[r];e.olmSessions.remove(s,o.id)}}}}finally{this.lock.release()}}}function rm(n){return n.reduce((e,t)=>!e||t!s.isTaken).slice(0,e);if(t.lengthi.isTaken).slice(0,e-t.length);t.push(...s)}return await Promise.all(t.map(s=>s.take())),new Qa(t)}async encrypt(e,t,s,i,r){let o=[];for(let c=0;cthis.senderKeyLock.takeLock(_t(c))));try{const{devicesWithoutSession:c,existingEncryptionTargets:l}=await this._findExistingSessions(s),h=this.now();let a=[];try{if(c.length){const g=await r.wrap("create sessions",f=>this._createNewSessions(c,i,h,f));a=a.concat(g)}await this._loadSessions(l),a=a.concat(l);const u={l:"encrypt",targets:a.length},p=r.wrap(u,()=>a.map(g=>{const f=this._encryptForDevice(e,t,g);return new om(f,g.device)}));return await this._storeSessions(a,h),p}finally{for(const u of a)u.dispose()}}finally{for(const c of o)c.release()}}async _findExistingSessions(e){const t=await this.storage.readTxn([this.storage.storeNames.olmSessions]),s=await Promise.all(e.map(async o=>await t.olmSessions.getSessionIds(_t(o)))),i=e.filter((o,c)=>{const l=s[c];return!(l!=null&&l.length)}),r=e.map((o,c)=>{const l=s[c];if((l==null?void 0:l.length)>0){const h=rm(l);return Li.fromSessionId(o,h)}}).filter(o=>!!o);return{devicesWithoutSession:i,existingEncryptionTargets:r}}_encryptForDevice(e,t,s){const{session:i,device:r}=s,o=JSON.stringify(this._buildPlainTextMessageForDevice(e,t,r)),c=i.encrypt(o);return{algorithm:wn,sender_key:this.account.identityKeys.curve25519,ciphertext:{[_t(r)]:c}}}_buildPlainTextMessageForDevice(e,t,s){return{keys:{ed25519:this.account.identityKeys.ed25519},recipient_keys:{ed25519:ks(s)},recipient:s.user_id,sender:this.ownUserId,content:t,type:e}}async _createNewSessions(e,t,s,i){const r=await i.wrap("claim",o=>this._claimOneTimeKeys(t,e,o));try{for(const o of r){const{device:c,oneTimeKey:l}=o;o.session=await this.account.createOutboundOlmSession(_t(c),l)}await this._storeSessions(r,s)}catch(o){for(const c of r)c.dispose();throw o}return r}async _claimOneTimeKeys(e,t,s){const i=En(t,l=>l.user_id,()=>new Map,(l,h)=>l.set(h.device_id,h)),r=Array.from(i.entries()).reduce((l,[h,a])=>(l[h]=Array.from(a.values()).reduce((u,p)=>(u[p.device_id]=wo,u),{}),l),{}),o=await e.claimKeys({timeout:1e4,one_time_keys:r},{log:s}).response();Object.keys(o.failures).length&&s.log({l:"failures",servers:Object.keys(o.failures)},s.level.Warn);const c=o==null?void 0:o.one_time_keys;return this._verifyAndCreateOTKTargets(c,i,s)}_verifyAndCreateOTKTargets(e,t,s){var r;const i=[];for(const[o,c]of Object.entries(e))for(const[l,h]of Object.entries(c)){const[a,u]=Object.entries(h)[0],[p]=a.split(":");if(p===wo){const g=(r=t.get(o))==null?void 0:r.get(l);if(g&&vn(this.olmUtil,o,l,ks(g),u,s)===ne.Valid){const v=Li.fromOTK(g,u.key);i.push(v)}}}return i}async _loadSessions(e){const t=await this.storage.readTxn([this.storage.storeNames.olmSessions]);let s=!1;try{await Promise.all(e.map(async i=>{const r=await t.olmSessions.get(_t(i.device),i.sessionId);if(r&&!s){const o=new this.olm.Session;o.unpickle(this.pickleKey,r.session),i.session=o}}))}catch(i){s=!0;for(const r of e)r.dispose();throw i}}async _storeSessions(e,t){const s=await this.storage.readWriteTxn([this.storage.storeNames.olmSessions]);try{for(const i of e){const r=Xa(i.session,_t(i.device),t,this.pickleKey);s.olmSessions.set(r)}}catch(i){throw s.abort(),i}await s.complete()}}class Li{constructor(e,t,s){this.device=e,this.oneTimeKey=t,this.sessionId=s,this.session=null}static fromOTK(e,t){return new Li(e,t,null)}static fromSessionId(e,t){return new Li(e,null,t)}dispose(){this.session&&this.session.free()}}class om{constructor(e,t){this.content=e,this.device=t}}class am{constructor(e,t,s,i){this._roomId=e,this._results=t,this._errors=s,this._replayEntries=i}async write(e){return await Promise.all(this._replayEntries.map(async t=>{try{this._handleReplayAttack(this._roomId,t,e)}catch(s){this._errors.set(t.eventId,s)}})),{results:this._results,errors:this._errors}}async _handleReplayAttack(e,t,s){const{messageIndex:i,sessionId:r,eventId:o,timestamp:c}=t,l=await s.groupSessionDecryptions.get(e,r,i);if(l&&l.eventId!==o){const a=l.timestamp{const r=await i.decryptAll();rn(r.errors,e),rn(r.results,t),s.push(...r.replayEntries)})),new am(this._roomId,t,e,s)}finally{this.dispose()}}dispose(){for(const e of this._sessionDecryptions)e.dispose()}}class lm{constructor(e,t,s){this.sessionId=e,this.messageIndex=t,this.event=s}get eventId(){return this.event.event_id}get timestamp(){return this.event.origin_server_ts}}class hm{constructor(e,t,s,i){this.key=e,this.events=t,this.olmWorker=s,this.keyLoader=i,this.decryptionRequests=s?[]:void 0}async decryptAll(){const e=[],t=new Map;let s;return await this.keyLoader.useKey(this.key,async i=>{for(const r of this.events)try{const o=r.content.ciphertext;let c;if(this.olmWorker){const u=this.olmWorker.megolmDecrypt(i,o);this.decryptionRequests.push(u),c=await u.response()}else c=i.decrypt(o);const{plaintext:l}=c;let h;try{h=JSON.parse(l)}catch(u){throw new fe("PLAINTEXT_NOT_JSON",r,{plaintext:l,err:u})}if(h.room_id!==this.key.roomId)throw new fe("MEGOLM_WRONG_ROOM",r,{encryptedRoomId:h.room_id,eventRoomId:this.key.roomId});e.push(new lm(this.key.sessionId,c.message_index,r));const a=new Za(h,this.key.senderKey,this.key.claimedEd25519Key,r);t.set(r.event_id,a)}catch(o){if(o.name==="AbortError")return;s||(s=new Map),s.set(r.event_id,o)}}),{results:t,errors:s,replayEntries:e}}dispose(){if(this.decryptionRequests)for(const e of this.decryptionRequests)e.abort()}}function xn(n){var e;return(e=n.content)==null?void 0:e.sender_key}function Vn(n){var e;return(e=n.content)==null?void 0:e.session_id}function dm(n){var e;return(e=n.content)==null?void 0:e.ciphertext}function um(n){return typeof xn(n)=="string"&&typeof Vn(n)=="string"&&typeof dm(n)=="string"}class mm{constructor(){this.events=[]}get senderKey(){return xn(this.events[0])}get sessionId(){return Vn(this.events[0])}}function nn(n){return En(n,e=>`${xn(e)}|${Vn(e)}`,()=>new mm,(e,t)=>e.events.push(t))}class tc{isForSession(e,t,s){return this.roomId===e&&this.senderKey===t&&this.sessionId===s}get isBetter(){return this._isBetter}set isBetter(e){this._isBetter=e}}function sc(n,e){return n.first_known_index(){s=r.pickle(o)},t),this.isBetter===!1)return!1;s||(s=await e.useKey(this,(r,o)=>r.pickle(o)));const i={roomId:this.roomId,senderKey:this.senderKey,sessionId:this.sessionId,session:s,backup:this.backupStatus,source:this.keySource,claimedKeys:{ed25519:this.claimedEd25519Key}};return t.inboundGroupSessions.set(i),!0}get eventIds(){return this._eventIds}async _checkBetterThanKeyInStorage(e,t,s){if(this.isBetter!==void 0)return this.isBetter;let i=e.getCachedKey(this.roomId,this.senderKey,this.sessionId);if(!i){const r=await nc(this.roomId,this.senderKey,this.sessionId,s);r&&(r.hasSession?i=r:r.eventIds&&(this._eventIds=r.eventIds))}if(i){const r=i;await e.useKey(this,async o=>{await e.useKey(r,(c,l)=>{this.isBetter=sc(o,c),r.isBetter=!this.isBetter,this.isBetter&&t&&t(o,l)})})}else this.isBetter=!0;return this.isBetter}get backupStatus(){return Vr.NotBackedUp}}class _m extends Nn{constructor(e){super(),this._decryptionResult=e}get roomId(){var e;return(e=this._decryptionResult.event.content)==null?void 0:e.room_id}get senderKey(){return this._decryptionResult.senderCurve25519Key}get sessionId(){var e;return(e=this._decryptionResult.event.content)==null?void 0:e.session_id}get claimedEd25519Key(){return this._decryptionResult.claimedEd25519Key}get serializationKey(){var e;return(e=this._decryptionResult.event.content)==null?void 0:e.session_key}get serializationType(){return"create"}get keySource(){return Hi.DeviceMessage}loadInto(e){e.create(this.serializationKey)}}class pm extends Nn{constructor(e,t,s){super(),this._roomId=e,this.outboundSession=t,this.identityKeys=s,this.isBetter=!0,this._sessionKey=this.outboundSession.session_key()}get roomId(){return this._roomId}get senderKey(){return this.identityKeys.curve25519}get sessionId(){return this.outboundSession.session_id()}get claimedEd25519Key(){return this.identityKeys.ed25519}get serializationKey(){return this._sessionKey}get serializationType(){return"create"}get keySource(){return Hi.Outbound}loadInto(e){e.create(this.serializationKey)}}class gm extends Nn{constructor(e,t,s){super(),this._roomId=e,this._sessionId=t,this._backupInfo=s}get roomId(){return this._roomId}get senderKey(){return this._backupInfo.sender_key}get sessionId(){return this._sessionId}get claimedEd25519Key(){var e;return(e=this._backupInfo.sender_claimed_keys)==null?void 0:e.ed25519}get serializationKey(){return this._backupInfo.session_key}get serializationType(){return"import_session"}get keySource(){return Hi.Backup}loadInto(e){e.import_session(this.serializationKey)}get backupStatus(){return Vr.BackedUp}}class ic extends tc{constructor(e){super(),this.isBetter=!0,this.storageEntry=e}get roomId(){return this.storageEntry.roomId}get senderKey(){return this.storageEntry.senderKey}get sessionId(){return this.storageEntry.sessionId}get claimedEd25519Key(){return this.storageEntry.claimedKeys.ed25519}get eventIds(){return this.storageEntry.eventIds}get serializationKey(){return this.storageEntry.session||""}get serializationType(){return"unpickle"}loadInto(e,t){e.unpickle(t,this.serializationKey)}get hasSession(){return!!this.serializationKey}}function fm(n){var s;const e=(s=n.event.content)==null?void 0:s.session_key,t=new _m(n);if(typeof t.roomId=="string"&&typeof t.sessionId=="string"&&typeof t.senderKey=="string"&&typeof e=="string")return t}function rc(n,e,t){var o;const s=t.session_key,i=t.sender_key,r=(o=t.sender_claimed_keys)==null?void 0:o.ed25519;if(typeof n=="string"&&typeof e=="string"&&typeof i=="string"&&typeof s=="string"&&typeof r=="string")return new gm(n,e,t)}async function nc(n,e,t,s){const i=await s.inboundGroupSessions.get(n,e,t);if(i)return new ic(i)}class ym{constructor(e,t){this.keyLoader=e,this.olmWorker=t}async addMissingKeyEventIds(e,t,s,i,r){let o=await r.inboundGroupSessions.get(e,t,s);if(!(o!=null&&o.session)){if(o){const c=new Set(o.eventIds);for(const l of i)c.add(l);o.eventIds=Array.from(c)}else o={roomId:e,senderKey:t,sessionId:s,eventIds:i};r.inboundGroupSessions.set(o)}}async getEventIdsForMissingKey(e,t,s,i){const r=await i.inboundGroupSessions.get(e,t,s);if(r&&!r.session)return r.eventIds}async hasSession(e,t,s,i){const r=await i.inboundGroupSessions.get(e,t,s);return typeof(r==null?void 0:r.session)=="string"}async prepareDecryptAll(e,t,s,i){const r=new Map,o=[];for(const h of t)um(h)?o.push(h):r.set(h.event_id,new fe("MEGOLM_INVALID_EVENT",h));const c=nn(o),l=[];return await Promise.all(Array.from(c.values()).map(async h=>{const a=await this.getRoomKey(e,h.senderKey,h.sessionId,s,i);if(a)l.push(new hm(a,h.events,this.olmWorker,this.keyLoader));else for(const u of h.events)r.set(u.event_id,new fe("MEGOLM_NO_SESSION",u))})),new cm(e,l,r)}async getRoomKey(e,t,s,i,r){if(i){const l=i.find(h=>h.isForSession(e,t,s));if(l&&await l.checkBetterThanKeyInStorage(this.keyLoader,r))return l}const o=this.keyLoader.getCachedKey(e,t,s);if(o)return o;const c=await nc(e,t,s,r);if(c&&c.serializationKey)return c}writeRoomKey(e,t){return e.write(this.keyLoader,t)}roomKeysFromDeviceMessages(e,t){var i,r;const s=[];for(const o of e)((i=o.event)==null?void 0:i.type)!=="m.room_key"||((r=o.event.content)==null?void 0:r.algorithm)!==ft||t.wrap("room_key",c=>{const l=fm(o);l?(c.set("roomId",l.roomId),c.set("id",l.sessionId),s.push(l)):(c.logLevel=c.level.Warn,c.set("invalid",!0))},t.level.Detail);return s}roomKeyFromBackup(e,t,s){return rc(e,t,s)}dispose(){this.keyLoader.dispose()}}class wm extends Ba{constructor(e,t,s){super(s),this.pickleKey=t,this.olm=e}getCachedKey(e,t,s){const i=this.findCachedKeyIndex(e,t,s);if(i!==-1)return this._getByIndexAndMoveUp(i).key}async useKey(e,t){const s=await this.allocateOperation(e);try{return await t(s.session,this.pickleKey)}finally{this.releaseOperation(s)}}get running(){return this._entries.some(e=>e.refCount!==0)}dispose(){for(let e=0;e{this.resolveUnusedOperation=e})),this.operationBecomesUnusedPromise}findIndexForAllocation(e){let t=this.findIndexSameKey(e);return t===-1&&(this.size{const l=i===-1?void 0:c[i];return r.isBest===!0&&r.isForSameSession(e,t,s)&&(!l||r.isBetter(l))?o:i},-1)}findIndexSameKey(e){return this._entries.findIndex(t=>t.isForSameSession(e.roomId,e.senderKey,e.sessionId)&&t.isForKey(e))}findIndexSameSessionUnused(e){return this._entries.reduce((t,s,i,r)=>{const o=t===-1?void 0:r[t];return s.refCount===0&&s.isForSameSession(e.roomId,e.senderKey,e.sessionId)&&(!o||!s.isBetter(o))?i:t},-1)}findIndexOldestUnused(){for(let e=this._entries.length-1;e>=0;e-=1)if(this._entries[e].refCount===0)return e;return-1}}class vm{constructor(e,t){this.key=e,this.session=t,this.refCount=1}isForSameSession(e,t,s){return this.key.roomId===e&&this.key.senderKey===t&&this.key.sessionId===s}isBetter(e){return sc(this.session,e.session)}isForKey(e){return this.key.serializationKey===e.serializationKey&&this.key.serializationType===e.serializationType}dispose(){this.session.free(),this.session=void 0}get isBest(){return this.key.isBetter}}const bm="m.megolm_backup.v1.curve25519-aes-sha2";class Dn{constructor(e,t){this.encryption=e,this.decryption=t}static fromAuthData(e,t,s){const i=e.public_key,r=new s.PkDecryption,o=new s.PkEncryption;try{const c=r.init_with_private_key(t);if(c!==i)throw new Error(`Bad backup key, public key does not match. Calculated ${c} but expected ${i}`);o.set_recipient_key(c)}catch(c){throw r.free(),o.free(),c}return new Dn(o,r)}decryptRoomKey(e){const t=this.decryption.decrypt(e.ephemeral,e.mac,e.ciphertext);return JSON.parse(t)}encryptRoomKey(e,t){const s={algorithm:ft,sender_key:e.senderKey,sender_claimed_keys:{ed25519:e.claimedEd25519Key},forwarding_curve25519_key_chain:[],session_key:t};return this.encryption.encrypt(JSON.stringify(s))}dispose(){var e,t;(e=this.decryption)==null||e.free(),this.decryption=void 0,(t=this.encryption)==null||t.free(),this.encryption=void 0}}const Sm=200;class km{constructor(e,t){this.info=e,this.crypto=t}}class Im extends $t{constructor(e,t,s,i,r,o=1e4){super(),this.hsApi=e,this.olm=t,this.keyLoader=s,this.storage=i,this.platform=r,this.maxDelay=o,this._stopped=!1,this._needsNewKey=!1,this._hasBackedUpAllKeys=!1,this.backupConfigDeferred=new As,this.backupConfigDeferred=new As}get hasStopped(){return this._stopped}get error(){return this._error}get version(){var e,t;return(t=(e=this.backupConfigDeferred.value)==null?void 0:e.info)==null?void 0:t.version}get needsNewKey(){return this._needsNewKey}get hasBackedUpAllKeys(){return this._hasBackedUpAllKeys}get operationInProgress(){return this._operationInProgress}async getRoomKey(e,t,s){if(this.needsNewKey)return;const i=await this.backupConfigDeferred.promise;if(!i)return;const r=await this.hsApi.roomKeyForRoomAndSession(i.info.version,e,t,{log:s}).response();if(!r.session_data)return;const o=i.crypto.decryptRoomKey(r.session_data);if((o==null?void 0:o.algorithm)===ft)return rc(e,t,o);o!=null&&o.algorithm&&s.set("unknown algorithm",o.algorithm)}markAllForBackup(e){return e.inboundGroupSessions.markAllAsNotBackedUp()}async load(e,t){const s=await e.readSecret("m.megolm_backup.v1");return s?(this.privateKey=new Uint8Array(this.platform.encoding.base64.decode(s)),!0):(this.backupConfigDeferred.resolve(void 0),!1)}async start(e){await e.wrap("KeyBackup.start",async t=>{if(this.privateKey&&!this.backupInfoRequest){let s;try{this.backupInfoRequest=this.hsApi.roomKeysVersion(void 0,{log:t}),s=await this.backupInfoRequest.response()}catch(i){if(i.name==="AbortError"){t.set("aborted",!0);return}else throw i}finally{this.backupInfoRequest=void 0}if(s.algorithm===bm){const i=Dn.fromAuthData(s.auth_data,this.privateKey,this.olm);this.backupConfigDeferred.resolve(new km(s,i)),this.emit("change")}else this.backupConfigDeferred.resolve(void 0),t.log({l:"Unknown backup algorithm",algorithm:s.algorithm});this.privateKey=void 0}this.flush(t)})}flush(e){this._operationInProgress||e.wrapDetached("flush key backup",async t=>{if(this._needsNewKey){t.set("needsNewKey",this._needsNewKey);return}this._stopped=!1,this._error=void 0,this._hasBackedUpAllKeys=!1;const s=this._runFlushOperation(t);this._operationInProgress=s,this.emit("change");try{await s.result,this._hasBackedUpAllKeys=!0}catch(i){this._stopped=!0,i.name==="HomeServerError"&&(i.errcode==="M_WRONG_ROOM_KEYS_VERSION"||i.errcode==="M_NOT_FOUND")?(t.set("wrong_version",!0),this._needsNewKey=!0):(i.name!=="AbortError"||i.name==="StorageError"&&i.errcode==="AbortError")&&(this._error=i),t.catch(i)}this._operationInProgress=void 0,this.emit("change")})}_runFlushOperation(e){return new oa(async(t,s)=>{const i=await this.backupConfigDeferred.promise;if(!i)return;let r=0,o=0;for(;;){const c=this.platform.random()*this.maxDelay,l=this.platform.clock.createTimeout(c);t(l),await l.elapsed();const h=await this.storage.readTxn([J.inboundGroupSessions]);t(h),r=o+await h.inboundGroupSessions.countNonBackedUpSessions(),s(new vo(r,o));const a=(await h.inboundGroupSessions.getFirstNonBackedUpSessions(Sm)).map(g=>new ic(g));if(a.length===0){e.set("total",r);return}const u=await this.encodeKeysForBackup(a,i.crypto),p=this.hsApi.uploadRoomKeysToBackup(i.info.version,u,{log:e});t(p),await p.response(),await this.markKeysAsBackedUp(a,t),o+=a.length,s(new vo(r,o))}})}async encodeKeysForBackup(e,t){const s={rooms:{}},i=s.rooms;for(const r of e){let o=i[r.roomId];o||(o=i[r.roomId]={sessions:{}}),o.sessions[r.sessionId]=await this.encodeRoomKey(r,t)}return s}async markKeysAsBackedUp(e,t){const s=await this.storage.readWriteTxn([J.inboundGroupSessions]);t(s);try{await Promise.all(e.map(i=>s.inboundGroupSessions.markAsBackedUp(i.roomId,i.senderKey,i.sessionId)))}catch(i){throw s.abort(),i}await s.complete()}async encodeRoomKey(e,t){return await this.keyLoader.useKey(e,s=>{const i=s.first_known_index(),r=s.export_session(i);return{first_message_index:i,forwarded_count:0,is_verified:!1,session_data:t.encryptRoomKey(e,r)}})}dispose(){var e,t,s;(e=this.backupInfoRequest)==null||e.abort(),(s=(t=this.backupConfigDeferred.value)==null?void 0:t.crypto)==null||s.dispose()}}class vo{constructor(e,t){this.total=e,this.finished=t}}class Mm{constructor({pickleKey:e,olm:t,account:s,keyLoader:i,storage:r,now:o,ownDeviceId:c}){this._pickleKey=e,this._olm=t,this._account=s,this._keyLoader=i,this._storage=r,this._now=o,this._ownDeviceId=c}discardOutboundSession(e,t){t.outboundGroupSessions.remove(e)}async createRoomKeyMessage(e,t){let s=await t.outboundGroupSessions.get(e);if(s){const i=new this._olm.OutboundGroupSession;try{return i.unpickle(this._pickleKey,s.session),this._createRoomKeyMessage(i,e)}finally{i.free()}}}createWithheldMessage(e,t,s){return{algorithm:e.algorithm,code:t,reason:s,room_id:e.room_id,sender_key:this._account.identityKeys.curve25519,session_id:e.session_id}}async ensureOutboundSession(e,t){let s=new this._olm.OutboundGroupSession;try{const i=await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions,this._storage.storeNames.outboundGroupSessions]);let r;try{let o=await i.outboundGroupSessions.get(e);r=await this._readOrCreateSession(s,o,e,t,i),r&&this._writeSession(this._now(),s,e,i)}catch(o){throw i.abort(),o}return await i.complete(),r}finally{s.free()}}async _readOrCreateSession(e,t,s,i,r){if(t&&e.unpickle(this._pickleKey,t.session),!t||this._needsToRotate(e,t.createdAt,i)){t&&(e.free(),e=new this._olm.OutboundGroupSession),e.create();const o=this._createRoomKeyMessage(e,s);return await new pm(s,e,this._account.identityKeys).write(this._keyLoader,r),o}}_writeSession(e,t,s,i){i.outboundGroupSessions.set({roomId:s,session:t.pickle(this._pickleKey),createdAt:e})}async encrypt(e,t,s,i){let r=new this._olm.OutboundGroupSession;try{const o=await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions,this._storage.storeNames.outboundGroupSessions]);let c,l;try{let h=await o.outboundGroupSessions.get(e);c=await this._readOrCreateSession(r,h,e,i,o),l=this._encryptContent(e,r,t,s);const a=c?this._now():h.createdAt;this._writeSession(a,r,e,o)}catch(h){throw o.abort(),h}return await o.complete(),new Cm(l,c)}finally{r&&r.free()}}_needsToRotate(e,t,s){let i=6048e5;Number.isSafeInteger(s==null?void 0:s.rotation_period_ms)&&(i=s==null?void 0:s.rotation_period_ms);let r=100;if(Number.isSafeInteger(s==null?void 0:s.rotation_period_msgs)&&(r=s==null?void 0:s.rotation_period_msgs),this._now()>t+i||e.message_index()>=r)return!0}_encryptContent(e,t,s,i){const r=JSON.stringify({room_id:e,type:s,content:i}),o=t.encrypt(r);return{algorithm:ft,sender_key:this._account.identityKeys.curve25519,ciphertext:o,session_id:t.session_id(),device_id:this._ownDeviceId}}_createRoomKeyMessage(e,t){return{room_id:t,session_id:e.session_id(),session_key:e.session_key(),algorithm:ft,chain_index:e.message_index()}}}class Cm{constructor(e,t){this.content=e,this.roomKeyMessage=t}}const bo="m.room.encrypted",So="m.room.history_visibility",Em=60*1e3;class Rm{constructor({room:e,deviceTracker:t,olmEncryption:s,megolmEncryption:i,megolmDecryption:r,encryptionParams:o,storage:c,keyBackup:l,notifyMissingMegolmSession:h,clock:a}){this._room=e,this._deviceTracker=t,this._olmEncryption=s,this._megolmEncryption=i,this._megolmDecryption=r,this._encryptionParams=o,this._senderDeviceCache=new Map,this._storage=c,this._keyBackup=l,this._notifyMissingMegolmSession=h,this._clock=a,this._isFlushingRoomKeyShares=!1,this._lastKeyPreShareTime=null,this._keySharePromise=null,this._historyVisibility=void 0,this._disposed=!1}enableKeyBackup(e){this._keyBackup&&!!e||(this._keyBackup=e)}async restoreMissingSessionsFromBackup(e,t){const s=e.filter(a=>a.isEncrypted&&!a.isDecrypted&&a.event).map(a=>a.event),i=nn(s),r=Array.from(i.values()),o=await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]),c=await Promise.all(r.map(async a=>this._megolmDecryption.hasSession(this._room.id,a.senderKey,a.sessionId,o))),l=r.filter((a,u)=>!c[u]);if(l.length)for(var h=l.length-1;h>=0;h--){const a=l[h];await t.wrap("session",u=>this._requestMissingSessionFromBackup(a.senderKey,a.sessionId,u))}}notifyTimelineClosed(){this._senderDeviceCache=new Map}async writeSync(e,t,s,i){let r=await this._loadHistoryVisibilityIfNeeded(this._historyVisibility,s);const o=[],c=[];if(await Js(e,h=>{var a;if(h.state_key===""&&h.type===So){const u=(a=h==null?void 0:h.content)==null?void 0:a.history_visibility;if(u!==r)return i.wrap({l:"history_visibility changed",from:r,to:u},async p=>{r=u;const g=await this._deviceTracker.writeHistoryVisibility(this._room,r,s,p);o.push(...g.added),c.push(...g.removed)})}}),t.size){const h=await this._deviceTracker.writeMemberChanges(this._room,t,r,s);o.push(...h.added),c.push(...h.removed)}c.length&&(i.log({l:"discardOutboundSession",leftUsers:c}),this._megolmEncryption.discardOutboundSession(this._room.id,s));let l=!1;return o.length&&(l=await this._addShareRoomKeyOperationForMembers(o,s,i)),{shouldFlush:l,historyVisibility:r}}afterSync({historyVisibility:e}){this._historyVisibility=e}async _loadHistoryVisibilityIfNeeded(e,t=void 0){var s,i;if(!e){t||(t=await this._storage.readTxn([this._storage.storeNames.roomState]));const r=await t.roomState.get(this._room.id,So,"");if(r)return(i=(s=r.event)==null?void 0:s.content)==null?void 0:i.history_visibility}return e}async prepareDecryptAll(e,t,s,i){var l,h,a;const r=new Map,o=[];for(const u of e)u.redacted_because||((l=u.unsigned)==null?void 0:l.redacted_because)||(((h=u.content)==null?void 0:h.algorithm)!==ft&&r.set(u.event_id,new Error("Unsupported algorithm: "+((a=u.content)==null?void 0:a.algorithm))),o.push(u));const c=await this._megolmDecryption.prepareDecryptAll(this._room.id,o,t,i);return new Tm(c,r,s,this,e)}async _processDecryptionResults(e,t,s,i,r,o){const c=e.filter(h=>{const a=s.get(h.event_id);return(a==null?void 0:a.code)==="MEGOLM_NO_SESSION"});if(!c.length)return;const l=nn(c);i===ts.Sync&&await Promise.all(Array.from(l.values()).map(async h=>{const a=h.events.map(u=>u.event_id);return this._megolmDecryption.addMissingKeyEventIds(this._room.id,h.senderKey,h.sessionId,a,r)})),this._keyBackup&&o.wrapDetached("check key backup",async h=>{if(h.set("source",i),h.set("events",c.length),h.set("sessions",l.size),i===ts.Sync){if(await this._clock.createTimeout(1e4).elapsed(),this._disposed)return;const a=await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);await Promise.all(Array.from(l).map(async([u,p])=>{await this._megolmDecryption.hasSession(this._room.id,p.senderKey,p.sessionId,a)&&l.delete(u)}))}await Promise.all(Array.from(l.values()).map(a=>h.wrap("session",u=>this._requestMissingSessionFromBackup(a.senderKey,a.sessionId,u))))})}async _verifyDecryptionResults(e,t){await Promise.all(e.map(async s=>{let i=this._senderDeviceCache.get(s.senderCurve25519Key);i||(i=await this._deviceTracker.getDeviceByCurve25519Key(s.senderCurve25519Key,t),this._senderDeviceCache.set(s.senderCurve25519Key,i)),i&&s.setDevice(i)}))}async _fetchKeyAndVerifyDecryptionResults(e,t,s){const i=e.filter(r=>r.isVerificationUnknown);return i.length?s.wrap("fetch unverified senders",async r=>{const o=Array.from(i.reduce((a,u)=>a.add(u.encryptedEvent.sender),new Set));r.set("senders",o),await this._deviceTracker.devicesForUsers(o,t,r);const c=await this._storage.readTxn([this._storage.storeNames.deviceKeys]);await this._verifyDecryptionResults(i,c);const h=i.filter(a=>!a.isVerificationUnknown).reduce((a,u)=>(a.set(u.encryptedEvent.event_id,u),a),new Map);return new on(h,new Map,this)}):new on(new Map,new Map,this)}async _requestMissingSessionFromBackup(e,t,s){if(!this._keyBackup){s.set("enabled",!1),this._notifyMissingMegolmSession();return}s.set("id",t),s.set("senderKey",e);try{const i=await this._keyBackup.getRoomKey(this._room.id,t,s);if(i){if(i.senderKey!==e){s.set("wrong_sender_key",i.senderKey),s.logLevel=s.level.Warn;return}let r=!1,o;const c=await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]);try{r=await this._megolmDecryption.writeRoomKey(i,c),s.set("isBetter",r),r&&(o=i.eventIds)}catch(l){throw c.abort(),l}await c.complete(),r&&await s.wrap("retryDecryption",l=>this._room.notifyRoomKey(i,o||[],l))}}catch(i){i.name==="HomeServerError"&&i.errcode==="M_NOT_FOUND"?(s.error=i,s.logLevel=s.level.Error):s.set("not_found",!0)}}getEventIdsForMissingKey(e,t){return this._megolmDecryption.getEventIdsForMissingKey(this._room.id,e.senderKey,e.sessionId,t)}async ensureMessageKeyIsShared(e,t){var s;if(!(((s=this._lastKeyPreShareTime)==null?void 0:s.measure()){var r;const i=await this._megolmEncryption.ensureOutboundSession(this._room.id,this._encryptionParams);i&&((r=this._keyBackup)==null||r.flush(t),await t.wrap("share key",o=>this._shareNewRoomKey(i,e,o)))})(),await this._keySharePromise}finally{this._keySharePromise=null}}}async encrypt(e,t,s,i){var o;this._keySharePromise&&(i.set("waitForRunningKeyShare",!0),await this._keySharePromise);const r=await i.wrap("megolm encrypt",()=>this._megolmEncryption.encrypt(this._room.id,e,t,this._encryptionParams));return r.roomKeyMessage&&((o=this._keyBackup)==null||o.flush(i),await i.wrap("share key",c=>this._shareNewRoomKey(r.roomKeyMessage,s,c))),{type:bo,content:r.content}}needsToShareKeys(e){for(const t of e.values())if(t.hasJoined)return!0;return!1}async _shareNewRoomKey(e,t,s){this._historyVisibility=await this._loadHistoryVisibilityIfNeeded(this._historyVisibility),await this._deviceTracker.trackRoom(this._room,this._historyVisibility,s);const i=await this._deviceTracker.devicesForTrackedRoom(this._room.id,t,s),r=Array.from(i.reduce((l,h)=>l.add(h.user_id),new Set));let o=await this._storage.readWriteTxn([this._storage.storeNames.operations]),c;try{c=this._writeRoomKeyShareOperation(e,r,o)}catch(l){throw o.abort(),l}await this._processShareRoomKeyOperation(c,t,s)}async _addShareRoomKeyOperationForMembers(e,t,s){const i=await this._megolmEncryption.createRoomKeyMessage(this._room.id,t);return i?(s.log({l:"share key for new members",userIds:e,id:i.session_id,chain_index:i.chain_index}),this._writeRoomKeyShareOperation(i,e,t),!0):!1}async flushPendingRoomKeyShares(e,t,s){if(!this._isFlushingRoomKeyShares){this._isFlushingRoomKeyShares=!0;try{t||(t=await(await this._storage.readTxn([this._storage.storeNames.operations])).operations.getAllByTypeAndScope("share_room_key",this._room.id));for(const i of t)i.type==="share_room_key"&&await s.wrap("operation",r=>this._processShareRoomKeyOperation(i,e,r))}finally{this._isFlushingRoomKeyShares=!1}}}_writeRoomKeyShareOperation(e,t,s){const r={id:Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(),type:"share_room_key",scope:this._room.id,userIds:t,roomKeyMessage:e};return s.operations.add(r),r}async _processShareRoomKeyOperation(e,t,s){s.set("id",e.id),this._historyVisibility=await this._loadHistoryVisibilityIfNeeded(this._historyVisibility),await this._deviceTracker.trackRoom(this._room,this._historyVisibility,s);const i=await this._deviceTracker.devicesForRoomMembers(this._room.id,e.userIds,t,s),r=await s.wrap("olm encrypt",c=>this._olmEncryption.encrypt("m.room_key",e.roomKeyMessage,i,t,c)),o=i.filter(c=>!r.some(l=>l.device===c));await s.wrap("send",c=>this._sendMessagesToDevices(bo,r,t,c)),o.length&&await s.wrap("missingDevices",async c=>{c.set("devices",o.map(a=>a.device_id));const l=e.userIds.filter(a=>o.some(u=>u.user_id===a));c.set("unsentUserIds",l),e.userIds=l,await this._updateOperationsStore(a=>a.update(e));const h=this._megolmEncryption.createWithheldMessage(e.roomKeyMessage,"m.no_olm","OTKs exhausted");await this._sendSharedMessageToDevices("org.matrix.room_key.withheld",h,o,t,c)}),await this._updateOperationsStore(c=>c.remove(e.id))}async _updateOperationsStore(e){const t=await this._storage.readWriteTxn([this._storage.storeNames.operations]);try{e(t.operations)}catch(s){throw t.abort(),s}await t.complete()}async _sendSharedMessageToDevices(e,t,s,i,r){const o=ti(s,h=>h.user_id),c={messages:Array.from(o.entries()).reduce((h,[a,u])=>(h[a]=u.reduce((p,g)=>(p[g.device_id]=t,p),{}),h),{})},l=Pe();await i.sendToDevice(e,c,l,{log:r}).response()}async _sendMessagesToDevices(e,t,s,i){i.set("messages",t.length);const r=Fi(t),o=Pe();await s.sendToDevice(e,r,o,{log:i}).response()}filterUndecryptedEventEntriesForKeys(e,t){return e.filter(s=>{var i,r;if(s.isEncrypted&&!s.isDecrypted){const{event:o}=s;if(o){const c=(i=o.content)==null?void 0:i.sender_key,l=(r=o.content)==null?void 0:r.session_id;return t.some(h=>c===h.senderKey&&l===h.sessionId)}}return!1})}dispose(){this._disposed=!0}}class Tm{constructor(e,t,s,i,r){this._megolmDecryptionPreparation=e,this._extraErrors=t,this._source=s,this._roomEncryption=i,this._events=r}async decrypt(){return new Am(await this._megolmDecryptionPreparation.decrypt(),this._extraErrors,this._source,this._roomEncryption,this._events)}dispose(){this._megolmDecryptionPreparation.dispose()}}class Am{constructor(e,t,s,i,r){this._megolmDecryptionChanges=e,this._extraErrors=t,this._source=s,this._roomEncryption=i,this._events=r}async write(e,t){const{results:s,errors:i}=await this._megolmDecryptionChanges.write(e);return rn(this._extraErrors,i),await this._roomEncryption._processDecryptionResults(this._events,s,i,this._source,e,t),new on(s,i,this._roomEncryption)}}class on{constructor(e,t,s){this.results=e,this.errors=t,this._roomEncryption=s}applyToEntries(e,t=void 0){for(const s of e){const i=this.results.get(s.id);if(i)s.setDecryptionResult(i),t==null||t(s);else{const r=this.errors.get(s.id);r&&(s.setDecryptionError(r),t==null||t(s))}}}verifyKnownSenders(e){return this._roomEncryption._verifyDecryptionResults(Array.from(this.results.values()),e)}get hasUnverifiedSenders(){for(const e of this.results.values())if(e.isVerificationUnknown)return!0;return!1}fetchAndVerifyRemainingSenders(e,t){return this._roomEncryption._fetchKeyAndVerifyDecryptionResults(Array.from(this.results.values()),e,t)}}class xm{constructor(){this._map=new Map}async takeLock(e){let t=this._map.get(e);return t?await t.take():(t=new Ja,t.tryTake(),this._map.set(e,t)),t.released().then(()=>{Promise.resolve().then(()=>{t.isTaken||this._map.delete(e)})}),t}}function oc(n,e,t=!1){for(const[s,i]of Object.entries(e)){if(n[s]instanceof Object&&i){oc(n[s],i);continue}if(i!=null||!t){n[s]=i;continue}}return n}/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */var an=(n=>(n.Video="video",n.Audio="audio",n))(an||{});function is(n){return n==null?void 0:n.getAudioTracks()[0]}function xt(n){return n==null?void 0:n.getVideoTracks()[0]}function cn(n,e,t){return t.wrap("mute",s=>{s.set("cameraMuted",e.camera),s.set("microphoneMuted",e.microphone);const i=is(n.userMedia);if(i){const o=!e.microphone;s.set("microphone enabled",o),i.enabled=o}const r=xt(n.userMedia);if(r){const o=!e.camera;s.set("camera enabled",o),r.enabled=o}})}class si{constructor(e=!1,t=!1,s=!1,i=!1){this.isMicrophoneMuted=e,this.isCameraMuted=t,this.hasMicrophoneTrack=s,this.hasCameraTrack=i}updateTrackInfo(e){this.hasMicrophoneTrack=!!is(e),this.hasCameraTrack=!!xt(e)}get microphone(){return!this.hasMicrophoneTrack||this.isMicrophoneMuted}get camera(){return!this.hasCameraTrack||this.isCameraMuted}toggleCamera(){return new si(this.microphone,!this.camera,this.hasMicrophoneTrack,this.hasCameraTrack)}toggleMicrophone(){return new si(!this.microphone,this.camera,this.hasMicrophoneTrack,this.hasCameraTrack)}equals(e){return this.microphone===e.microphone&&this.camera===e.camera}}const fs="call",jr=3600*1e3;var q=(n=>(n.GroupCall="org.matrix.msc3401.call",n.GroupCallMember="org.matrix.msc3401.call.member",n.Invite="m.call.invite",n.Candidates="m.call.candidates",n.Answer="m.call.answer",n.Hangup="m.call.hangup",n.Reject="m.call.reject",n.SelectAnswer="m.call.select_answer",n.Negotiate="m.call.negotiate",n.SDPStreamMetadataChanged="m.call.sdp_stream_metadata_changed",n.SDPStreamMetadataChangedPrefix="org.matrix.call.sdp_stream_metadata_changed",n.Replaces="m.call.replaces",n.AssertedIdentity="m.call.asserted_identity",n.AssertedIdentityPrefix="org.matrix.call.asserted_identity",n))(q||{});const dt="org.matrix.msc3077.sdp_stream_metadata";var Zt=(n=>(n.Usermedia="m.usermedia",n.Screenshare="m.screenshare",n))(Zt||{}),ee=(n=>(n.UserHangup="user_hangup",n.LocalOfferFailed="local_offer_failed",n.NoUserMedia="no_user_media",n.UnknownDevices="unknown_devices",n.SendInvite="send_invite",n.CreateAnswer="create_answer",n.SendAnswer="send_answer",n.SetRemoteDescription="set_remote_description",n.SetLocalDescription="set_local_description",n.AnsweredElsewhere="answered_elsewhere",n.IceFailed="ice_failed",n.InviteTimeout="invite_timeout",n.Replaced="replaced",n.SignallingFailed="signalling_timeout",n.UserBusy="user_busy",n.Transfered="transferred",n.NewSession="new_session",n))(ee||{}),Ki=(n=>(n.Ring="m.ring",n.Prompt="m.prompt",n.Room="m.room",n))(Ki||{}),yr=(n=>(n.Video="m.video",n.Voice="m.voice",n))(yr||{}),ln=(n=>(n[n.InviteGlare=0]="InviteGlare",n[n.Handle=1]="Handle",n[n.Ignore=2]="Ignore",n))(ln||{});class Vm{constructor(e,t){this.userMedia=e,this.screenShare=t}}class Nm{constructor(e,t,s){this.callId=e,this.options=t,this.logItem=s,this._state=$.Fledgling,this.candidateSendQueue=[],this.remoteCandidateBuffer=new Map,this.disposables=new li,this.statePromiseMap=new Map,this._remoteTrackToStreamId=new Map,this._remoteStreams=new Map,this.makingOffer=!1,this.ignoreOffer=!1,this.sentEndOfCandidates=!1,this._remoteMuteSettings=new si,this.onIceConnectionStateChange=async(r,o)=>{var l,h;if(this._state===$.Ended)return;let c=!1;if(r=="connected")(l=this.iceDisconnectedTimeout)==null||l.abort(),this.iceDisconnectedTimeout=void 0,this.setState($.Connected,o);else if(r=="failed")c=!0,(h=this.iceDisconnectedTimeout)==null||h.abort(),this.iceDisconnectedTimeout=void 0,await this._hangup(ee.IceFailed,o);else if(r=="disconnected"){c=!0,this.iceDisconnectedTimeout=this.options.createTimeout(30*1e3);try{await this.iceDisconnectedTimeout.elapsed(),await this._hangup(ee.IceFailed,o)}catch(a){if(!(a instanceof rt))throw a}}if(c){const a=await this.peerConnection.getStats(),u={};a.forEach((p,g)=>{u[g]=p}),o.set("peerConnectionStats",u)}},s.log({l:"create PeerCall",id:e}),this._remoteMedia=new Vm,this.peerConnection=t.webRTC.createPeerConnection(this.options.forceTURN,[this.options.turnServer.get()],0),this.disposables.track(this.options.turnServer.subscribe(r=>{this.logItem.log({l:"updating turn server",turnServer:r}),this.peerConnection.setConfiguration({iceServers:[r]})}));const i=(r,o,c)=>{const l=a=>{this.options.errorBoundary.try(()=>o(a))};this.peerConnection.addEventListener(r,l);const h=()=>{this.peerConnection.removeEventListener(r,l)};this.disposables.track(h)};i("iceconnectionstatechange",async()=>{const r=this.peerConnection.iceConnectionState;await s.wrap({l:"onIceConnectionStateChange",status:r},async o=>{await this.onIceConnectionStateChange(r,o)})}),i("icecandidate",async r=>{await s.wrap("onLocalIceCandidate",async o=>{r.candidate&&await this.handleLocalIceCandidate(r.candidate,o)})}),i("icegatheringstatechange",async()=>{const r=this.peerConnection.iceGatheringState;await s.wrap({l:"onIceGatheringStateChange",status:r},async o=>{await this.handleIceGatheringState(r,o)})}),i("track",r=>{s.wrap("onRemoteTrack",o=>{this.onRemoteTrack(r.track,r.streams,o)})}),i("datachannel",r=>{s.wrap("onRemoteDataChannel",o=>{this._dataChannel=r.channel,this.options.emitUpdate(this,void 0,o)})}),i("negotiationneeded",()=>{var c,l;const r=this.peerConnection.signalingState,o=()=>s.wrap({l:"onNegotiationNeeded",signalingState:r},h=>this.handleNegotiation(h));this.responsePromiseChain=(l=(c=this.responsePromiseChain)==null?void 0:c.then(o))!=null?l:o(),this.responsePromiseChain.catch(h=>this.options.errorBoundary.reportError(h))})}get dataChannel(){return this._dataChannel}get state(){return this._state}get hangupReason(){return this._hangupReason}get remoteMedia(){return this._remoteMedia}get remoteMuteSettings(){return this._remoteMuteSettings}call(e,t,s){return s.wrap("call",async i=>{var r;this._state===$.Fledgling&&(i.set("signalingState",this.peerConnection.signalingState),this.direction=Ri.Outbound,this.setState($.CreateOffer,i),this.localMuteSettings=t,await this.updateLocalMedia(e,i),(r=this.localMedia)!=null&&r.dataChannelOptions&&(this._dataChannel=this.peerConnection.createDataChannel("channel",this.localMedia.dataChannelOptions)),await this.waitForState([$.InviteSent,$.CreateAnswer]))})}answer(e,t,s){return s.wrap("answer",async i=>{if(this._state!==$.Ringing)return;this.setState($.CreateAnswer,i),this.localMuteSettings=t,await this.updateLocalMedia(e,i);let r;try{r=await this.peerConnection.createAnswer()}catch(o){await i.wrap("Failed to create answer",c=>{c.catch(o),this.terminate(De.Local,ee.CreateAnswer,c)});return}try{await this.peerConnection.setLocalDescription(r),this.setState($.Connecting,i)}catch(o){await i.wrap("Error setting local description!",c=>{c.catch(o),this.terminate(De.Local,ee.SetLocalDescription,c)});return}try{await this.delay(200)}catch{return}await this.sendAnswer(i)})}setMedia(e,t){return t.wrap("setMedia",async s=>{s.set("userMedia_audio",!!is(e.userMedia)),s.set("userMedia_video",!!xt(e.userMedia)),s.set("screenShare_video",!!xt(e.screenShare)),s.set("datachannel",!!e.dataChannelOptions),await this.updateLocalMedia(e,s);const i={call_id:this.callId,version:1,[dt]:this.getSDPMetadata()};await this.sendSignallingMessage({type:q.SDPStreamMetadataChangedPrefix,content:i},s)})}setMuted(e,t){return t.wrap("setMuted",async s=>{if(this.localMuteSettings=e,s.set("cameraMuted",e.camera),s.set("microphoneMuted",e.microphone),this.localMedia){cn(this.localMedia,e,s);const i={call_id:this.callId,version:1,[dt]:this.getSDPMetadata()};await this.sendSignallingMessage({type:q.SDPStreamMetadataChangedPrefix,content:i},s)}})}hangup(e,t){return t.wrap("hangup",s=>this._hangup(e,s))}async _hangup(e,t){this._state===$.Ended||this._state===$.Ending||(this.setState($.Ending,t),await this.sendHangupWithCallId(this.callId,e,t),this.terminate(De.Local,e,t))}getMessageAction(e){const t=this.callId===e.content.call_id;return e.type===q.Invite&&!t?0:t?1:2}handleIncomingSignallingMessage(e,t,s){let i;return s.wrap({l:"receive signalling message",type:e.type,callId:e.content.call_id,payload:e.content},async r=>{var o;if(i=r,this.getMessageAction(e)!==1){r.set("wrongCallId",!0);return}switch(e.type){case q.Invite:await this.handleFirstInvite(e.content,t,r);break;case q.Answer:await this.handleAnswer(e.content,t,r);break;case q.Negotiate:await this.onNegotiateReceived(e.content,r);break;case q.Candidates:await this.handleRemoteIceCandidates(e.content,t,r);break;case q.SDPStreamMetadataChanged:case q.SDPStreamMetadataChangedPrefix:this.updateRemoteSDPStreamMetadata(e.content[dt],r);break;case q.Hangup:r.set("reason",e.content.reason),this.terminate(De.Remote,(o=e.content.reason)!=null?o:ee.UserHangup,r);break;default:r.log(`Unknown event type for call: ${e.type}`);break}}),i}sendHangupWithCallId(e,t,s){const i={call_id:e,version:1};return t&&(i.reason=t),this.sendSignallingMessage({type:q.Hangup,content:i},s)}async handleNegotiation(e){this.makingOffer=!0;try{try{await this.peerConnection.setLocalDescription()}catch(s){e.log("Error setting local description!").catch(s),this.terminate(De.Local,ee.SetLocalDescription,e);return}if(this.peerConnection.iceGatheringState==="gathering")try{await this.delay(200)}catch{return}if(this._state===$.Ended)return;const t=this.peerConnection.localDescription;if(e.set("includedCandidates",this.candidateSendQueue.length),this.candidateSendQueue=[],this._state===$.CreateOffer){const s={call_id:this.callId,offer:t,[dt]:this.getSDPMetadata(),version:1,lifetime:Si};await this.sendSignallingMessage({type:q.Invite,content:s},e),this.setState($.InviteSent,e)}else if(this._state===$.Connected||this._state===$.Connecting){const s={call_id:this.callId,description:t,[dt]:this.getSDPMetadata(),version:1,lifetime:Si};await this.sendSignallingMessage({type:q.Negotiate,content:s},e)}}finally{this.makingOffer=!1}if(this.sendCandidateQueue(e),this._state===$.InviteSent){const t=this.logItem.child("invite timeout");e.refDetached(t),await t.run(async s=>{try{await this.delay(Si)}catch{return}this._state===$.InviteSent&&await this._hangup(ee.InviteTimeout,s)})}}handleInviteGlare(e,t,s){if(e.type!==q.Invite)return{shouldReplace:!1};const{content:i}=e,r=i.call_id,o=this.callId>r;let c;return s.wrap("handling call glare",async l=>{c=l,o?(l.log("Glare detected: answering incoming call "+r+" and canceling outgoing call "),this._state!==$.Fledgling&&this._state!==$.CreateOffer&&await this.sendHangupWithCallId(this.callId,ee.Replaced,l),this.close(ee.Replaced,l),this.dispose()):(l.log("Glare detected: rejecting incoming call "+r+" and keeping outgoing call "),await this.sendHangupWithCallId(r,ee.Replaced,l))}),{shouldReplace:o,log:c}}handleHangupReceived(e,t){this.terminate(De.Remote,e.reason||ee.UserHangup,t)}async handleFirstInvite(e,t,s){this._state!==$.Fledgling||this.opponentPartyId!==void 0||await this.handleInvite(e,t,s)}async handleInvite(e,t,s){var r;this.opponentPartyId=t,this.direction=Ri.Inbound;const i=e[dt];i?this.updateRemoteSDPStreamMetadata(i,s):s.log("Call did not get any SDPStreamMetadata! Can not send/receive multiple streams");try{await this.peerConnection.setRemoteDescription(e.offer),await this.addBufferedIceCandidates(s)}catch(o){await s.wrap("Call failed to set remote description",async c=>(c.catch(o),this.terminate(De.Local,ee.SetRemoteDescription,c)));return}if(this.peerConnection.getReceivers().length===0){await s.wrap("Call no remote stream or no tracks after setting remote description!",async o=>this.terminate(De.Local,ee.SetRemoteDescription,o));return}this.setState($.Ringing,s);try{await this.delay((r=e.lifetime)!=null?r:Si)}catch{return}this._state===$.Ringing&&(s.log("Invite has expired. Hanging up."),this.hangupParty=De.Remote,this.setState($.Ended,s),this.peerConnection.signalingState!="closed"&&this.peerConnection.close())}async handleAnswer(e,t,s){if(this._state===$.Ended){s.log("Ignoring answer because call has ended");return}if(this.opponentPartyId!==void 0){s.log(`Ignoring answer: we already have an answer/reject from ${this.opponentPartyId}`);return}this.opponentPartyId=t,await this.addBufferedIceCandidates(s),this.setState($.Connecting,s);const i=e[dt];i?this.updateRemoteSDPStreamMetadata(i,s):s.log("Did not get any SDPStreamMetadata! Can not send/receive multiple streams");try{await this.peerConnection.setRemoteDescription(e.answer)}catch(r){await s.wrap("Failed to set remote description",o=>{o.catch(r),this.terminate(De.Local,ee.SetRemoteDescription,o)});return}}async handleIceGatheringState(e,t){if(e==="complete"&&!this.sentEndOfCandidates){const s={candidate:""};await this.queueCandidate(s,t),this.sentEndOfCandidates=!0}}async handleLocalIceCandidate(e,t){t.set("sdpMid",e.sdpMid),t.set("candidate",e.candidate),this._state!==$.Ended&&(e.candidate!==""||!this.sentEndOfCandidates)&&(await this.queueCandidate(e,t),e.candidate===""&&(this.sentEndOfCandidates=!0))}async handleRemoteIceCandidates(e,t,s){if(this.state===$.Ended){s.log("Ignoring remote ICE candidate because call has ended");return}const i=e.candidates;if(!i){s.log("Ignoring candidates event with no candidates!");return}const r=e.version===0?null:t||null;if(this.opponentPartyId===void 0){s.log(`Buffering ${i.length} candidates until we pick an opponent`);const o=this.remoteCandidateBuffer.get(r)||[];o.push(...i),this.remoteCandidateBuffer.set(r,o);return}if(this.opponentPartyId!==t){s.log(`Ignoring candidates from party ID ${t}: we have chosen party ID ${this.opponentPartyId}`);return}await this.addIceCandidates(i,s)}async onNegotiateReceived(e,t){const s=e.description;if(!s||!s.sdp||!s.type){t.log("Ignoring invalid m.call.negotiate event");return}const i=this.direction===Ri.Inbound,r=s.type==="offer"&&(this.makingOffer||this.peerConnection.signalingState!=="stable");if(this.ignoreOffer=!i&&r,this.ignoreOffer){t.log("Ignoring colliding negotiate event because we're impolite");return}const o=e[dt];o?this.updateRemoteSDPStreamMetadata(o,t):t.log("Received negotiation event without SDPStreamMetadata!");try{if(await this.peerConnection.setRemoteDescription(s),s.type==="offer"){await this.peerConnection.setLocalDescription();const c={call_id:this.callId,description:this.peerConnection.localDescription,[dt]:this.getSDPMetadata(),version:1,lifetime:Si};await this.sendSignallingMessage({type:q.Negotiate,content:c},t)}}catch(c){t.log("Failed to complete negotiation").catch(c)}}async sendAnswer(e){const t=this.peerConnection.localDescription,s={call_id:this.callId,version:1,answer:{sdp:t.sdp,type:t.type},[dt]:this.getSDPMetadata()};e.log(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in answer`),this.candidateSendQueue=[];try{await this.sendSignallingMessage({type:q.Answer,content:s},e)}catch(i){throw this.terminate(De.Local,ee.SendAnswer,e),i}this.sendCandidateQueue(e)}async queueCandidate(e,t){var i;if(this.candidateSendQueue.push(e),this._state===$.Ringing)return;this.flushCandidatesLog=(i=this.flushCandidatesLog)!=null?i:this.logItem.child("flush candidate queue"),t.refDetached(this.flushCandidatesLog);const{flushCandidatesLog:s}=this;try{await this.delay(this.direction===Ri.Inbound?500:2e3)}catch{return}this.sendCandidateQueue(s),this.flushCandidatesLog=void 0}async sendCandidateQueue(e){if(this.candidateSendQueue.length===0||this._state===$.Ended)return;const t=this.candidateSendQueue;return this.candidateSendQueue=[],e.wrap({l:"send candidates",size:t.length},async s=>{try{await this.sendSignallingMessage({type:q.Candidates,content:{call_id:this.callId,version:1,candidates:t}},s),await this.sendCandidateQueue(s)}catch(i){s.catch(i),this.terminate(De.Local,ee.SignallingFailed,s)}})}updateRemoteSDPStreamMetadata(e,t){this.remoteSDPStreamMetadata=oc(this.remoteSDPStreamMetadata||{},e,!0),this.updateRemoteMedia(t)}async addBufferedIceCandidates(e){if(this.remoteCandidateBuffer&&this.opponentPartyId){const t=this.remoteCandidateBuffer.get(this.opponentPartyId);t&&(e.log(`Adding ${t.length} buffered candidates for opponent ${this.opponentPartyId}`),await this.addIceCandidates(t,e)),this.remoteCandidateBuffer=void 0}}async addIceCandidates(e,t){for(const s of e){let i;(s.sdpMid===null||s.sdpMid===void 0)&&(s.sdpMLineIndex===null||s.sdpMLineIndex===void 0)?i=t.log("Got remote end-of-ICE candidates"):i=t.log(`Adding remote ICE ${s.sdpMid} candidate: ${s.candidate}`);try{await this.peerConnection.addIceCandidate(s)}catch(r){this.ignoreOffer||i.catch(r)}}}setState(e,t){if(e!==this._state){t.log({l:"change state",status:e,oldState:this._state}),this._state,this._state=e;let s=this.statePromiseMap.get(e);s&&(s.resolve(),this.statePromiseMap.delete(e)),this.options.emitUpdate(this,void 0,t)}}waitForState(e){return Promise.race(e.map(t=>{let s=this.statePromiseMap.get(t);if(!s){let i;const r=new Promise(o=>{i=o});s={resolve:i,promise:r},this.statePromiseMap.set(t,s)}return s.promise}))}terminate(e,t,s){this._state!==$.Ended&&(this.hangupParty=e,this._hangupReason=t,this.setState($.Ended,s),this.localMedia=void 0,this.peerConnection&&this.peerConnection.signalingState!=="closed"&&this.peerConnection.close())}getSDPMetadata(){var t,s,i,r,o,c;const e={};if((t=this.localMedia)!=null&&t.userMedia){const l=this.localMedia.userMedia.id;e[l]={purpose:Zt.Usermedia,audio_muted:(i=(s=this.localMuteSettings)==null?void 0:s.microphone)!=null?i:!1,video_muted:(o=(r=this.localMuteSettings)==null?void 0:r.camera)!=null?o:!1}}if((c=this.localMedia)!=null&&c.screenShare){const l=this.localMedia.screenShare.id;e[l]={purpose:Zt.Screenshare}}return e}findReceiverForStream(e,t){return this.peerConnection.getReceivers().find(s=>s.track.kind===e&&this._remoteTrackToStreamId.get(s.track.id)===t)}findTransceiverForTrack(e){return this.peerConnection.getTransceivers().find(t=>{var s;return((s=t.sender.track)==null?void 0:s.id)===e.id})}onRemoteTrack(e,t,s){if(s.set("kind",e.kind),s.set("id",e.id),s.set("streams",t.map(r=>r.id)),t.length===0){s.log({l:`ignoring ${e.kind} streamless track`,id:e.id});return}const i=t[0];if(this._remoteTrackToStreamId.set(e.id,i.id),!this._remoteStreams.has(i.id)){const r=c=>{this.logItem.wrap({l:"removetrack",id:c.track.id},l=>{const h=this._remoteTrackToStreamId.get(c.track.id);if(h){this._remoteTrackToStreamId.delete(c.track.id);const a=this._remoteStreams.get(h);a&&a.stream.getTracks().length===0&&(this.disposables.disposeTracked(o),this._remoteStreams.delete(i.id),this.updateRemoteMedia(l))}})};i.addEventListener("removetrack",r);const o=()=>{i.removeEventListener("removetrack",r)};this.disposables.track(o),this._remoteStreams.set(i.id,{disposeListener:o,stream:i})}this.updateRemoteMedia(s)}updateRemoteMedia(e){e.wrap("reevaluating remote media",t=>{var s,i;if(this._remoteMedia.userMedia=void 0,this._remoteMedia.screenShare=void 0,this.remoteSDPStreamMetadata)for(const r of this._remoteStreams.values()){const{stream:o}=r,c=this.remoteSDPStreamMetadata[o.id];if(c)if(c.purpose===Zt.Usermedia){this._remoteMedia.userMedia=o;const l=this.findReceiverForStream(an.Audio,o.id);l&&(l.track.enabled=!c.audio_muted);const h=this.findReceiverForStream(an.Video,o.id);h&&(h.track.enabled=!c.video_muted),this._remoteMuteSettings=new si((s=c.audio_muted)!=null?s:!1,(i=c.video_muted)!=null?i:!1,!!(l!=null&&l.track),!!(h!=null&&h.track)),t.log({l:"setting userMedia",micMuted:this._remoteMuteSettings.microphone,cameraMuted:this._remoteMuteSettings.camera})}else c.purpose===Zt.Screenshare&&(this._remoteMedia.screenShare=o,t.log("setting screenShare"));else t.log({l:"no metadata yet for stream, ignoring for now",id:o.id})}this.options.emitUpdate(this,void 0,t)})}updateLocalMedia(e,t){return t.wrap("updateLocalMedia",async s=>{var o,c;const i=this.peerConnection.getSenders(),r=async(l,h,a)=>{const u=async(p,g)=>{const f=i.find(M=>M.track===p),v=l!=null?l:h;if(v!==h&&(p&&(v.removeTrack(p),p.stop()),g&&v.addTrack(g)),g&&f)try{await s.wrap(`attempting to replace ${a} ${g.kind} track`,M=>f.replaceTrack(g));return}catch{}f&&s.wrap(`removing ${a} ${f.track.kind} track`,M=>{this.peerConnection.removeTrack(f)}),g&&s.wrap(`adding ${a} ${g.kind} track`,M=>{const R=this.peerConnection.addTrack(g,v);this.options.webRTC.prepareSenderForPurpose(this.peerConnection,R,a)})};!l&&!h||(await u(is(l),is(h)),await u(xt(l),xt(h)))};await r((o=this.localMedia)==null?void 0:o.userMedia,e==null?void 0:e.userMedia,Zt.Usermedia),await r((c=this.localMedia)==null?void 0:c.screenShare,e==null?void 0:e.screenShare,Zt.Screenshare),this.localMedia||(this.localMedia=e)})}async delay(e){const t=this.disposables.track(this.options.createTimeout(e));try{await t.elapsed()}finally{this.disposables.untrack(t)}}sendSignallingMessage(e,t){return t.wrap({l:"send",id:e.type},async s=>this.options.sendSignallingMessage(e,s))}dispose(){var e;this.disposables.dispose(),(e=this.iceDisconnectedTimeout)==null||e.abort(),this.peerConnection.close(),this.options.emitUpdate=(t,s,i)=>{i.log("emitting update from PeerCall after disposal",this.logItem.level.Error),console.trace("emitting update from PeerCall after disposal")}}close(e,t){e===void 0&&(e=ee.UserHangup),this.terminate(De.Local,e,t)}}var De=(n=>(n.Local="local",n.Remote="remote",n))(De||{}),$=(n=>(n.Fledgling="fledgling",n.CreateOffer="create_offer",n.InviteSent="invite_sent",n.CreateAnswer="create_answer",n.Connecting="connecting",n.Connected="connected",n.Ringing="ringing",n.Ending="ending",n.Ended="ended",n))($||{}),Ri=(n=>(n.Inbound="inbound",n.Outbound="outbound",n))(Ri||{});const Si=6e4;function Dm(n){return n===q.Invite||n===q.Candidates||n===q.Answer||n===q.Hangup||n===q.SDPStreamMetadataChanged||n===q.SDPStreamMetadataChangedPrefix||n===q.Negotiate}class ac{constructor(e){this.errorCallback=e}try(e,t){try{let s=e();return s instanceof Promise&&(s=s.catch(i=>(this._error=i,this.reportError(i),t))),s}catch(s){return this._error=s,this.reportError(s),t}}reportError(e){try{this.errorCallback(e)}catch(t){console.error("error in ErrorBoundary callback",t)}}get error(){return this._error}}const Um=[ee.UserHangup,ee.AnsweredElsewhere,ee.Replaced,ee.UserBusy,ee.Transfered,ee.NewSession];class Om{constructor(e,t,s,i){this.localMedia=e,this.localMuteSettings=t,this.turnServer=s,this.logItem=i,this.retryCount=0,this.queuedSignallingMessages=[],this.outboundSeqCounter=0}get canDequeueNextSignallingMessage(){if(this.queuedSignallingMessages.length===0)return!1;const t=this.queuedSignallingMessages[0].content.seq;return this.lastIgnoredSeqNr!==void 0&&t===this.lastIgnoredSeqNr+1?!0:this.lastProcessedSeqNr===void 0?t===0:t<=this.lastProcessedSeqNr+1}dispose(){var e;(e=this.peerCall)==null||e.dispose(),this.localMedia.dispose(),this.logItem.finish()}}class Pm{constructor(e,t,s,i){this.member=e,this.callDeviceMembership=t,this.options=s,this.errorBoundary=new ac(r=>{this.options.emitUpdate(this,"error"),this.connection&&this.connection.logItem.log("error at boundary").catch(r)}),this.emitUpdateFromPeerCall=async(r,o,c)=>{const l=this.connection;if(r.state===$.Ringing)l.logItem.wrap("ringing, answer peercall",h=>(c.refDetached(h),r.answer(l.localMedia,l.localMuteSettings,h)));else if(r.state===$.Ended){const h=r.hangupReason;if(r.dispose(),l.peerCall=void 0,h&&!Um.includes(h)){l.retryCount+=1;const{retryCount:a}=l;await l.logItem.wrap({l:"retry connection",retryCount:a},async u=>{if(c.refDetached(u),a<=3)await this.callIfNeeded(u);else{const p=await this.disconnect(!1);p&&u.refDetached(p)}})}}this.options.emitUpdate(this,o)},this.sendSignallingMessage=async(r,o)=>{const c=r;c.content.seq=this.connection.outboundSeqCounter++,c.content.conf_id=this.options.confId,c.content.device_id=this.options.ownDeviceId,c.content.party_id=this.options.ownDeviceId,c.content.sender_session_id=this.options.sessionId,c.content.dest_session_id=this.sessionId;let l,h=r.type;const a=await this.options.encryptDeviceMessage(this.member.userId,this.deviceId,c,o);a?(l=Fi(a),h="m.room.encrypted"):l=Fi([{content:c.content,device:this}]),o.set("payload",c.content),await this.options.hsApi.sendToDevice(h,l,Pe(),{log:o}).response()},this._renewExpireTimeout(i)}get error(){return this.errorBoundary.error}get usesFoci(){const e=this.callDeviceMembership["m.foci.active"];return Array.isArray(e)&&e.length>0}_renewExpireTimeout(e){var i;(i=this.expireTimeout)==null||i.dispose(),this.expireTimeout=void 0;const t=Rr(this.callDeviceMembership);if(typeof t!="number")return;const s=Math.max(0,t-this.options.clock.now());e==null||e.set("expiresIn",s),this.expireTimeout=this.options.clock.createTimeout(s+10),this.expireTimeout.elapsed().then(()=>{this.options.emitUpdate(this,"isExpired")},r=>{})}get logItem(){var e;return(e=this.connection)==null?void 0:e.logItem}get remoteMedia(){var e,t;return(t=(e=this.connection)==null?void 0:e.peerCall)==null?void 0:t.remoteMedia}get isExpired(){return!this.isConnected&&hn(this.callDeviceMembership,this.options.clock.now())}get remoteMuteSettings(){var e,t;return(t=(e=this.connection)==null?void 0:e.peerCall)==null?void 0:t.remoteMuteSettings}get isConnected(){var e,t;return((t=(e=this.connection)==null?void 0:e.peerCall)==null?void 0:t.state)===$.Connected}get userId(){return this.member.userId}get deviceId(){return this.callDeviceMembership.device_id}get user_id(){return this.userId}get device_id(){return this.deviceId}get sessionId(){return this.callDeviceMembership.session_id}get dataChannel(){var e,t;return(t=(e=this.connection)==null?void 0:e.peerCall)==null?void 0:t.dataChannel}connect(e,t,s,i){return this.errorBoundary.try(async()=>{if(this.connection)return;const r=new Om(e.clone(),t,s,i);this.connection=r;let o;return await r.logItem.wrap("connect",async c=>{o=c,await this.callIfNeeded(c)}),o})}callIfNeeded(e){return e.wrap("callIfNeeded",async t=>{let s;if(this.member.userId===this.options.ownUserId?s=this.deviceId>this.options.ownDeviceId:s=this.member.userId>this.options.ownUserId,s){const i=this.connection;i.peerCall=this._createPeerCall(Ir("c")),await i.peerCall.call(i.localMedia,i.localMuteSettings,t)}else t.set("wait_for_invite",!0)})}disconnect(e){return this.errorBoundary.try(async()=>{const{connection:t}=this;if(!t)return;let s;return await t.logItem.wrap("disconnect",async i=>{s=i,e&&t.peerCall&&await t.peerCall.hangup(ee.UserHangup,i)}),t.dispose(),this.connection=void 0,s})}updateCallInfo(e,t){this.errorBoundary.try(()=>{this.callDeviceMembership=e,this._renewExpireTimeout(t),this.connection&&this.connection.logItem.refDetached(t)})}updateRoomMember(e){this.member=e,this.options.emitUpdate(this)}handleDeviceMessage(e,t){this.errorBoundary.try(()=>{var s;t.wrap({l:"Member.handleDeviceMessage",type:e.type,seq:(s=e.content)==null?void 0:s.seq},i=>{const{connection:r}=this;if(r){const o=e.content.dest_session_id;if(o!==this.options.sessionId){const h=r.logItem.log({l:"ignoring to_device event with wrong session_id",destSessionId:o,type:e.type});i.refDetached(h);return}if(r.peerCall&&r.peerCall.getMessageAction(e)===ln.InviteGlare){const{shouldReplace:a,log:u}=r.peerCall.handleInviteGlare(e,this.deviceId,r.logItem);u&&u.refDetached(u),a&&(r.peerCall.dispose(),r.peerCall=void 0)}e.type===q.Invite&&!r.peerCall&&(r.peerCall=this._createPeerCall(e.content.call_id));const c=Nt(r.queuedSignallingMessages,e,(h,a)=>h.content.seq-a.content.seq);r.queuedSignallingMessages.splice(c,0,e);let l=!1;r.peerCall&&(l=this.dequeueSignallingMessages(r,r.peerCall,e,i)),l||i.refDetached(r.logItem.log({l:"queued message",type:e.type,seq:e.content.seq,idx:c}))}else t.log({l:"member not connected",userId:this.userId,deviceId:this.deviceId})})})}dequeueSignallingMessages(e,t,s,i){let r=!1;for(;e.canDequeueNextSignallingMessage;){const o=e.queuedSignallingMessages.shift(),c=o===s;r=r||c,i.wrap(c?"process message":"dequeue message",l=>{var u;const h=(u=o.content)==null?void 0:u.seq;if(l.set("seq",h),l.set("type",o.type),t.getMessageAction(o)===ln.Handle){const p=t.handleIncomingSignallingMessage(o,this.deviceId,e.logItem);l.refDetached(p),e.lastProcessedSeqNr=h}else l.set("ignored",!0),e.lastIgnoredSeqNr=h})}return r}async setMedia(e,t){return this.errorBoundary.try(async()=>{var i;const{connection:s}=this;s&&(s.localMedia=e.replaceClone(s.localMedia,t),await((i=s.peerCall)==null?void 0:i.setMedia(s.localMedia,s.logItem)))})}async setMuted(e){return this.errorBoundary.try(async()=>{var s;const{connection:t}=this;t&&(t.localMuteSettings=e,await((s=t.peerCall)==null?void 0:s.setMuted(e,t.logItem)))})}_createPeerCall(e){const t=this.connection;return new Nm(e,Object.assign({},this.options,{errorBoundary:this.errorBoundary,emitUpdate:this.emitUpdateFromPeerCall,sendSignallingMessage:this.sendSignallingMessage,turnServer:t.turnServer}),t.logItem)}dispose(){var e,t;(e=this.connection)==null||e.dispose(),this.connection=void 0,(t=this.expireTimeout)==null||t.dispose(),this.expireTimeout=void 0,this.options.emitUpdate=()=>{}}}function Rr(n){const e=n.expires_ts;if(Number.isSafeInteger(e))return e}function hn(n,e,t=0){const s=Rr(n);return typeof s=="number"?s+t<=e:!0}function Ws(n,e){return JSON.stringify(n)+","+JSON.stringify(e)}function ko(n,e){return n.startsWith(JSON.stringify(e)+",")}function Fm(n){return JSON.parse(`[${n}]`)[1]}class Lm{constructor(e,t,s,i,r,o){this.logItem=e,this.membersLogItem=t,this.localMedia=s,this.localPreviewMedia=i,this.localMuteSettings=r,this.turnServer=o}dispose(){var e;this.localMedia.dispose(),this.localPreviewMedia.dispose(),this.logItem.finish(),(e=this.renewMembershipTimeout)==null||e.dispose()}}class qr extends $t{constructor(e,t,s,i,r,o,c){super(),this.id=e,this.isLoadedFromStorage=t,this.startTime=i,this.callContent=r,this.roomId=o,this.options=c,this._members=new Dt,this.bufferedDeviceMessages=new Map,this.errorBoundary=new ac(l=>{this.emitChange(),this.joinedData&&(this.joinedData.logItem.log("error at boundary").catch(l),console.error(l))}),this._state=s?"fledgling":"created",this._memberOptions=Object.assign({},c,{confId:this.id,emitUpdate:l=>{var a;const h=Ws(l.userId,l.deviceId);if(l.isExpired&&!l.isConnected){const u=this.options.logger.log({l:"removing expired member from call",memberKey:h,callId:this.id});(a=l.logItem)==null||a.refDetached(u),l.dispose(),this._members.remove(h)}else this._members.update(h)},encryptDeviceMessage:(l,h,a,u)=>this.options.encryptDeviceMessage(this.roomId,l,h,a,u)})}get localMedia(){var e;return(e=this.joinedData)==null?void 0:e.localMedia}get localPreviewMedia(){var e;return(e=this.joinedData)==null?void 0:e.localPreviewMedia}get members(){return this._members}get isTerminated(){var e;return!!((e=this.callContent)!=null&&e["m.terminated"])}get usesFoci(){for(const e of this._members.values())if(e.usesFoci)return!0;return!1}get duration(){if(typeof this.startTime=="number")return this.options.clock.now()-this.startTime}get isRinging(){return this._state==="created"&&this.intent==="m.ring"&&!this.isMember(this.options.ownUserId)}get name(){var e;return(e=this.callContent)==null?void 0:e["m.name"]}get intent(){var e;return(e=this.callContent)==null?void 0:e["m.intent"]}get type(){var e;return(e=this.callContent)==null?void 0:e["m.type"]}get logItem(){var e;return(e=this.joinedData)==null?void 0:e.logItem}get error(){return this.errorBoundary.error}join(e,t){return this.options.logger.wrapOrRun(t,"Call.join",async s=>{if(this._state!=="created"||this.joinedData||this.usesFoci){e.dispose();return}const i=this.options.logger.child({l:"Call.connection",t:fs,id:this.id,ownSessionId:this.options.sessionId}),r=await this.options.turnServerSource.getSettings(i),o=i.child("member connections"),c=new si;c.updateTrackInfo(e.userMedia);const l=e.asPreview(),h=new Lm(i,o,e,l,c,r);this.joinedData=h,await h.logItem.wrap("join",async a=>{s.refDetached(a),this._state="joining",this.emitChange(),await a.wrap("update member state",async u=>{const p=await this._createMemberPayload(!0);u.set("payload",p),await this.options.hsApi.sendState(this.roomId,q.GroupCallMember,this.options.ownUserId,p,{log:u}).response(),this.emitChange()});for(const u of this._members.values())this.connectToMember(u,h,a)})})}async setMedia(e){var t;if((this._state==="joining"||this._state==="joined")&&this.joinedData){const s=this.joinedData.localMedia;this.joinedData.localMedia=e,(t=this.joinedData.localPreviewMedia)==null||t.dispose(),this.joinedData.localPreviewMedia=e.asPreview(),this.joinedData.localMuteSettings.updateTrackInfo(e.userMedia),this.emitChange(),await Promise.all(Array.from(this._members.values()).map(i=>i.setMedia(e,s))),s==null||s.dispose()}}async setMuted(e){const{joinedData:t}=this;if(!t)return;const s=t.localMuteSettings;e.updateTrackInfo(t.localMedia.userMedia),t.localMuteSettings=e,s.equals(e)||(this.localPreviewMedia&&cn(this.localPreviewMedia,e,this.joinedData.logItem),this.localMedia&&cn(this.localMedia,e,this.joinedData.logItem),await Promise.all(Array.from(this._members.values()).map(i=>i.setMuted(t.localMuteSettings))),this.emitChange())}get muteSettings(){var e;return(e=this.joinedData)==null?void 0:e.localMuteSettings}get hasJoined(){return this._state==="joining"||this._state==="joined"}async leave(e){await this.options.logger.wrapOrRun(e,"Call.leave",async t=>{var i;const{joinedData:s}=this;if(!!s)try{(i=s.renewMembershipTimeout)==null||i.dispose(),s.renewMembershipTimeout=void 0;const r=await this._createMemberPayload(!1);r?(await this.options.hsApi.sendState(this.roomId,q.GroupCallMember,this.options.ownUserId,r,{log:t}).response(),(this.intent===Ki.Ring||this.intent===Ki.Prompt)&&this._members.size===0&&await this.terminate(t)):t.set("already_left",!0)}finally{if(!this.disconnect(t))throw this.errorBoundary.error}})}terminate(e){return this.options.logger.wrapOrRun(e,{l:"terminate call",t:fs},async t=>{if(this._state==="fledgling")return;await this.options.hsApi.sendState(this.roomId,q.GroupCall,this.id,Object.assign({},this.callContent,{"m.terminated":!0}),{log:t}).response()})}create(e,t){return t.wrap({l:"create call",t:fs},async s=>{if(this._state!=="fledgling")return;this._state="creating",this.emitChange(),this.callContent=Object.assign({"m.type":e},this.callContent),await this.options.hsApi.sendState(this.roomId,q.GroupCall,this.id,this.callContent,{log:s}).response(),this._state="created",this.emitChange()})}updateCallEvent(e,t){this.errorBoundary.try(()=>{t.wrap({l:"update call",t:fs,id:this.id},s=>{typeof this.startTime!="number"&&(this.startTime=e.origin_server_ts),this.callContent=e.content,this._state==="creating"&&(this._state="created"),s.set("status",this._state),this.emitChange()})})}updateRoomMembers(e){this.errorBoundary.try(()=>{for(const t of e.values()){const{member:s}=t;for(const i of this._members.values())i.userId===s.userId&&i.updateRoomMember(s)}})}updateMembership(e,t,s,i){this.errorBoundary.try(async()=>{await i.wrap({l:"update call membership",t:fs,id:this.id,userId:e},async r=>{const o=this.options.clock.now(),c=s["m.devices"],l=this.getDeviceIdsForUserId(e);for(const a of c){const u=a.device_id,p=Ws(e,u);e===this.options.ownUserId&&u===this.options.ownDeviceId?r.wrap("update own membership",g=>{this.hasJoined&&(this.joinedData&&this.joinedData.logItem.refDetached(g),this._setupRenewMembershipTimeout(a,g)),this._state==="joining"&&(g.set("joined",!0),this._state="joined",this.emitChange())}):await r.wrap({l:"update device membership",id:p,sessionId:a.session_id},async g=>{if(hn(a,o)){g.set("expired",!0);const M=this._members.get(p);M?(M.dispose(),this._members.remove(p),g.set("removed",!0)):g.discard();return}let f=this._members.get(p);const v=f&&f.sessionId!==a.session_id;if(f&&!v)g.set("update",!0),f.updateCallInfo(a,g);else{if(f&&v){g.set("removedSessionId",f.sessionId);const M=await f.disconnect(!1);M&&g.refDetached(M),f.dispose(),this._members.remove(p),f=void 0}g.set("add",!0),f=new Pm(t,a,this._memberOptions,g),this._members.add(p,f),this.joinedData&&this.connectToMember(f,this.joinedData,g)}this.flushPendingIncomingDeviceMessages(f,g)})}const h=new Set(c.map(a=>a.device_id));for(const a of l)h.has(a)||this.removeMemberDevice(e,a,r);e===this.options.ownUserId&&!h.has(this.options.ownDeviceId)&&this.removeOwnDevice(r)})})}removeMembership(e,t){this.errorBoundary.try(()=>{const s=this.getDeviceIdsForUserId(e);t.wrap({l:"remove call member",t:fs,id:this.id,userId:e},i=>{for(const r of s)this.removeMemberDevice(e,r,i);e===this.options.ownUserId&&this.removeOwnDevice(i)})})}flushPendingIncomingDeviceMessages(e,t){const s=Ws(e.userId,e.deviceId),i=this.bufferedDeviceMessages.get(s);if(i){for(const r of i)r.content.sender_session_id===e.sessionId&&(e.handleDeviceMessage(r,t),i.delete(r));i.size===0&&this.bufferedDeviceMessages.delete(s)}}getDeviceIdsForUserId(e){return Array.from(this._members.keys()).filter(t=>ko(t,e)).map(t=>Fm(t))}isMember(e){return Array.from(this._members.keys()).some(t=>ko(t,e))}removeOwnDevice(e){e.wrap("remove own membership",t=>{this.disconnect(t)})}disconnect(e){return this.errorBoundary.try(async()=>{var t;if(this.hasJoined){for(const s of this._members.values()){const i=await s.disconnect(!0);i&&e.refDetached(i)}this._state="created"}(t=this.joinedData)==null||t.dispose(),this.joinedData=void 0,this.emitChange()},!1)||!0}async removeMemberDevice(e,t,s){const i=Ws(e,t);await s.wrap({l:"remove device member",id:i},async r=>{const o=this._members.get(i);if(o){r.set("leave",!0);const c=await o.disconnect(!1);c&&r.refDetached(c),o.dispose(),this._members.remove(i)}})}handleDeviceMessage(e,t,s,i){this.errorBoundary.try(()=>{const r=Ws(t,s);let o=this._members.get(r);if(o&&e.content.sender_session_id===o.sessionId)o.handleDeviceMessage(e,i);else{i.log({l:"call: buffering to_device message, member not found",t:fs,id:this.id,userId:t,deviceId:s,sessionId:e.content.sender_session_id,type:e.type});let c=this.bufferedDeviceMessages.get(r);c||(c=new Set,this.bufferedDeviceMessages.set(r,c)),c.add(e)}})}async _createMemberPayload(e){var h,a;const{storage:t}=this.options,i=await(await t.readTxn([t.storeNames.roomState])).roomState.get(this.roomId,q.GroupCallMember,this.options.ownUserId),r=(a=(h=i==null?void 0:i.event)==null?void 0:h.content)!=null?a:{["m.calls"]:[]};let o=r["m.calls"],c=o.find(u=>u["m.call_id"]===this.id);c||(c={["m.call_id"]:this.id,["m.devices"]:[]},o.push(c));const l=this.options.clock.now();return c["m.devices"]=c["m.devices"].filter(u=>!(u.device_id===this.options.ownDeviceId||Rr(u)===void 0||hn(u,l,jr))),e&&c["m.devices"].push({device_id:this.options.ownDeviceId,session_id:this.options.sessionId,expires_ts:l+jr,feeds:[{purpose:"m.usermedia"}]}),r["m.calls"]=o.filter(u=>u["m.devices"].length!==0),r}async connectToMember(e,t,s){const i=Ws(e.userId,e.deviceId),r=t.membersLogItem.child({l:"member",id:i,sessionId:e.sessionId});await s.wrap({l:"connect",id:i},async o=>{const c=await e.connect(t.localMedia,t.localMuteSettings,t.turnServer,r);c&&o.refDetached(c)})}emitChange(){this.emit("change"),this.options.emitUpdate(this)}_setupRenewMembershipTimeout(e,t){var l;const{joinedData:s}=this;if(!s)return;(l=s.renewMembershipTimeout)==null||l.dispose(),s.renewMembershipTimeout=void 0;const i=Rr(e);if(typeof i!="number")return;const r=i-this.options.clock.now(),o=Math.max(1e4,Math.ceil((.2+this.options.random()*.8)*(.08333*jr))),c=Math.max(0,r-o);t.set("expiresIn",r),t.set("renewIn",c),s.renewMembershipTimeout=this.options.clock.createTimeout(c),s.renewMembershipTimeout.elapsed().then(()=>{s.logItem.wrap("renew membership",async h=>{const a=await this._createMemberPayload(!0);h.set("payload",a),await this.options.hsApi.sendState(this.roomId,q.GroupCallMember,this.options.ownUserId,a,{log:h}).response()})},()=>{})}dispose(){var e;(e=this.joinedData)==null||e.dispose();for(const t of this._members.values())t.dispose()}}const Io=5*60,Km={urls:["stun:turn.matrix.org"],username:"",credential:""};class Bm{constructor(e,t,s=Km){this.hsApi=e,this.clock=t,this.defaultSettings=s,this.isPolling=!1}getSettings(e){return e.wrap("get turn server",async t=>{if(!this.isPolling){const s=await this.doRequest(t),i=s?Mo(s):this.defaultSettings;t.set("iceServer",i),this.currentObservable?this.currentObservable.set(i):this.currentObservable=new Ui(i,()=>{this.stopPollLoop()},()=>{var r;this.runLoop((r=s==null?void 0:s.ttl)!=null?r:Io)})}return this.currentObservable})}async runLoop(e){let t=e;for(this.isPolling=!0;this.isPolling;)try{this.pollTimeout=this.clock.createTimeout(t*1e3),await this.pollTimeout.elapsed(),this.pollTimeout=void 0;const s=await this.doRequest(void 0);if(s){const i=Mo(s);$m(this.currentObservable,i)&&this.currentObservable.set(i),s.ttl>0?t=s.ttl:this.stopPollLoop()}else t=Io}catch(s){s.name}}async doRequest(e){try{return this.pollRequest=this.hsApi.getTurnServer({log:e}),await this.pollRequest.response()}catch(t){if(t.name==="HomeServerError")return;throw t}finally{this.pollRequest=void 0}}stopPollLoop(){var e,t;this.isPolling=!1,this.currentObservable=void 0,(e=this.pollTimeout)==null||e.dispose(),this.pollTimeout=void 0,(t=this.pollRequest)==null||t.abort(),this.pollRequest=void 0}dispose(){this.stopPollLoop()}}function $m(n,e){const t=n.get();if(!t)return!0;const s=Array.isArray(t.urls)?t.urls:[t.urls],i=Array.isArray(e.urls)?e.urls:[e.urls];return!(s.length===i.length&&!i.some(o=>!s.includes(o)))||e.username!==t.username||e.credential!==t.credential}function Mo(n){return{urls:n.uris,username:n.username,credential:n.password,credentialType:"password"}}function jm(n,e){return JSON.stringify(n)+","+JSON.stringify(e)}class qm{constructor(e){this.options=e,this._calls=new Dt,this.roomMemberToCallIds=new Map,this.sessionId=Ir("s"),this.groupCallOptions=Object.assign({},this.options,{turnServerSource:new Bm(this.options.hsApi,this.options.clock),emitUpdate:(t,s)=>this._calls.update(t.id,s),createTimeout:this.options.clock.createTimeout,sessionId:this.sessionId})}loadCalls(e,t){return this.options.logger.wrapOrRun(t,"CallHandler.loadCalls",async s=>{e||(e=Ki.Ring),s.set("intent",e);const i=await this._getLoadTxn(),r=await i.calls.getByIntent(e);await this._loadCallEntries(r,i,s)})}loadCallsForRoom(e,t,s){return this.options.logger.wrapOrRun(s,"CallHandler.loadCallsForRoom",async i=>{i.set("intent",e),i.set("roomId",t);const r=await this._getLoadTxn(),o=await r.calls.getByIntentAndRoom(e,t);await this._loadCallEntries(o,r,i)})}async _getLoadTxn(){const e=this.options.storage.storeNames;return await this.options.storage.readTxn([e.calls,e.roomState])}async _loadCallEntries(e,t,s){s.set("entries",e.length),await Promise.all(e.map(async r=>{if(this._calls.get(r.callId))return;const o=await t.roomState.get(r.roomId,q.GroupCall,r.callId);if(o){const c=new qr(o.event.state_key,!0,!1,r.timestamp,o.event.content,o.roomId,this.groupCallOptions);this._calls.set(c.id,c)}}));const i=Array.from(new Set(e.map(r=>r.roomId)));await Promise.all(i.map(async r=>{const o=await t.roomState.getAllForType(r,q.GroupCallMember);await Promise.all(o.map(async c=>{const l=c.event.sender,h=await t.roomState.get(r,Ke,l);let a;h&&(a=Q.fromMemberEvent(h.event)),a||(a=Q.fromUserId(r,l,"join")),this.handleCallMemberEvent(c.event,a,r,s)}))})),s.set("newSize",this._calls.size)}createCall(e,t,s,i,r){return this.options.logger.wrapOrRun(r,"CallHandler.createCall",async o=>{i||(i=Ki.Ring);const c=new qr(Ir("conf-"),!1,!0,void 0,{"m.name":s,"m.intent":i},e,this.groupCallOptions);this._calls.set(c.id,c);try{await c.create(t,o);const l=await this.options.storage.readWriteTxn([this.options.storage.storeNames.calls]);l.calls.add({intent:c.intent,callId:c.id,timestamp:this.options.clock.now(),roomId:e}),await l.complete()}catch(l){throw this._calls.remove(c.id),l}return c})}get calls(){return this._calls}async handleRoomState(e,t,s,i,r){if(t.type===q.GroupCall&&this.handleCallEvent(t,e.id,i,r),t.type===q.GroupCallMember){let o=await s.lookupMemberAtEvent(t.sender,t,i);o||(o=Q.fromUserId(e.id,t.sender,"join")),this.handleCallMemberEvent(t,o,e.id,r)}}updateRoomMembers(e,t){for(const s of this._calls.values())s.roomId===e.id&&s.updateRoomMembers(t)}handlesDeviceMessageEventType(e){return Dm(e)}handleDeviceMessage(e,t,s,i){const r=this._calls.get(e.content.conf_id);r==null||r.handleDeviceMessage(e,t,s,i)}handleCallEvent(e,t,s,i){const r=e.state_key;let o=this._calls.get(r);o?(o.updateCallEvent(e,i),o.isTerminated&&(o.disconnect(i),this._calls.remove(o.id),s.calls.remove(o.intent,t,o.id))):e.content["m.terminated"]||(o=new qr(e.state_key,!1,!1,e.origin_server_ts,e.content,t,this.groupCallOptions),this._calls.set(o.id,o),s.calls.add({intent:o.intent,callId:o.id,timestamp:e.origin_server_ts,roomId:t}))}handleCallMemberEvent(e,t,s,i){var a;const r=e.state_key,o=jm(s,r),c=(a=e.content["m.calls"])!=null?a:[];for(const u of c){const p=u["m.call_id"],g=this._calls.get(p);g==null||g.updateMembership(r,t,u,i)}const l=new Set(c.map(u=>u["m.call_id"]));let h=this.roomMemberToCallIds.get(o);if(h){for(const u of h)if(!l.has(u)){const p=this._calls.get(u);p==null||p.removeMembership(r,i)}}l.size===0?this.roomMemberToCallIds.delete(o):this.roomMemberToCallIds.set(o,l)}dispose(){this.groupCallOptions.turnServerSource.dispose();for(const e of this._calls.values())e.dispose()}}class Hm extends xr{async handleRoomState(e,t,s,i,r){const o=[];for(let c of this._handlers)o.push(c.handleRoomState(e,t,s,i,r));await Promise.all(o)}updateRoomMembers(e,t){for(let s of this._handlers)s.updateRoomMembers(e,t)}}var dn=(n=>(n[n.Calls=1]="Calls",n[n.CrossSigning=2]="CrossSigning",n))(dn||{});class Xs{constructor(e=0){this.flags=e}withFeature(e){return new Xs(this.flags|e)}withoutFeature(e){return new Xs(this.flags^e)}isFeatureEnabled(e){return(this.flags&e)!==0}get calls(){return this.isFeatureEnabled(1)}get crossSigning(){return this.isFeatureEnabled(2)}static async load(e){const t=await e.getInt("enabled_features")||0;return new Xs(t)}async store(e){await e.setInt("enabled_features",this.flags)}}const ys="DEFAULT_KEY",ki="pusher";class Wm{constructor({storage:e,hsApi:t,sessionInfo:s,olm:i,olmWorker:r,platform:o,mediaRepository:c,features:l}){this._platform=o,this._storage=e,this._hsApi=t,this._mediaRepository=c,this._features=l,this._syncInfo=null,this._sessionInfo=s,this._rooms=new Dt,this._roomUpdateCallback=(h,a)=>this._rooms.update(h.id,a),this._activeArchivedRooms=new Map,this._invites=new Dt,this._inviteUpdateCallback=(h,a)=>this._invites.update(h.id,a),this._roomsBeingCreatedUpdateCallback=(h,a)=>{h.isCancelled?this._roomsBeingCreated.remove(h.id):this._roomsBeingCreated.update(h.id,a)},this._roomsBeingCreated=new Dt,this._user=new nu(s.userId),this._roomStateHandler=new Hm,l.calls&&this._setupCallHandler(),this._deviceMessageHandler=new Du({storage:e,callHandler:this._callHandler}),this._olm=i,this._olmUtil=null,this._e2eeAccount=null,this._deviceTracker=null,this._olmEncryption=null,this._keyLoader=null,this._megolmEncryption=null,this._megolmDecryption=null,this._getSyncToken=()=>this.syncToken,this._olmWorker=r,this._keyBackup=new Vt(void 0),this._crossSigning=new Vt(void 0),this._observedRoomStatus=new Map,i&&(this._olmUtil=new i.Utility,this._deviceTracker=new Id({storage:e,getSyncToken:this._getSyncToken,olmUtil:this._olmUtil,ownUserId:s.userId,ownDeviceId:s.deviceId})),this._createRoomEncryption=this._createRoomEncryption.bind(this),this._forgetArchivedRoom=this._forgetArchivedRoom.bind(this),this.needsKeyBackup=new Vt(!1),this._secretFetcher=new Bu,this._secretSharing=null,this._secretStorage=null}get fingerprintKey(){var e;return(e=this._e2eeAccount)==null?void 0:e.identityKeys.ed25519}get hasSecretStorageKey(){return this._hasSecretStorageKey}get deviceId(){return this._sessionInfo.deviceId}get userId(){return this._sessionInfo.userId}get callHandler(){return this._callHandler}get features(){return this._features}_setupCallHandler(){this._callHandler=new qm({clock:this._platform.clock,random:this._platform.random,hsApi:this._hsApi,encryptDeviceMessage:async(e,t,s,i,r)=>{if(!this._deviceTracker||!this._olmEncryption){r.set("encryption_disabled",!0);return}const o=await r.wrap("get device key",async c=>{const l=this._deviceTracker.deviceForId(t,s,this._hsApi,c);return l||c.set("not_found",!0),l});if(o)return await this._olmEncryption.encrypt(i.type,i.content,[o],this._hsApi,r)},storage:this._storage,webRTC:this._platform.webRTC,ownDeviceId:this._sessionInfo.deviceId,ownUserId:this._sessionInfo.userId,logger:this._platform.logger,forceTURN:!1}),this.observeRoomState(this._callHandler)}async _setupEncryption(){const e=new xm,t=new tm(this._e2eeAccount,ys,this._platform.clock.now,this._user.id,this._olm,e);this._olmEncryption=new nm(this._e2eeAccount,ys,this._olm,this._storage,this._platform.clock.now,this._user.id,this._olmUtil,e),this._keyLoader=new wm(this._olm,ys,20),this._megolmEncryption=new Mm({account:this._e2eeAccount,pickleKey:ys,olm:this._olm,storage:this._storage,keyLoader:this._keyLoader,now:this._platform.clock.now,ownDeviceId:this._sessionInfo.deviceId}),this._megolmDecryption=new ym(this._keyLoader,this._olmWorker),this._deviceMessageHandler.enableEncryption({olmDecryption:t,megolmDecryption:this._megolmDecryption}),this._secretSharing=new $u({hsApi:this._hsApi,storage:this._storage,deviceMessageHandler:this._deviceMessageHandler,deviceTracker:this._deviceTracker,ourUserId:this.userId,olmEncryption:this._olmEncryption,crypto:this._platform.crypto,encoding:this._platform.encoding,crossSigning:this._crossSigning,logger:this._platform.logger}),await this._secretSharing.load(),this._secretFetcher.setSecretSharing(this._secretSharing)}_createRoomEncryption(e,t){var s;if(!this._olmEncryption)throw new Error("creating room encryption before encryption got globally enabled");return t.algorithm!==ft?null:new Rm({room:e,deviceTracker:this._deviceTracker,olmEncryption:this._olmEncryption,megolmEncryption:this._megolmEncryption,megolmDecryption:this._megolmDecryption,storage:this._storage,keyBackup:(s=this._keyBackup)==null?void 0:s.get(),encryptionParams:t,notifyMissingMegolmSession:()=>{this._keyBackup.get()||this.needsKeyBackup.set(!0)},clock:this._platform.clock})}enableSecretStorage(e,t,s=void 0){return this._platform.logger.wrapOrRun(s,"enable secret storage",async i=>{var o,c;if(!this._olm)throw new Error("olm required");this._keyBackup.get()&&(this._keyBackup.get().dispose(),this._keyBackup.set(void 0));const r=await Yu(e,t,this._storage,this._platform,this._olm);if(await this._tryLoadSecretStorage(r,i))return await this._writeSSSSKey(r,i),await((o=this._keyBackup.get())==null?void 0:o.start(i)),await((c=this._crossSigning.get())==null?void 0:c.start(i)),r;throw new Error("Could not read key backup with the given key")})}async _writeSSSSKey(e,t){const s=this._keyBackup.get();if(!s)return;const i=s.version,r=await this._storage.readWriteTxn([this._storage.storeNames.session,this._storage.storeNames.inboundGroupSessions]);try{const o=await Wu(e,i,r);if(t.set("previousBackupVersion",o),t.set("backupVersion",i),!!o&&o!==i){const c=await s.markAllForBackup(r);t.set("amountMarkedForBackup",c)}}catch(o){throw r.abort(),o}await r.complete()}async disableSecretStorage(){const e=await this._storage.readWriteTxn([this._storage.storeNames.session]);try{Gu(e)}catch(s){throw e.abort(),s}if(await e.complete(),this._keyBackup.get()){for(const s of this._rooms.values())s.isEncrypted&&s.enableKeyBackup(void 0);this._keyBackup.get().dispose(),this._keyBackup.set(void 0)}const t=this._crossSigning.get();t&&(t.dispose(),this._crossSigning.set(void 0))}_tryLoadSecretStorage(e,t){return t.wrap("enable secret storage",async s=>{const i=new Hu({key:e,platform:this._platform,storage:this._storage}),r=await i.hasValidKeyForAnyAccountData();return s.set("isValid",r),r&&(this._secretStorage=i,await this._loadSecretStorageServices(i,s),this._secretFetcher.setSecretStorage(i)),r})}async _loadSecretStorageServices(e,t){try{await t.wrap("enable key backup",async s=>{const i=new Im(this._hsApi,this._olm,this._keyLoader,this._storage,this._platform);if(await i.load(e,s)){for(const r of this._rooms.values())r.isEncrypted&&r.enableKeyBackup(i);return this._keyBackup.set(i),!0}else s.set("no_backup",!0)})}catch(s){t.catch(s)}}get keyBackup(){return this._keyBackup}get crossSigning(){return this._crossSigning}get secretSharing(){return this._secretSharing}get secretFetcher(){return this._secretFetcher}get hasIdentity(){return!!this._e2eeAccount}async createIdentity(e){this._olm&&(this._e2eeAccount||(this._e2eeAccount=await this._createNewAccount(this._sessionInfo.deviceId,this._storage),e.set("keys",this._e2eeAccount.identityKeys),await this._setupEncryption()),this._sessionInfo.isReadOnly||(await this._e2eeAccount.generateOTKsIfNeeded(this._storage,e),await e.wrap("uploadKeys",t=>this._e2eeAccount.uploadKeys(this._storage,!1,t))),await this._createCrossSigning())}async dehydrateIdentity(e,t){return t.set("deviceId",e.deviceId),this._olm?e.deviceId!==this.deviceId?(t.set("wrong_device",!0),!1):this._e2eeAccount?(t.set("account_already_setup",!0),!1):await e.claim(this._hsApi,t)?(this._e2eeAccount=await Is.adoptDehydratedDevice({dehydratedDevice:e,hsApi:this._hsApi,olm:this._olm,pickleKey:ys,userId:this._sessionInfo.userId,olmWorker:this._olmWorker,deviceId:this.deviceId,storage:this._storage}),t.set("keys",this._e2eeAccount.identityKeys),this._setupEncryption(),!0):(t.set("already_claimed",!0),!1):(t.set("no_olm",!0),!1)}_createNewAccount(e,t=void 0){return Is.create({hsApi:this._hsApi,olm:this._olm,pickleKey:ys,userId:this._sessionInfo.userId,olmWorker:this._olmWorker,deviceId:e,storage:t})}setupDehydratedDevice(e,t=null){return this._platform.logger.wrapOrRun(t,"setupDehydratedDevice",async s=>{const i=await this._createNewAccount("temp-device-id");try{const r=await Xu(i,this._hsApi,e,"Dehydrated device",s);return s.set("deviceId",r),r}finally{i.dispose()}})}async load(e){const t=await this._storage.readTxn([this._storage.storeNames.session,this._storage.storeNames.roomSummary,this._storage.storeNames.invites,this._storage.storeNames.roomMembers,this._storage.storeNames.timelineEvents,this._storage.storeNames.timelineFragments,this._storage.storeNames.pendingEvents,this._storage.storeNames.accountData,this._storage.storeNames.crossSigningKeys]);this._syncInfo=await t.session.get("sync"),this._olm&&(this._e2eeAccount=await Is.load({hsApi:this._hsApi,olm:this._olm,pickleKey:ys,userId:this._sessionInfo.userId,deviceId:this._sessionInfo.deviceId,olmWorker:this._olmWorker,txn:t}),this._e2eeAccount&&e.set("keys",this._e2eeAccount.identityKeys),this._setupEncryption());const s=await this._getPendingEventsByRoom(t),i=await t.invites.getAll(),r=Promise.all(i.map(async l=>{const h=this.createInvite(l.roomId);e.wrap("invite",a=>h.load(l,a)),this._invites.add(h.id,h)})),o=await t.roomSummary.getAll(),c=Promise.all(o.map(async l=>{const h=this.createJoinedRoom(l.roomId,s.get(l.roomId));await e.wrap("room",a=>h.load(l,t,a)),this._rooms.add(h.id,h)}));await Promise.all([r,c]);for(const[l,h]of this.invites){const a=this.rooms.get(l);a&&a.setInvite(h)}if(this._olm&&this._e2eeAccount){const l=await zu(t);l&&await this._tryLoadSecretStorage(l,e)}this._e2eeAccount&&await this._createCrossSigning()}async _createCrossSigning(){this._features.crossSigning&&this._platform.logger.run("enable cross-signing",async e=>{const t=new wd({storage:this._storage,secretFetcher:this._secretFetcher,platform:this._platform,olm:this._olm,olmUtil:this._olmUtil,deviceTracker:this._deviceTracker,deviceMessageHandler:this._deviceMessageHandler,hsApi:this._hsApi,ownUserId:this.userId,e2eeAccount:this._e2eeAccount,deviceId:this.deviceId});await t.load(e),this._crossSigning.set(t)})}dispose(){var e,t,s,i,r,o;(e=this._olmWorker)==null||e.dispose(),this._olmWorker=void 0,(t=this._keyBackup.get())==null||t.dispose(),this._keyBackup.set(void 0),(s=this._megolmDecryption)==null||s.dispose(),this._megolmDecryption=void 0,(i=this._e2eeAccount)==null||i.dispose(),this._e2eeAccount=void 0,(r=this._callHandler)==null||r.dispose(),this._callHandler=void 0,(o=this._crossSigning.get())==null||o.dispose();for(const c of this._rooms.values())c.dispose();this._rooms=void 0}async start(e,t,s){var c,l;if(e){const h=await this._storage.readWriteTxn([this._storage.storeNames.session]);h.session.set("serverVersions",e),await h.complete()}t&&await s.wrap("SSSSKeyFromDehydratedDeviceKey",async h=>{const a=await Ju(t.key,this._storage,this._platform);a&&await this._tryLoadSecretStorage(a,h)&&(h.set("success",!0),await this._writeSSSSKey(a))}),await((c=this._keyBackup.get())==null?void 0:c.start(s)),await((l=this._crossSigning.get())==null?void 0:l.start(s));const r=await(await this._storage.readWriteTxn([this._storage.storeNames.operations])).operations.getAll(),o=ti(r,h=>h.scope);for(const h of this._rooms.values()){let a;const u=o.get(h.id);u&&(a=ti(u,p=>p.type)),h.start(a,s)}}async _getPendingEventsByRoom(e){return(await e.pendingEvents.getAll()).reduce((s,i)=>{const r=s.get(i.roomId);return r?r.push(i):s.set(i.roomId,[i]),s},new Map)}get rooms(){return this._rooms}findDirectMessageForUserId(e){for(const[,t]of this._rooms)if(t.isDirectMessageForUserId(e))return t;for(const[,t]of this._invites)if(t.isDirectMessageForUserId(e))return t}createJoinedRoom(e,t){return new Iu({roomId:e,getSyncToken:this._getSyncToken,storage:this._storage,emitCollectionChange:this._roomUpdateCallback,hsApi:this._hsApi,mediaRepository:this._mediaRepository,pendingEvents:t,user:this._user,createRoomEncryption:this._createRoomEncryption,platform:this._platform,roomStateHandler:this._roomStateHandler})}_createArchivedRoom(e){const t=new Mu({roomId:e,getSyncToken:this._getSyncToken,storage:this._storage,emitCollectionChange:()=>{},releaseCallback:()=>this._activeArchivedRooms.delete(e),forgetCallback:this._forgetArchivedRoom,hsApi:this._hsApi,mediaRepository:this._mediaRepository,user:this._user,createRoomEncryption:this._createRoomEncryption,platform:this._platform});return this._activeArchivedRooms.set(e,t),t}get invites(){return this._invites}createInvite(e){return new Nu({roomId:e,hsApi:this._hsApi,emitCollectionUpdate:this._inviteUpdateCallback,mediaRepository:this._mediaRepository,user:this._user,platform:this._platform})}get roomsBeingCreated(){return this._roomsBeingCreated}async createRoom(e){let t;return await this._platform.logger.run("create room",async s=>{const i=`local-${Math.floor(this._platform.random()*Number.MAX_SAFE_INTEGER)}`;t=new Vu(i,e,this._roomsBeingCreatedUpdateCallback,this._mediaRepository,this._platform,s),this._roomsBeingCreated.set(i,t);const r=[t.create(this._hsApi,s)];e.loadProfiles!==!1&&r.push(t.loadProfiles(this._hsApi,s)),await Promise.all(r),t.roomId&&(this.rooms.get(t.roomId)&&this._tryReplaceRoomBeingCreated(t.roomId,s),await t.adjustDirectMessageMapIfNeeded(this._user,this._storage,this._hsApi,s))}),t}async obtainSyncLock(e){var s;const t=(s=e.to_device)==null?void 0:s.events;if(Array.isArray(t)&&t.length)return await this._deviceMessageHandler.obtainSyncLock(t)}async prepareSync(e,t,s,i){var o;const r=(o=e.to_device)==null?void 0:o.events;if(Array.isArray(r)&&r.length)return await i.wrap("deviceMsgs",c=>this._deviceMessageHandler.prepareSync(r,t,s,c))}async writeSync(e,t,s,i,r){const o={syncInfo:null,e2eeAccountChanges:null,hasNewRoomKeys:!1,deviceMessageDecryptionResults:null,changedDevices:null},c=e.next_batch;if(c!==this.syncToken){const u={token:c,filterId:t};i.session.set("sync",u),o.syncInfo=u}const l=e.device_one_time_keys_count;this._e2eeAccount&&l&&(o.e2eeAccountChanges=this._e2eeAccount.writeSync(l,i,r));const h=e.device_lists;if(this._deviceTracker&&Array.isArray(h==null?void 0:h.changed)&&h.changed.length&&(await r.wrap("deviceLists",u=>this._deviceTracker.writeDeviceChanges(h.changed,i,u)),o.changedDevices=h.changed),s){const{hasNewRoomKeys:u,decryptionResults:p}=await r.wrap("deviceMsgs",g=>this._deviceMessageHandler.writeSync(s,i,g));o.hasNewRoomKeys=u,o.deviceMessageDecryptionResults=p}const a=e.account_data;if(Array.isArray(a==null?void 0:a.events))for(const u of a.events)typeof u.type=="string"&&i.accountData.set(u);return o}afterSync({syncInfo:e,e2eeAccountChanges:t}){e&&(this._syncInfo=e),this._e2eeAccount&&this._e2eeAccount.afterSync(t)}async afterSyncCompleted(e,t,s){var i,r,o;this._e2eeAccount&&!t&&!this._sessionInfo.isReadOnly&&await this._e2eeAccount.generateOTKsIfNeeded(this._storage,s)&&await s.wrap("uploadKeys",l=>this._e2eeAccount.uploadKeys(this._storage,!1,l)),e.hasNewRoomKeys&&((i=this._keyBackup.get())==null||i.flush(s)),e.deviceMessageDecryptionResults&&await this._deviceMessageHandler.afterSyncCompleted(e.deviceMessageDecryptionResults,this._deviceTracker,this._hsApi,s),(r=e.changedDevices)!=null&&r.includes(this.userId)&&((o=this._secretSharing)==null||o.checkSecretValidity())}_tryReplaceRoomBeingCreated(e,t){for(const[,s]of this._roomsBeingCreated)if(s.roomId===e){const i=this._observedRoomStatus.get(s.id);i&&(t.log("replacing room being created").set("localId",s.id).set("roomId",s.roomId),i.set(i.get()|se.Replaced)),s.dispose(),this._roomsBeingCreated.remove(s.id);return}}async applyRoomCollectionChangesAfterSync(e,t,s,i){var r,o;for(const c of t)c.shouldAdd?(this._rooms.add(c.id,c.room),this._tryReplaceRoomBeingCreated(c.id,i)):c.shouldRemove&&this._rooms.remove(c.id);for(const c of e)c.shouldAdd?this._invites.add(c.id,c.invite):c.shouldRemove&&this._invites.remove(c.id);if(this._observedRoomStatus.size!==0){for(const c of s)c.shouldAdd&&((r=this._observedRoomStatus.get(c.id))==null||r.set(se.Archived));for(const c of t)c.shouldAdd&&((o=this._observedRoomStatus.get(c.id))==null||o.set(se.Joined));for(const c of e){const l=this._observedRoomStatus.get(c.id);if(l){const h=l.get()|se.Invited;if(c.shouldAdd)l.set(h);else if(c.shouldRemove){const a=h^se.Invited;l.set(a)}}}}}_forgetArchivedRoom(e){const t=this._observedRoomStatus.get(e);t&&t.set((t.get()|se.Archived)^se.Archived)}get syncToken(){var e;return(e=this._syncInfo)==null?void 0:e.token}get syncFilterId(){var e;return(e=this._syncInfo)==null?void 0:e.filterId}get user(){return this._user}get mediaRepository(){return this._mediaRepository}enablePushNotifications(e){return e?this._enablePush():this._disablePush()}async _enablePush(){return this._platform.logger.run("enablePush",async e=>{const t=bs.createDefaultPayload(this._sessionInfo.id),s=await this._platform.notificationService.enablePush(bs,t);if(!s)return e.set("no_pusher",!0),!1;await s.enable(this._hsApi,e);const i=await this._storage.readWriteTxn([this._storage.storeNames.session]);return i.session.set(ki,s.serialize()),await i.complete(),!0})}async _disablePush(){return this._platform.logger.run("disablePush",async e=>{await this._platform.notificationService.disablePush();const s=await(await this._storage.readTxn([this._storage.storeNames.session])).session.get(ki);if(!s)return!0;await new bs(s).disable(this._hsApi,e);const r=await this._storage.readWriteTxn([this._storage.storeNames.session]);return r.session.remove(ki),await r.complete(),!0})}async arePushNotificationsEnabled(){return await this._platform.notificationService.isPushEnabled()?!!await(await this._storage.readTxn([this._storage.storeNames.session])).session.get(ki):!1}async checkPusherEnabledOnHomeserver(){const t=await(await this._storage.readTxn([this._storage.storeNames.session])).session.get(ki);if(!t)return!1;const s=new bs(t),i=await this._hsApi.getPushers().response();return((i==null?void 0:i.pushers)||[]).map(o=>new bs(o)).some(o=>o.equals(s))}async getRoomStatus(e){if(!!this._roomsBeingCreated.get(e))return se.BeingCreated;if(!!this._rooms.get(e))return se.Joined;{const i=!!this._invites.get(e),o=await(await this._storage.readTxn([this._storage.storeNames.archivedRoomSummary])).archivedRoomSummary.has(e);return i&&o?se.Invited|se.Archived:i?se.Invited:o?se.Archived:se.None}}async observeRoomStatus(e){let t=this._observedRoomStatus.get(e);if(!t){let s;t=new Ui(s,()=>{this._observedRoomStatus.delete(e)}),this._observedRoomStatus.set(e,t),s=await this.getRoomStatus(e),t.get()===void 0&&t.set(s)}return t}observeRoomState(e){return this._roomStateHandler.subscribe(e)}createOrGetArchivedRoomForSync(e){let t=this._activeArchivedRooms.get(e);return t?t.retain():t=this._createArchivedRoom(e),t}loadArchivedRoom(e,t=null){return this._platform.logger.wrapOrRun(t,"loadArchivedRoom",async s=>{s.set("id",e);const i=this._activeArchivedRooms.get(e);if(i)return i.retain(),i;const r=await this._storage.readTxn([this._storage.storeNames.archivedRoomSummary,this._storage.storeNames.roomMembers]),o=await r.archivedRoomSummary.get(e);if(o){const c=this._createArchivedRoom(e);return await c.load(o,r,s),c}})}joinRoom(e,t=null){return this._platform.logger.wrapOrRun(t,"joinRoom",async s=>(await this._hsApi.joinIdOrAlias(e,{log:s}).response()).room_id)}updateAccessToken(e){this._hsApi.updateAccessToken(e)}}class zm{constructor({username:e,password:t,homeserver:s}){this._username=e,this._password=t,this.homeserver=s}async login(e,t,s){return await e.passwordLogin(this._username,this._password,t,{log:s}).response()}}class Gm{constructor({homeserver:e,loginToken:t}){this.homeserver=e,this._loginToken=t}async login(e,t,s){return await e.tokenLogin(this._loginToken,Pe(),t,{log:s}).response()}}class Ym{constructor(e){this._homeserver=e}get homeserver(){return this._homeserver}createSSORedirectURL(e){return`${this._homeserver}/_matrix/client/r0/login/sso/redirect?redirectUrl=${encodeURIComponent(e)}`}}class Un{constructor(e,t){this._session=e,this._params=t}setNextStage(e){this._nextStage=e}get nextStage(){return this._nextStage}}class Jm extends Un{generateAuthenticationData(){return{session:this._session,type:this.type}}get type(){return"m.login.dummy"}}class Qm extends Un{generateAuthenticationData(){return{session:this._session,type:this.type}}get type(){return"m.login.terms"}get privacyPolicy(){var e;return(e=this._params)==null?void 0:e.policies.privacy_policy}get termsOfService(){var e;return(e=this._params)==null?void 0:e.policies.terms_of_service}}class Xm extends Un{constructor(e,t,s){super(e,t),this._type=s}generateAuthenticationData(){if(!this._token)throw new Error("No token provided for TokenAuth");return{session:this._session,type:this._type,token:this._token}}setToken(e){this._token=e}get type(){return this._type}}class Zm{constructor(e,t,s,i){this.homeserver=e,this._hsApi=t,this._accountDetails=s,this._flowSelector=i!=null?i:r=>r[0]}async start(){const e=await this._hsApi.register(this._accountDetails.username,this._accountDetails.password,this._accountDetails.initialDeviceDisplayName,void 0,this._accountDetails.inhibitLogin).response();return this.parseStagesFromResponse(e)}async submitStage(e){const t=e.generateAuthenticationData(),{username:s,password:i,initialDeviceDisplayName:r,inhibitLogin:o}=this._accountDetails,c=this._hsApi.register(s,i,r,t,o),l=await c.response(),h=await c.responseCode(),a=Fr(It({},l),{status:h});return this.parseRegistrationResponse(a,e)}parseStagesFromResponse(e){const{session:t,params:s}=e,i=this._flowSelector(e.flows);if(!i)throw new Error("flowSelector did not return any flow!");let r,o;for(const c of i.stages){const l=this._createRegistrationStage(c,t,s);r?(o.setNextStage(l),o=l):(r=l,o=l)}return r}async parseRegistrationResponse(e,t){var s;switch(e.status){case 200:this._registerResponse=e;return;case 401:if((s=e.completed)!=null&&s.includes(t.type))return t.nextStage;throw new Error("This stage could not be completed!")}}_createRegistrationStage(e,t,s){switch(e){case"m.login.dummy":return new Jm(t,s==null?void 0:s[e]);case"m.login.terms":return new Qm(t,s==null?void 0:s[e]);case"org.matrix.msc3231.login.registration_token":case"m.login.registration_token":return new Xm(t,s==null?void 0:s[e],e);default:throw new Error(`Unknown stage: ${e}`)}}get authData(){if(this._registerResponse)return{accessToken:this._registerResponse.access_token,homeserver:this.homeserver,userId:this._registerResponse.user_id,deviceId:this._registerResponse.device_id}}}const W=oi("NotLoading","Login","LoginFailed","QueryAccount","AccountSetup","Loading","SessionSetup","Migrating","FirstSync","Error","Ready"),Pt=oi("Connection","Credentials","Unknown");class Nr{constructor(e,t=new Xs(0)){this._platform=e,this._sessionStartedByReconnector=!1,this._status=new Vt(W.NotLoading),this._error=null,this._loginFailure=null,this._reconnector=null,this._session=null,this._sync=null,this._sessionId=null,this._storage=null,this._requestScheduler=null,this._olmPromise=e.loadOlm(),this._workerPromise=e.loadOlmWorker(),this._accountSetup=void 0,this._features=t}createNewSessionId(){return Math.floor(this._platform.random()*Number.MAX_SAFE_INTEGER).toString()}get sessionId(){return this._sessionId}async startWithExistingSession(e){this._status.get()===W.NotLoading&&(this._status.set(W.Loading),await this._platform.logger.run("load session",async t=>{t.set("id",e);try{const s=await this._platform.sessionInfoStorage.get(e);if(!s)throw new Error("Invalid session id: "+e);await this._loadSessionInfo(s,null,t),t.set("status",this._status.get())}catch(s){t.catch(s),this._error=s,this._status.set(W.Error)}}))}_parseLoginOptions(e,t){const s=e.flows,i={homeserver:t};for(const r of s)r.type==="m.login.password"?i.password=(o,c)=>new zm({homeserver:t,username:o,password:c}):r.type==="m.login.sso"&&s.find(o=>o.type==="m.login.token")?i.sso=new Ym(t):r.type==="m.login.token"&&(i.token=o=>new Gm({homeserver:t,loginToken:o}));return i}queryLogin(e){return new oa(async t=>{e=await Xc(e,(r,o)=>t(this._platform.request(r,o)));const s=new ws({homeserver:e,request:this._platform.request}),i=await t(s.getLoginFlows()).response();return this._parseLoginOptions(i,e)})}async startRegistration(e,t,s,i,r){const o=this._platform.request,c=new ws({homeserver:e,request:o});return new Zm(e,c,{username:t,password:s,initialDeviceDisplayName:i},r)}async startWithAuthData({accessToken:e,deviceId:t,userId:s,homeserver:i,isReadOnly:r=!1}){await this._platform.logger.run("startWithAuthData",async o=>{r&&o.set("isReadonly (Disabled OTK Upload)",!0),await this._createSessionAfterAuth({accessToken:e,deviceId:t,userId:s,homeserver:i},!0,r,o)})}async startWithLogin(e,{inspectAccountSetup:t}={}){const s=this._status.get();s!==W.LoginFailed&&s!==W.NotLoading&&s!==W.Error||(this._resetStatus(),await this._platform.logger.run("login",async i=>{this._status.set(W.Login);let r;try{const o=this._platform.request,c=new ws({homeserver:e.homeserver,request:o}),l=await e.login(c,"Hydrogen",i);r={deviceId:l.device_id,userId:l.user_id,homeserver:e.homeserver,accessToken:l.access_token}}catch(o){this._error=o,o.name==="HomeServerError"?(o.errcode==="M_FORBIDDEN"?this._loginFailure=Pt.Credentials:this._loginFailure=Pt.Unknown,i.set("loginFailure",this._loginFailure),this._status.set(W.LoginFailed)):o.name==="ConnectionError"?(this._loginFailure=Pt.Connection,this._status.set(W.LoginFailed)):this._status.set(W.Error);return}await this._createSessionAfterAuth(r,t,!1,i)}))}async _createSessionAfterAuth({deviceId:e,userId:t,accessToken:s,homeserver:i},r,o,c){const l=this.createNewSessionId(),h=this._platform.clock.now(),a={id:l,deviceId:e,userId:t,homeServer:i,homeserver:i,accessToken:s,lastUsed:h,isReadOnly:o};let u;r&&(u=await this._inspectAccountAfterLogin(a,c),u&&(a.deviceId=u.deviceId)),await this._platform.sessionInfoStorage.add(a);try{await this._loadSessionInfo(a,u,c),c.set("status",this._status.get())}catch(p){c.catch(p),u==null||u.dispose(),this._error=p,this._status.set(W.Error)}}async _loadSessionInfo(e,t,s){s.set("appVersion",this._platform.version);const i=this._platform.clock;this._sessionStartedByReconnector=!1,this._status.set(W.Loading),this._reconnector=new Al({onlineStatus:this._platform.onlineStatus,retryDelay:new ua(i.createTimeout),createMeasure:i.createMeasure});const r=new ws({homeserver:e.homeServer,accessToken:e.accessToken,request:this._platform.request,reconnector:this._reconnector});this._sessionId=e.id,this._storage=await this._platform.storageFactory.create(e.id,s);const o={id:e.id,deviceId:e.deviceId,userId:e.userId,homeserver:e.homeServer,isReadOnly:e.isReadOnly},c=await this._olmPromise;let l=null;this._workerPromise&&(l=await this._workerPromise),this._requestScheduler=new Ul({hsApi:r,clock:i}),this._requestScheduler.start();const h=await r.versions({timeout:1e4,log:s}).response(),a=new Nl({homeserver:e.homeServer,platform:this._platform,serverVersions:h.versions});if(this._platform.updateService.updateAuthData({accessToken:e.accessToken,homeserver:e.homeServer}),this._session=new Wm({storage:this._storage,sessionInfo:o,hsApi:this._requestScheduler.hsApi,olm:c,olmWorker:l,mediaRepository:a,platform:this._platform,features:this._features}),await this._session.load(s),t?(await s.wrap("dehydrateIdentity",u=>this._session.dehydrateIdentity(t,u)),await this._session.setupDehydratedDevice(t.key,s)):this._session.hasIdentity||(this._status.set(W.SessionSetup),await s.wrap("createIdentity",u=>this._session.createIdentity(u))),this._sync=new Fl({hsApi:this._requestScheduler.hsApi,storage:this._storage,session:this._session,logger:this._platform.logger}),this._reconnectSubscription=this._reconnector.connectionStatus.subscribe(u=>{u===Ys.Online&&this._platform.logger.runDetached("reconnect",async p=>{this._requestScheduler.start(),this._sync.start(),this._sessionStartedByReconnector=!0;const g=t;t=void 0,await p.wrap("session start",f=>this._session.start(this._reconnector.lastVersionsResponse,g,f))})}),await s.wrap("wait first sync",()=>this._waitForFirstSync()),!this._isDisposed&&(this._status.set(W.Ready),!this._sessionStartedByReconnector)){if(this._isDisposed)return;const u=t;t=void 0,await s.wrap("session start",p=>this._session.start(h,u,p))}}async updateAccessToken(e){if(!this._session)throw Error("No session loaded, cannot update access token");this._session.updateAccessToken(e),this._platform.updateService.updateAuthData({accessToken:e}),await this._platform.sessionInfoStorage.updateAccessToken(this._sessionId,e)}async _waitForFirstSync(){this._sync.start(),this._status.set(W.FirstSync),this._waitForFirstSyncHandle=this._sync.status.waitFor(e=>{var t;return e===te.Stopped?((t=this._sync.error)==null?void 0:t.name)!=="ConnectionError":e===te.Syncing});try{if(await this._waitForFirstSyncHandle.promise,this._sync.status.get()===te.Stopped&&this._sync.error)throw this._sync.error}catch(e){if(e.name==="AbortError")return;throw e}finally{this._waitForFirstSyncHandle=null}}_inspectAccountAfterLogin(e,t){return t.wrap("inspectAccount",async s=>{var c;this._status.set(W.QueryAccount);const i=new ws({homeserver:e.homeServer,accessToken:e.accessToken,request:this._platform.request}),r=await this._olmPromise;let o;try{o=await Qu(i,r,this._platform,s)}catch(l){if(l.name==="HomeServerError")s.set("not_supported",!0);else throw l}if(o){let l;const h=new Promise(u=>l=u);this._accountSetup=new e_(o,l),this._status.set(W.AccountSetup),await h;const a=(c=this._accountSetup)==null?void 0:c._dehydratedDevice;return this._accountSetup=null,a}})}get accountSetup(){return this._accountSetup}get loadStatus(){return this._status}get loadError(){return this._error}get loginFailure(){return this._loginFailure}get sync(){return this._sync}get session(){return this._session}get reconnector(){return this._reconnector}get _isDisposed(){return!this._reconnector}startLogout(e){return this._platform.logger.run("logout",async t=>{this._sessionId=e,t.set("id",this._sessionId);const s=await this._platform.sessionInfoStorage.get(this._sessionId);if(!s)throw new Error(`Could not find session for id ${this._sessionId}`);try{await new ws({homeserver:s.homeServer,accessToken:s.accessToken,request:this._platform.request}).logout({log:t}).response()}catch{}await this.deleteSession(t)})}startForcedLogout(e){return this._platform.logger.run("forced-logout",async t=>{this._sessionId=e,t.set("id",this._sessionId),await this.deleteSession(t)})}dispose(){this._reconnectSubscription&&(this._reconnectSubscription(),this._reconnectSubscription=null),this._reconnector=null,this._requestScheduler&&(this._requestScheduler.stop(),this._requestScheduler=null),this._sync&&(this._sync.stop(),this._sync=null),this._session&&(this._session.dispose(),this._session=null),this._waitForFirstSyncHandle&&(this._waitForFirstSyncHandle.dispose(),this._waitForFirstSyncHandle=null),this._storage&&(this._storage.close(),this._storage=null)}async deleteSession(e){this._sessionId&&(this.dispose(),await Promise.all([e.wrap("storageFactory",()=>this._platform.storageFactory.delete(this._sessionId)),e.wrap("sessionInfoStorage",()=>this._platform.sessionInfoStorage.delete(this._sessionId))]),this._sessionId=null)}_resetStatus(){this._status.set(W.NotLoading),this._error=null,this._loginFailure=null}}class e_{constructor(e,t){this._encryptedDehydratedDevice=e,this._dehydratedDevice=void 0,this._finishStage=t}get encryptedDehydratedDevice(){return this._encryptedDehydratedDevice}finish(e){this._dehydratedDevice=e,this._finishStage()}}class L extends $t{constructor(e){super(),this._isDisposed=!1,this._options=e}childOptions(e){return Object.assign({},this._options,e)}get options(){return this._options}getOption(e){return this._options[e]}observeNavigation(e,t){const i=this.navigation.observe(e).subscribe(r=>{t(r,e)});this.track(i)}track(e){return this.disposables||(this.disposables=new li),this.disposables.track(e)}untrack(e){if(this.disposables)return this.disposables.untrack(e)}dispose(){this.disposables&&this.disposables.dispose(),this._isDisposed=!0}get isDisposed(){return this._isDisposed}disposeTracked(e){if(this.disposables)return this.disposables.disposeTracked(e)}i18n(e,...t){let s="";for(let i=0;it.toLowerCase().trim())}matches(e){const t=e.name.toLowerCase();return this._parts.every(s=>t.includes(s))}}class o_{constructor(e){this._observables=new Map,this._allowsChild=e,this._path=new Tt([],e),this._pathObservable=new Vt(this._path)}get pathObservable(){return this._pathObservable}get path(){return this._path}push(e,...t){const s=this.path.with(new ze(e,...t));s&&this.applyPath(s)}applyPath(e){const t=this._path;this._path=e;for(let s=t.segments.length-1;s>=0;s-=1){const i=t.segments[s];if(!this._path.get(i.type)){const r=this._observables.get(i.type);r==null||r.emitIfChanged()}}for(const s of this._path.segments){const i=this._observables.get(s.type);i==null||i.emitIfChanged()}this._pathObservable.set(this._path)}observe(e){let t=this._observables.get(e);return t||(t=new c_(this,e),this._observables.set(e,t)),t}pathFrom(e){let t,s;for(s=0;s=-1)}until(e){const t=this._segments.findIndex(s=>s.type===e);return t!==-1?new Tt(this._segments.slice(0,t+1),this._allowsChild):new Tt([],this._allowsChild)}get(e){return this._segments.find(t=>t.type===e)}replace(e){const t=this._segments.findIndex(s=>s.type===e.type);if(t!==-1){const s=this._segments[t-1];if(this._allowsChild(s,e)){const i=this._segments[t+1];if(!i||this._allowsChild(e,i)){const r=this._segments.slice();return r[t]=e,new Tt(r,this._allowsChild)}}}}get segments(){return this._segments}}class c_ extends yt{constructor(e,t){var s;super(),this._navigation=e,this._type=t,this._lastSetValue=(s=e.path.get(t))==null?void 0:s.value}get(){const t=this._navigation.path.get(this._type);return t==null?void 0:t.value}emitIfChanged(){const e=this.get();a_(e,this._lastSetValue)||(this._lastSetValue=e,this.emit(e))}}class l_{constructor(e,t,s,i){this._isApplyingUrl=!1,this._history=e,this._navigation=t,this._parseUrlPath=s,this._stringifyPath=i,this._defaultSessionId=this._getLastSessionId()}_getLastSessionId(){var s;const t=(s=this._urlAsNavPath(this._history.getLastSessionUrl()||"").get("session"))==null?void 0:s.value;if(typeof t=="string")return t}attach(){this._subscription=this._history.subscribe(e=>this._applyUrl(e)),this._pathSubscription=this._navigation.pathObservable.subscribe(e=>this._applyNavPathToHistory(e)),this._applyUrl(this._history.get())}dispose(){this._subscription&&(this._subscription=this._subscription()),this._pathSubscription&&(this._pathSubscription=this._pathSubscription())}_applyNavPathToHistory(e){const t=this.urlForPath(e);t!==this._history.get()&&(this._isApplyingUrl?this._history.replaceUrlSilently(t):this._history.pushUrlSilently(t))}_applyNavPathToNavigation(e){this._isApplyingUrl=!0,this._navigation.applyPath(e),this._isApplyingUrl=!1}_urlAsNavPath(e){const t=this._history.urlAsPath(e);return this._navigation.pathFrom(this._parseUrlPath(t,this._navigation.path,this._defaultSessionId))}_applyUrl(e){const t=this._urlAsNavPath(e);this._applyNavPathToNavigation(t)}pushUrl(e){this._history.pushUrl(e)}tryRestoreLastUrl(){const e=this._urlAsNavPath(this._history.getLastSessionUrl()||"");return e.segments.length!==0?(this._applyNavPathToNavigation(e),!0):!1}urlForSegments(e){let t=this._navigation.path;for(const s of e)if(t=t.with(s),!t)return;return this.urlForPath(t)}urlForSegment(e,...t){return this.urlForSegments([this._navigation.segment(e,...t)])}urlUntilSegment(e){return this.urlForPath(this._navigation.path.until(e))}urlForPath(e){return this._history.pathAsUrl(this._stringifyPath(e))}openRoomActionUrl(e){const t=`${this._stringifyPath(this._navigation.path.until("session"))}/open-room/${encodeURIComponent(e)}`;return this._history.pathAsUrl(t)}createSSOCallbackURL(){return window.location.href}normalizeUrl(){const e=new URL(window.location.href);e.searchParams.delete("loginToken"),this._history.replaceUrlSilently(e.toString())}}function h_(){return new o_(u_)}function d_({history:n,navigation:e}){return new l_(n,e,__,p_)}function u_(n,e){const{type:t}=e;switch(n==null?void 0:n.type){case void 0:return t==="login"||t==="session"||t==="sso"||t==="logout";case"session":return t==="room"||t==="rooms"||t==="settings"||t==="create-room"||t==="join-room"||t==="device-verification";case"rooms":return t==="room"||t==="empty-grid-tile";case"room":return t==="lightbox"||t==="right-panel";case"right-panel":return t==="details"||t==="members"||t==="member"||t==="verification"||t==="invite";case"logout":return t==="forced";default:return!1}}function m_(n,e,t){if(n.value.includes(e))return n;{const s=t.get("empty-grid-tile"),i=t.get("room");let r=0;s?r=s.value:i&&(r=n.value.indexOf(i.value));const o=n.value.slice();return o[r]=e,new ze("rooms",o)}}function Eo(n,e,...t){n.push(new ze("right-panel")),n.push(new ze(e,...t))}function mn(n,e){const t=n.path.segments,s=t.findIndex(r=>r.type==="right-panel");let i=e;return s!==-1&&(i=e.until("room"),i=i.with(t[s]),i=i.with(t[s+1])),i}function __(n,e,t){const s=n.substring(1).split("/"),i=s[Symbol.iterator](),r=[];let o;for(;!(o=i.next()).done;){const c=o.value;if(c==="rooms"){const l=i.next().value;if(l===void 0)break;const h=l.split(",").map(p=>decodeURIComponent(p));r.push(new ze(c,h));const a=parseInt(i.next().value||"0",10),u=h[a];u?r.push(new ze("room",u)):r.push(new ze("empty-grid-tile",a))}else if(c==="open-room"){let l=i.next().value;if(!l)break;l=decodeURIComponent(l);const h=e.get("rooms");if(h&&r.push(m_(h,l,e)),r.push(new ze("room",l)),s.findIndex(p=>p==="open-room")>=s.length-2){const p=e.segments,g=p.findIndex(f=>f.type==="right-panel");g!==-1&&r.push(...p.slice(g))}}else if(c==="last-session"){let l=e.get("session");typeof(l==null?void 0:l.value)!="string"&&t&&(l=new ze("session",t)),l&&r.push(l)}else if(c==="details"||c==="members"||c==="verification"||c==="invite")Eo(r,c);else if(c==="member"){let l=i.next().value;if(!l)break;l=decodeURIComponent(l),Eo(r,c,l)}else if(c.includes("loginToken")){const l=c.split("=").pop();r.push(new ze("sso",l))}else{let l=i.next().value;l&&(l=decodeURIComponent(l)),r.push(new ze(c,l))}}return r}function p_(n){let e="",t;for(const s of n.segments){const i=g_(s.value);switch(s.type){case"rooms":e+=`/rooms/${i}`;break;case"empty-grid-tile":e+=`/${i}`;break;case"room":(t==null?void 0:t.type)==="rooms"?e+=`/${t.value.indexOf(s.value)}`:e+=`/${s.type}/${i}`;break;case"right-panel":case"sso":continue;default:e+=`/${s.type}`,i&&(e+=`/${i}`)}t=s}return e}function g_(n){return n===!0?"":Array.isArray(n)?n.map(e=>encodeURIComponent(e)).join(","):encodeURIComponent(n)}class f_ extends L{constructor(e){super(e);const{session:t}=e;this._tileViewModelsMap=this._mapTileViewModels(t.roomsBeingCreated,t.invites,t.rooms),this._tileViewModelsFilterMap=new yl(this._tileViewModelsMap),this._tileViewModels=this._tileViewModelsFilterMap.sortValues((s,i)=>s.compare(i)),this._currentTileVM=null,this._setupNavigation(),this._closeUrl=this.urlRouter.urlForSegment("session"),this._settingsUrl=this.urlRouter.urlForSegment("settings")}_mapTileViewModels(e,t,s){return t.join(e,s).mapValues((r,o)=>{var h;let c;return r.isBeingCreated?c=new r_(this.childOptions({roomBeingCreated:r,emitChange:o})):r.isInvite?c=new i_(this.childOptions({invite:r,emitChange:o})):c=new s_(this.childOptions({room:r,emitChange:o})),((h=this.navigation.path.get("room"))==null?void 0:h.value)===r.id&&(c.open(),this._updateCurrentVM(c)),c})}_updateCurrentVM(e){var t;(t=this._currentTileVM)==null||t.close(),this._currentTileVM=e}get closeUrl(){return this._closeUrl}get settingsUrl(){return this._settingsUrl}showCreateRoomView(){this.navigation.push("create-room")}showJoinRoomView(){this.navigation.push("join-room")}_setupNavigation(){const e=this.navigation.observe("room");this.track(e.subscribe(s=>this._open(s)));const t=this.navigation.observe("rooms");this.gridEnabled=!!t.get(),this.track(t.subscribe(s=>{const i=this.gridEnabled^!!s;this.gridEnabled=!!s,i&&this.emitChange("gridEnabled")}))}_open(e){var t,s;(t=this._currentTileVM)==null||t.close(),this._currentTileVM=null,e&&(this._currentTileVM=this._tileViewModelsMap.get(e),(s=this._currentTileVM)==null||s.open())}toggleGrid(){const e=this.navigation.path.get("room");let t=this.navigation.path.until("session");this.gridEnabled?e&&(t=t.with(e),t=mn(this.navigation,t)):e?(t=t.with(this.navigation.segment("rooms",[e.value])),t=t.with(e),t=mn(this.navigation,t)):(t=t.with(this.navigation.segment("rooms",[])),t=t.with(this.navigation.segment("empty-grid-tile",0))),this.navigation.applyPath(t)}get tileViewModels(){return this._tileViewModels}clearFilter(){this._tileViewModelsFilterMap.setApply(null),this._tileViewModelsFilterMap.applyOnce((e,t)=>t.hidden=!1)}setFilter(e){if(e=e.trim(),e.length===0)return this.clearFilter(),!1;{const t=!this._tileViewModelsFilterMap.hasApply(),s=new n_(e);return this._tileViewModelsFilterMap.setApply((i,r)=>{r.hidden=!s.matches(r)}),t}}}var me=(n=>(n.Message="message",n.MessageStatus="message-status",n.Announcement="announcement",n.File="file",n.Gap="gap",n.Image="image",n.Location="location",n.MissingAttachment="missing-attachment",n.Redacted="redacted",n.Video="video",n.DateHeader="date-header",n.Call="call",n.Verification="verification",n))(me||{});class Fe{constructor(e,t,s,i){this._remove=e,this._update=t,this._replace=s,this._updateParams=i}get shouldReplace(){return this._replace}get shouldRemove(){return this._remove}get shouldUpdate(){return this._update}get updateParams(){return this._updateParams}static Remove(){return new Fe(!0,!1,!1,null)}static Update(e){return new Fe(!1,!0,!1,e)}static Nothing(){return new Fe(!1,!1,!1,null)}static Replace(e){return new Fe(!1,!1,!0,e)}}class y_ extends ai{constructor(e,t){super(),this._entries=e,this._tiles=null,this._entrySubscription=null,this._tileOptions=t,this._emitSpontanousUpdate=this._emitSpontanousUpdate.bind(this)}_createTile(e){const t=this._tileOptions.tileClassForEntry(e,this._tileOptions);if(t)return new t(e,this._tileOptions)}_emitSpontanousUpdate(e,t){const s=e.lowerEntry,i=this._findTileIdx(s);this.emitUpdate(i,e,t)}onSubscribeFirst(){this._entrySubscription=this._entries.subscribe(this),this._populateTiles()}_populateTiles(){this._silent=!0,this._tiles=[];let e=null;for(let s of this._entries)(!e||!e.tryIncludeEntry(s))&&(e=this._createTile(s),e&&this._tiles.push(e));let t=null;for(let s of this._tiles)t&&t.updateNextSibling(s),s.updatePreviousSibling(t),t=s;t&&t.updateNextSibling(null);for(let s=0;s-s.compareEntry(t))}_findTileAtIdx(e,t){const s=this._getTileAtIdx(t);if(s&&s.compareEntry(e)===0)return s}_getTileAtIdx(e){return e>=0&&e=this._tiles.length)break;const i=this._tiles[s],r=s>0?this._tiles[s-1]:void 0,o=(r==null?void 0:r.shape)===me.DateHeader;i.needsDateSeparator&&!o?(e+=1,this._addTileAt(s,i.createDateSeparator())):!i.needsDateSeparator&&o&&this._removeTile(s-1,r)}}_addTileAt(e,t,s=!1){const i=e>0?this._tiles[e-1]:void 0,r=this._tiles[e];i==null||i.updateNextSibling(t),t.updatePreviousSibling(i),t.updateNextSibling(r),r==null||r.updatePreviousSibling(t),this._tiles.splice(e,0,t),s||this.emitAdd(e,t),t.setUpdateEmit(this._emitSpontanousUpdate)}onUpdate(e,t,s){if(!this._tiles)return;const i=this._findTileIdx(t),r=this._findTileAtIdx(t,i);if(r){const o=r.updateEntry(t,s);if(o.shouldReplace){const c=this._createTile(t);c?(this._replaceTile(i,r,c,o.updateParams),c.setUpdateEmit(this._emitSpontanousUpdate)):this._removeTile(i,r)}o.shouldRemove&&this._removeTile(i,r),o.shouldUpdate&&this.emitUpdate(i,r,o.updateParams)}}_replaceTile(e,t,s,i){t.dispose();const r=this._getTileAtIdx(e-1),o=this._getTileAtIdx(e+1);this._tiles[e]=s,r==null||r.updateNextSibling(s),s.updatePreviousSibling(r),s.updateNextSibling(o),o==null||o.updatePreviousSibling(s),this.emitUpdate(e,s,i)}_removeTile(e,t){const s=this._getTileAtIdx(e-1),i=this._getTileAtIdx(e+1);this._tiles.splice(e,1),t.dispose(),this.emitRemove(e,t),s==null||s.updateNextSibling(i),i==null||i.updatePreviousSibling(s),s&&s.shape===me.DateHeader&&(!i||!i.needsDateSeparator)&&this._removeTile(e-1,s)}onRemove(e,t){const s=this._findTileIdx(t),i=this._findTileAtIdx(t,s);i&&(i.removeEntry(t)?this._removeTile(s,i):this.emitUpdate(s,i))}onMove(){}[Symbol.iterator](){return this._tiles.values()}get length(){return this._tiles.length}getFirst(){return this._tiles[0]}getTileIndex(e){const t=Nt(this._tiles,e,(i,r)=>i.compare(r)),s=this._tiles[t];return(s==null?void 0:s.compare(e))===0?t:-1}sliceIterator(e,t){return this._tiles.slice(e,t)[Symbol.iterator]()}}class w_ extends L{constructor(e){super(e);const{timeline:t,tileOptions:s}=e;this._timeline=this.track(t),this._tiles=new y_(t.entries,s),this._startTile=null,this._endTile=null,this._topLoadingPromise=null,this._requestedStartTile=null,this._requestedEndTile=null,this._requestScheduled=!1,this._showJumpDown=!1}setVisibleTileRange(e,t){this._requestedStartTile=e,this._requestedEndTile=t,this._requestScheduled||(Promise.resolve().then(()=>{this._setVisibleTileRange(this._requestedStartTile,this._requestedEndTile),this._requestScheduled=!1}),this._requestScheduled=!0)}_setVisibleTileRange(e,t){let s;if(e&&t){this._startTile=e,this._endTile=t;const i=this._tiles.getTileIndex(this._startTile),r=this._tiles.getTileIndex(this._endTile);for(const o of this._tiles.sliceIterator(i,r+1))o.notifyVisible();s=i<10,this._setShowJumpDown(r{this._topLoadingPromise=null,i||this.setVisibleTileRange(this._requestedStartTile,this._requestedEndTile)}))}get tiles(){return this._tiles}_setShowJumpDown(e){this._showJumpDown!==e&&(this._showJumpDown=e,this.emitChange("showJumpDown"))}get showJumpDown(){return this._showJumpDown}}class v_ extends L{constructor(e){super(e.options),this._roomVM=e,this._isEmpty=!0,this._replyVM=null}setReplyingTo(e){var s;(new Boolean(e)!==new Boolean(this._replyVM)||!((s=this._replyVM)!=null&&s.id.equals(e.asEventKey())))&&(this._replyVM=this.disposeTracked(this._replyVM),e&&(this._replyVM=this.track(this._roomVM._createTile(e)),this._replyVM.notifyVisible()),this.emitChange("replyViewModel"),this.emit("focus"))}clearReplyingTo(){this.setReplyingTo(null)}get replyViewModel(){return this._replyVM}get isEncrypted(){return this._roomVM.isEncrypted}async sendMessage(e){const t=await this._roomVM._sendMessage(e,this._replyVM);return t&&(this._isEmpty=!0,this.emitChange("canSend"),this.clearReplyingTo()),t}sendPicture(){this._roomVM._pickAndSendPicture()}sendFile(){this._roomVM._pickAndSendFile()}sendVideo(){this._roomVM._pickAndSendVideo()}get canSend(){return!this._isEmpty}async setInput(e){const t=this._isEmpty;this._isEmpty=e.length===0,t&&!this._isEmpty&&this._roomVM._room.ensureMessageKeyIsShared(),t!==this._isEmpty&&this.emitChange("canSend")}get kind(){return"composer"}}async function b_(n,e,t,s){const i=new Map;n.text&&i.set("text",n.text),i.set("user_agent",n.userAgent),i.set("app",n.app),i.set("version",n.version),n.label&&i.set("label",n.label),i.set("file",{name:"logs.json",blob:e});const r=new Map;r.set("Accept","application/json");const o=s(t,{method:"POST",body:i,headers:r});let c;try{c=await o.response()}catch(a){throw new Error(`Could not submit logs to ${t}, got error ${a.message}`)}const{status:l,body:h}=c;if(l<200||l>=300)throw new Error(`Could not submit logs to ${t}, got status code ${l} with body ${h}`)}async function cc(n,e){const{bugReportEndpointUrl:t}=e.config;if(!t)throw new Error("no server configured to submit logs");const i=e.logger.reporters.find(o=>!!o.export);if(!i)throw new Error("No logger that can export configured");const r=await i.export();await b_({app:"hydrogen",userAgent:e.description,version:e.version,text:`Submit logs from settings for user ${n.userId} on device ${n.deviceId}`},r.asBlob(),t,e.request)}class S_ extends L{get message(){return this.error.message}get error(){return this.getOption("error")}close(){this.getOption("onClose")()}async submitLogs(){try{return await cc(this.getOption("session"),this.platform),!0}catch{return!1}}}class ot extends L{get errorViewModel(){return this._errorViewModel}reportError(e){var t;((t=this._errorViewModel)==null?void 0:t.error)!==e&&(this.disposeTracked(this._errorViewModel),this._errorViewModel=this.track(new S_(this.childOptions({error:e,onClose:()=>{this._errorViewModel=this.disposeTracked(this._errorViewModel),this.emitChange("errorViewModel")}}))),this.emitChange("errorViewModel"))}logAndCatch(e,t,s=void 0){try{let i=this.logger.run(e,t);return i instanceof Promise&&(i=i.catch(r=>(this.reportError(r),s))),i}catch(i){return this.reportError(i),s}}}class Ro extends ot{constructor(e){super(e);const t=new tl(this.call,"change");this.track(t.subscribe(()=>this.onUpdate()));const s=new Ml("self",t).mapValues((r,o)=>new k_(this.childOptions({call:r,emitChange:o})),()=>{}),i=this.call.members.filterValues(r=>r.isConnected).mapValues((r,o)=>new Pn(this.childOptions({member:r,emitChange:o,mediaRepository:this.getOption("room").mediaRepository})),(r,o)=>o==null?void 0:o.onUpdate());this.memberViewModels=i.join(s).sortValues((r,o)=>r.compare(o)),this.track(this.memberViewModels.subscribe({onRemove:()=>{this.emitChange()},onAdd:()=>{this.emitChange()},onUpdate:()=>{},onReset:()=>{},onMove:()=>{}}))}get isCameraMuted(){var e,t;return(t=(e=this.call.muteSettings)==null?void 0:e.camera)!=null?t:!0}get isMicrophoneMuted(){var e,t;return(t=(e=this.call.muteSettings)==null?void 0:e.microphone)!=null?t:!0}get memberCount(){return this.memberViewModels.length}get name(){return this.call.name}get id(){return this.call.id}get call(){return this.getOption("call")}onUpdate(){this.call.error&&this.reportError(this.call.error)}async hangup(){this.logAndCatch("CallViewModel.hangup",async e=>{this.call.hasJoined&&await this.call.leave(e)})}async toggleCamera(){this.logAndCatch("Call.toggleCamera",async e=>{const{localMedia:t,muteSettings:s}=this.call;if(s&&t){if(s.camera&&!xt(t.userMedia)){const i=await this.platform.mediaDevices.getMediaTracks(!s.microphone,!0);await this.call.setMedia(t.withUserMedia(i))}else await this.call.setMuted(s.toggleCamera());this.emitChange()}})}async toggleMicrophone(){this.logAndCatch("Call.toggleMicrophone",async e=>{const{localMedia:t,muteSettings:s}=this.call;if(s&&t){if(s.microphone&&!is(t.userMedia)){const i=await this.platform.mediaDevices.getMediaTracks(!0,!s.camera);await this.call.setMedia(t.withUserMedia(i))}else await this.call.setMuted(s.toggleMicrophone());this.emitChange()}})}}class k_ extends ot{constructor(e){super(e),this.init()}async init(){const e=this.getOption("room");this.memberObservable=await e.observeMember(e.user.id),this.track(this.memberObservable.subscribe(()=>{this.emitChange(void 0)}))}get errorViewModel(){}get stream(){var e;return(e=this.call.localPreviewMedia)==null?void 0:e.userMedia}get call(){return this.getOption("call")}get isCameraMuted(){var e,t;return(t=(e=this.call.muteSettings)==null?void 0:e.camera)!=null?t:!0}get isMicrophoneMuted(){var e,t;return(t=(e=this.call.muteSettings)==null?void 0:e.microphone)!=null?t:!0}get avatarLetter(){var t;const e=(t=this.memberObservable)==null?void 0:t.get();return e?Ee(e.name):this.getOption("room").user.id}get avatarColorNumber(){return Re(this.getOption("room").user.id)}avatarUrl(e){var s;const t=(s=this.memberObservable)==null?void 0:s.get();if(t)return Be(t.avatarUrl,e,this.platform,this.getOption("room").mediaRepository)}get avatarTitle(){var t;const e=(t=this.memberObservable)==null?void 0:t.get();return e?e.name:this.getOption("room").user.id}compare(e){return-1}}class Pn extends ot{get stream(){var e;return(e=this.member.remoteMedia)==null?void 0:e.userMedia}get member(){return this.getOption("member")}get isCameraMuted(){var e,t;return(t=(e=this.member.remoteMuteSettings)==null?void 0:e.camera)!=null?t:!0}get isMicrophoneMuted(){var e,t;return(t=(e=this.member.remoteMuteSettings)==null?void 0:e.microphone)!=null?t:!0}get avatarLetter(){return Ee(this.member.member.name)}get avatarColorNumber(){return Re(this.member.userId)}avatarUrl(e){const{avatarUrl:t}=this.member.member,s=this.getOption("mediaRepository");return Be(t,e,this.platform,s)}get avatarTitle(){return this.member.member.name}onUpdate(){this.mapMemberSyncErrorIfNeeded()}mapMemberSyncErrorIfNeeded(){this.member.error&&this.reportError(this.member.error)}compare(e){if(e instanceof Pn){const t=this.member.member.userId,s=e.member.member.userId;return t===s?0:t0){const s=is(t);s&&(s.stop(),t.removeTrack(s))}return e}replaceClone(e,t){const s=(i,r,o)=>(i==null?void 0:i.id)===(o==null?void 0:o.id)?r:o==null?void 0:o.clone();return new At(s(t==null?void 0:t.userMedia,e==null?void 0:e.userMedia,this.userMedia),s(t==null?void 0:t.screenShare,e==null?void 0:e.screenShare,this.screenShare),this.dataChannelOptions)}clone(){var e,t;return new At((e=this.userMedia)==null?void 0:e.clone(),(t=this.screenShare)==null?void 0:t.clone(),this.dataChannelOptions)}dispose(){var e,t,s;(e=is(this.userMedia))==null||e.stop(),(t=xt(this.userMedia))==null||t.stop(),(s=xt(this.screenShare))==null||s.stop()}}class I_ extends L{constructor(e,t){super(t),this._firstTileInDay=e}setUpdateEmit(e){this._emitUpdate=e}get upperEntry(){return this.refEntry}get lowerEntry(){return this.refEntry}get refEntry(){return this._firstTileInDay.lowerEntry}compare(e){return this.compareEntry(e.upperEntry)}get relativeDate(){return this._dateString||(this._dateString=this.timeFormatter.formatRelativeDate(new Date(this.refEntry.timestamp))),this._dateString}get machineReadableDate(){return this._machineReadableString||(this._machineReadableString=this.timeFormatter.formatMachineReadableDate(new Date(this.refEntry.timestamp))),this._machineReadableString}get shape(){return me.DateHeader}get needsDateSeparator(){return!1}createDateSeparator(){}compareEntry(e){const t=this.refEntry.compare(e);return t===0?-1:t}updateEntry(e,t){return Fe.Nothing()}removeEntry(e){return!1}tryIncludeEntry(){return!1}get comparisonIsNotCommutative(){return!0}updatePreviousSibling(e){this._firstTileInDay.updatePreviousSibling(e)}updateNextSibling(e){var s;if(!e)return;this._firstTileInDay=e;const t=this._dateString;this._dateString=void 0,this._machineReadableString=void 0,t&&t!==this.relativeDate&&((s=this._emitUpdate)==null||s.call(this,this,"relativeDate"))}notifyVisible(){}dispose(){}}class xs extends ot{constructor(e,t){super(t),this._needsDateSeparator=!1,this._entry=e,this._date=this._entry.timestamp?new Date(this._entry.timestamp):void 0}get isContinuation(){return!1}get needsDateSeparator(){return this._needsDateSeparator}createDateSeparator(){return new I_(this,this.childOptions({}))}_updateDateSeparator(e){e&&e._date&&this._date?this._needsDateSeparator=e._date.getFullYear()!==this._date.getFullYear()||e._date.getMonth()!==this._date.getMonth()||e._date.getDate()!==this._date.getDate():this._needsDateSeparator=!!this._date}get id(){return this._entry.asEventKey()}get eventId(){return this._entry.id}get isPending(){return this._entry.isPending}get isUnsent(){return this._entry.isPending&&this._entry.pendingEvent.status!==X.Sent}get canAbortSending(){return this._entry.isPending&&!this._entry.pendingEvent.hasStartedSending}async abortSending(){var e;await((e=this._entry.pendingEvent)==null?void 0:e.abort())}setUpdateEmit(e){this._emitUpdate=e}emitChange(e){this._emitUpdate&&this._emitUpdate(this,e),super.emitChange(e)}get upperEntry(){return this._entry}get lowerEntry(){return this._entry}get comparisonIsNotCommutative(){return!1}compare(e){return e.comparisonIsNotCommutative?-e.compare(this):this.upperEntry.compare(e.upperEntry)}compareEntry(e){return this._entry.compare(e)}updateEntry(e,t){const s=this.shape==="redacted";return!e.isGap&&e.isRedacted!==s?Fe.Replace("shape"):(this._entry=e,Fe.Update(t))}removeEntry(){return!0}tryIncludeEntry(){return!1}updatePreviousSibling(e){(e==null?void 0:e.shape)!==me.DateHeader&&this._updateDateSeparator(e)}updateNextSibling(){}notifyVisible(){}dispose(){this.setUpdateEmit(void 0),super.dispose()}get _room(){return this._roomVM.room}get _roomVM(){return this.options.roomVM}get _timeline(){return this.options.timeline}get _powerLevels(){return this._timeline.powerLevels}get _ownMember(){return this.options.timeline.me}get displayName(){return this._entry.displayName||this.sender}get sender(){return this._entry.sender}}class M_ extends xs{constructor(e,t){super(e,t),this._loading=!1,this._waitingForConnection=!1,this._isAtTop=!0,this._siblingChanged=!1}get needsDateSeparator(){return!1}async fill(e=!1){if(!this._loading&&!this._entry.edgeReached){this._loading=!0,this.emitChange("isLoading");try{await this._room.fillGap(this._entry,10)}catch(t){return t instanceof Ut?(await this._waitForReconnection(),e?!1:await this.fill(!0)):(this.reportError(t),!1)}finally{this._loading=!1,this.emitChange("isLoading")}return!0}return!1}async notifyVisible(){if(this.errorViewModel)return;let e=0,t;this._siblingChanged=!1;do t=await this.fill(),e=e+1;while(e<10&&!this._siblingChanged&&t&&!this.isDisposed)}get isAtTop(){return this._isAtTop}updatePreviousSibling(e){super.updatePreviousSibling(e);const t=!e;this._isAtTop!==t&&(this._isAtTop=t,this.emitChange("isAtTop")),this._siblingChanged=!0}updateNextSibling(){this._siblingChanged=!0}updateEntry(e,t){return super.updateEntry(e,t),e.isGap?Fe.Nothing():Fe.Remove()}async _waitForReconnection(){this._waitingForConnection=!0,this.emitUpdate("status"),await this.options.client.reconnector.connectionStatus.waitFor(e=>e===Ys.Online).promise,this._waitingForConnection=!1,this.emitUpdate("status")}get shape(){return"gap"}get isLoading(){return this._loading}get showSpinner(){return this.isLoading||this._waitingForConnection}get status(){const e=this._entry.prev_batch?"previous":"next";return this._waitingForConnection?"Waiting for connection\u2026":this.errorViewModel?`Could not load ${e} messages`:this.isLoading?"Loading more messages\u2026":"Gave up loading more messages"}}class C_{constructor(e){this._parentTile=e,this._map=new Dt,this._reactions=this._map.sortValues((t,s)=>t._compare(s))}update(e,t){if(e){for(const s in e)if(e.hasOwnProperty(s)){const i=e[s],r=this._map.get(s);r?r._tryUpdate(i)&&this._map.update(s):this._map.add(s,new To(s,i,null,this._parentTile))}}if(t)for(const[s,i]of t.entries()){const r=this._map.get(s);r?(r._tryUpdatePending(i),this._map.update(s)):this._map.add(s,new To(s,null,i,this._parentTile))}for(const s of this._map.keys()){const i=t==null?void 0:t.has(s),r=e==null?void 0:e.hasOwnProperty(s);!r&&!i?this._map.remove(s):r?i||this._map.get(s)._tryUpdatePending(null)&&this._map.update(s):this._map.get(s)._tryUpdate(null)&&this._map.update(s)}}get reactions(){return this._reactions}getReaction(e){return this._map.get(e)}}class To{constructor(e,t,s,i){this._key=e,this._annotation=t,this._pending=s,this._parentTile=i,this._isToggling=!1}_tryUpdate(e){const t=!!this._annotation!=!!e,i=this._annotation&&e&&(e.me!==this._annotation.me||e.count!==this._annotation.count||e.firstTimestamp!==this._annotation.firstTimestamp);return t||i?(this._annotation=e,!0):!1}_tryUpdatePending(e){return!e&&!this._pending?!1:(this._pending=e,!0)}get key(){return this._key}get count(){var e,t;return(((e=this._pending)==null?void 0:e.count)||0)+(((t=this._annotation)==null?void 0:t.count)||0)}get isPending(){return this._pending!==null}get isActive(){var e;return((e=this._annotation)==null?void 0:e.me)||this.isPending}get firstTimestamp(){let e=Number.MAX_SAFE_INTEGER;return this._annotation&&(e=Math.min(e,this._annotation.firstTimestamp)),this._pending&&(e=Math.min(e,this._pending.firstTimestamp)),e}_compare(e){if(e===this)return 0;if(this.count!==e.count)return e.count-this.count;{const t=this.firstTimestamp-e.firstTimestamp;return t===0?this.key{var r,o;if(!this.canReact){s.set("powerlevel_lacking",!0);return}if(this._entry.haveAnnotation(e)){s.set("already_reacted",!0);return}const i=(o=(r=this._entry.pendingAnnotations)==null?void 0:r.get(e))==null?void 0:o.redactionEntry;i&&!i.pendingEvent.hasStartedSending?(s.set("abort_redaction",!0),await i.pendingEvent.abort()):await this._room.sendEvent("m.reaction",this._entry.annotate(e),null,s)})}redactReaction(e,t=null){return this.logger.wrapOrRun(t,"redactReaction",async s=>{var r,o;if(!this._powerLevels.canRedactFromSender(this._ownMember.userId)){s.set("powerlevel_lacking",!0);return}if(!this._entry.haveAnnotation(e)){s.set("not_yet_reacted",!0);return}let i=(o=(r=this._entry.pendingAnnotations)==null?void 0:r.get(e))==null?void 0:o.annotationEntry;i||(i=await this._timeline.getOwnAnnotationEntry(this._entry.id,e)),i?await this._room.sendRedaction(i.id,null,s):s.set("no_reaction",!0)})}toggleReaction(e,t=null){return this.logger.wrapOrRun(t,"toggleReaction",async s=>{this._entry.haveAnnotation(e)?await this.redactReaction(e,s):await this.react(e,s)})}_updateReactions(){const{annotations:e,pendingAnnotations:t}=this._entry;!e&&!t?this._reactions&&(this._reactions=null):(this._reactions||(this._reactions=new C_(this)),this._reactions.update(e,t))}get replyTile(){return this._entry.contextEventId?this._replyTile:null}}const E_="(?:https|http|ftp):\\/\\/",lc="[^\\s.,?!)]",Ao="[a-zA-Z0-9:.\\[\\]-]",R_=`${Ao}*(?=${Ao})${lc}`,T_=`(?:[\\/#](?:[^\\s]*${lc})?)`,A_=`${E_}${R_}${T_}?`,x_=new RegExp(A_,"gi");function hc(n,e){const t=n.matchAll(x_);let s=0;for(let r of t){const o=n.slice(s,r.index);e(o,!1),e(r[0],!0);const c=r[0].length;s=r.index+c}const i=n.slice(s);e(i,!1)}function V_(n){const e=[],t=n.split(` +`),s=(i,r)=>{r?e.push(new _n(i,[new ii(i)])):e.push(new ii(i))};for(let i=0;i=t.length-1||e.push(new dc)}return new Fn(n,e)}function N_(n){return new Fn(n,[new ii(n)])}class D_{constructor(e,t){this.level=e,this.inlines=t}get type(){return"header"}}class xo{constructor(e,t){this.language=e,this.text=t}get type(){return"codeblock"}}class U_{constructor(e,t){this.items=t,this.startOffset=e}get type(){return"list"}}class O_{constructor(e,t){this.head=e,this.body=t}get type(){return"table"}}class P_{get type(){return"rule"}}class dc{get type(){return"newline"}}class hr{constructor(e,t){this.format=e.toLowerCase(),this.children=t}get type(){return"format"}}class F_{constructor(e,t,s,i,r){this.src=e,this.width=t,this.height=s,this.alt=i,this.title=r}get type(){return"image"}}class L_{constructor(e,t,s){this.id=e,this.href=t,this.children=s}get type(){return"pill"}get avatarColorNumber(){return Re(this.id)}get avatarInitials(){return Ee(this.id)}}class _n{constructor(e,t){this.url=e,this.inlines=t}get type(){return"link"}}class ii{constructor(e){this.text=e}get type(){return"text"}}function K_(n){return n.type==="format"&&n.format==="blockquote"}class Fn{constructor(e,t){this.sourceString=e,this.parts=t}insertEmote(e){let t=0;for(;t`${n}://`),q_="https://matrix.to",Vo=`${q_}/#/`;class H_{constructor(e,t){this.result=e,this.mediaRepository=t}parsePillLink(e){if(!e.startsWith(Vo))return null;const t=e.substring(Vo.length);return t[0]==="@"?t:null}parseLink(e,t){const s=this.result.getAttributeValue(e,"href"),i=s==null?void 0:s.toLowerCase();if(!i||!j_.some(o=>i.startsWith(o)))return new hr("span",t);const r=this.parsePillLink(s);return r?new L_(r,s,t):new _n(s,t)}parseList(e){const t=this.result;let s=null;t.getNodeElementName(e)==="OL"&&(s=parseInt(t.getAttributeValue(e,"start"))||1);const i=[];for(const r of t.getChildNodes(e)){if(t.getNodeElementName(r)!=="LI")continue;const o=this.parseAnyNodes(t.getChildNodes(r));i.push(o)}return new U_(s,i)}_ensureElement(e,t){return e&&this.result.isElementNode(e)&&this.result.getNodeElementName(e)===t}parseCodeBlock(e){const t=this.result;let s;for(const o of t.getChildNodes(e)){s=o;break}let i=null;if(!this._ensureElement(s,"CODE"))return new xo(i,this.result.getNodeText(e));const r=t.getAttributeValue(s,"class")||"";for(const o of r.split(" "))if(o.startsWith("language-")&&!o.startsWith("language-_")){i=o.substring(9);break}return new xo(i,this.result.getNodeText(s))}parseImage(e){const t=this.result,s=t.getAttributeValue(e,"src")||"",i=this.mediaRepository.mxcUrl(s);if(!i)return null;const r=parseInt(t.getAttributeValue(e,"width"))||null,o=parseInt(t.getAttributeValue(e,"height"))||null,c=t.getAttributeValue(e,"alt"),l=t.getAttributeValue(e,"title");return new F_(i,r,o,c,l)}parseTableRow(e,t){const s=[];for(const i of this.result.getChildNodes(e)){if(!this._ensureElement(i,t))continue;const r=this.result.getChildNodes(i),o=this.parseInlineNodes(r);s.push(o)}return s}parseTableHead(e){let t=null;for(const s of this.result.getChildNodes(e)){t=s;break}return this._ensureElement(t,"TR")?this.parseTableRow(t,"TH"):null}parseTableBody(e){const t=[];for(const s of this.result.getChildNodes(e))!this._ensureElement(s,"TR")||t.push(this.parseTableRow(s,"TD"));return t}parseTable(e){const t=Array.from(this.result.getChildNodes(e));let s,i;return this._ensureElement(t[0],"THEAD")&&this._ensureElement(t[1],"TBODY")?(s=this.parseTableHead(t[0]),i=this.parseTableBody(t[1])):this._ensureElement(t[0],"TBODY")&&(s=null,i=this.parseTableBody(t[0])),new O_(s,i)}parseInlineElement(e){const t=this.result,s=t.getNodeElementName(e),i=t.getChildNodes(e);switch(s){case"A":{const r=this.parseInlineNodes(i);return this.parseLink(e,r)}case"BR":return new dc;default:{if(!B_.includes(s))return null;const r=this.parseInlineNodes(i);return new hr(s,r)}}}parseInlineNode(e){return this.result.isElementNode(e)?this.parseInlineElement(e):null}parseBlockElement(e){const t=this.result,s=t.getNodeElementName(e),i=t.getChildNodes(e);switch(s){case"H1":case"H2":case"H3":case"H4":case"H5":case"H6":{const r=this.parseInlineNodes(i);return new D_(parseInt(s[1]),r)}case"UL":case"OL":return this.parseList(e);case"PRE":return this.parseCodeBlock(e);case"HR":return new P_;case"IMG":return this.parseImage(e);case"P":{const r=this.parseInlineNodes(i);return new hr(s,r)}case"TABLE":return this.parseTable(e);default:{if(!$_.includes(s))return null;const r=this.parseAnyNodes(i);return new hr(s,r)}}}parseBlockNode(e){return this.result.isElementNode(e)?this.parseBlockElement(e):null}_parseTextParts(e,t){if(!this.result.isTextNode(e))return!1;const s=(i,r)=>{r?t.push(new _n(i,[new ii(i)])):t.push(new ii(i))};return hc(this.result.getNodeText(e),s),!0}_isAllowedNode(e){return!this._ensureElement(e,"MX-REPLY")}_parseInlineNodes(e,t){for(const s of e){if(this._parseTextParts(s,t))continue;const i=this.parseInlineNode(s);if(i){t.push(i);continue}this._isAllowedNode(s)&&this._parseInlineNodes(this.result.getChildNodes(s),t)}}parseInlineNodes(e){const t=[];return this._parseInlineNodes(e,t),t}_parseAnyNodes(e,t){for(const s of e){if(this._parseTextParts(s,t))continue;const i=this.parseInlineNode(s)||this.parseBlockNode(s);if(i){t.push(i);continue}this._isAllowedNode(s)&&this._parseAnyNodes(this.result.getChildNodes(s),t)}}parseAnyNodes(e){const t=[];return this._parseAnyNodes(e,t),t}}function W_(n,e,t){const s=n.parseHTML(t),r=new H_(s,e).parseAnyNodes(s.rootNodes);return new Fn(t,r)}class z_ extends uc{_getContentString(e){var t;return((t=this._getContent())==null?void 0:t[e])||""}_getPlainBody(){return this._getContentString("body")}_getFormattedBody(){return this._getContentString("formatted_body")}_getBody(){return this._getBodyFormat()===Ti.Html?this._getFormattedBody():this._getPlainBody()}_getBodyFormat(){var e;return((e=this._getContent())==null?void 0:e.format)==="org.matrix.custom.html"?Ti.Html:Ti.Plain}_parseBody(e,t){var i;let s;return t===Ti.Html?s=W_(this.platform,this._mediaRepository,e):s=V_(e),((i=this._getContent())==null?void 0:i.msgtype)==="m.emote"&&s.insertEmote(`* ${this.displayName} `),s}}class No extends ns{get shape(){return"redacted"}get description(){const{redactionReason:e}=this._entry;return this.isRedacting?e?this.i18n`This message is being deleted (${e})…`:this.i18n`This message is being deleted…`:e?this.i18n`This message has been deleted (${e}).`:this.i18n`This message has been deleted.`}get isRedacting(){return this._entry.isRedacting}get canRedact(){return!1}abortPendingRedaction(){return this._entry.abortPendingRedaction()}}const G_=300,Y_=400;class mc extends ns{constructor(e,t){super(e,t),this._decryptedThumbnail=null,this._decryptedFile=null,this._isVisible=!1,this._error=null,this._downloading=!1,this._downloadError=null}async downloadMedia(){if(this._downloading||this.isPending)return;const e=this._getContent(),t=e.body;this._downloading=!0,this.emitChange("status");let s;try{s=await this._mediaRepository.downloadAttachment(e),this.platform.saveFileAs(s,t)}catch(i){this._downloadError=i}finally{s==null||s.dispose(),this._downloading=!1}this.emitChange("status")}get isUploading(){return this.isPending&&this._entry.pendingEvent.status===X.UploadingAttachments}get uploadPercentage(){const{pendingEvent:e}=this._entry;return e&&Math.round(e.attachmentsSentBytes/e.attachmentsTotalBytes*100)}get status(){const{pendingEvent:e}=this._entry;switch(e==null?void 0:e.status){case X.Waiting:return this.i18n`Waiting…`;case X.EncryptingAttachments:case X.Encrypting:return this.i18n`Encrypting…`;case X.UploadingAttachments:return this.i18n`Uploading…`;case X.Sending:return this.i18n`Sending…`;case X.Error:return this.i18n`Error: ${e.error.message}`;default:return this._downloadError?"Download failed":this._downloading?this.i18n`Downloading…`:""}}get thumbnailUrl(){var e,t;if(!this._isVisible)return"";if(this._decryptedThumbnail)return this._decryptedThumbnail.url;{const s=(e=this._getContent().info)==null?void 0:e.thumbnail_url;if(s)return this._mediaRepository.mxcUrlThumbnail(s,this.width,this.height,"scale")}if(this._entry.isPending){const s=this._entry.pendingEvent.getAttachment("info.thumbnail_url");return s&&s.localPreview.url}if(this._isMainResourceImage()){if(this._decryptedFile)return this._decryptedFile.url;{const s=(t=this._getContent())==null?void 0:t.url;if(typeof s=="string")return this._mediaRepository.mxcUrlThumbnail(s,this.width,this.height,"scale")}}return""}notifyVisible(){super.notifyVisible(),this._isVisible=!0,this.emitChange("thumbnailUrl"),this.isPending||this._tryLoadEncryptedThumbnail()}get width(){var t;const e=(t=this._getContent())==null?void 0:t.info;return Math.round((e==null?void 0:e.w)*this._scaleFactor())}get height(){var t;const e=(t=this._getContent())==null?void 0:t.info;return Math.round((e==null?void 0:e.h)*this._scaleFactor())}get mimeType(){var t;const e=(t=this._getContent())==null?void 0:t.info;return e==null?void 0:e.mimetype}get label(){return this._getContent().body}get error(){return this._error?`Could not load media: ${this._error.message}`:null}setViewError(e){this._error=e,this.emitChange("error")}async _loadEncryptedFile(e){const t=await this._mediaRepository.downloadEncryptedFile(e,!0);if(this.isDisposed){t.dispose();return}return this.track(t)}async _tryLoadEncryptedThumbnail(){var e;try{const t=(e=this._getContent().info)==null?void 0:e.thumbnail_file,s=this._getContent().file;t?(this._decryptedThumbnail=await this._loadEncryptedFile(t),this.emitChange("thumbnailUrl")):s&&this._isMainResourceImage()&&(this._decryptedFile=await this._loadEncryptedFile(s),this.emitChange("thumbnailUrl"))}catch(t){this._error=t,this.emitChange("error")}}_scaleFactor(){var i;const e=(i=this._getContent())==null?void 0:i.info,t=G_/(e==null?void 0:e.h),s=Y_/(e==null?void 0:e.w);return Math.min(s,t,1)}_isMainResourceImage(){return!0}}class J_ extends mc{constructor(e,t){super(e,t),this._lightboxUrl=this.urlRouter.urlForSegments([this.navigation.segment("room",this._room.id),this.navigation.segment("lightbox",this._entry.id)])}get lightboxUrl(){return this.isPending?"":this._lightboxUrl}get shape(){return"image"}}class Q_ extends mc{async loadVideo(){const e=this._getContent().file;e&&!this._decryptedFile&&(this._decryptedFile=await this._loadEncryptedFile(e),this.emitChange("videoUrl"))}get videoUrl(){var t;if(this._decryptedFile)return this._decryptedFile.url;const e=(t=this._getContent())==null?void 0:t.url;return typeof e=="string"?this._mediaRepository.mxcUrl(e):""}get shape(){return"video"}_isMainResourceImage(){return!1}}function X_(n,e=2){if(Number.isSafeInteger(n)){const t=Math.min(3,Math.floor(Math.log(n)/Math.log(1024))),s=Math.round(n/Math.pow(1024,t)).toFixed(e);switch(t){case 0:return`${s} bytes`;case 1:return`${s} KB`;case 2:return`${s} MB`;case 3:return`${s} GB`}}return""}class Z_ extends ns{constructor(e,t){super(e,t),this._downloadError=null,this._downloading=!1}async download(){if(this._downloading||this.isPending)return;const e=this._getContent(),t=e.body;this._downloading=!0,this.emitChange("label");let s;try{s=await this._mediaRepository.downloadAttachment(e),this.platform.saveFileAs(s,t)}catch(i){this._downloadError=i}finally{s==null||s.dispose(),this._downloading=!1}this.emitChange("label")}get label(){var s;if(this._downloadError)return`Could not download file: ${this._downloadError.message}`;const t=this._getContent().body;if(this._entry.isPending){const{pendingEvent:i}=this._entry;switch(i==null?void 0:i.status){case X.Waiting:return this.i18n`Waiting to send ${t}…`;case X.EncryptingAttachments:case X.Encrypting:return this.i18n`Encrypting ${t}…`;case X.UploadingAttachments:{const r=Math.round(i.attachmentsSentBytes/i.attachmentsTotalBytes*100);return this.i18n`Uploading ${t}: ${r}%`}case X.Sending:case X.Sent:return this.i18n`Sending ${t}…`;case X.Error:return this.i18n`Error: could not send ${t}: ${i.error.message}`;default:return`Unknown send status for ${t}`}}else{const i=X_((s=this._getContent().info)==null?void 0:s.size);return this._downloading?this.i18n`Downloading ${t} (${i})…`:this.i18n`Download ${t} (${i})`}}get shape(){return"file"}}class ep extends ns{get shape(){return"location"}get mapsLink(){try{const e=new URL(this._getContent().geo_uri);if(e.protocol!=="geo:")return"";const[t,...s]=e.pathname.split(";"),[i,r]=t.split(","),o=parseFloat(i),c=parseFloat(r);let l;for(const h of s){const[a,u]=h.split("=");a==="u"&&(l=parseFloat(u))}if(this.platform.isIOS)return`http://maps.apple.com/?ll=${o},${c}`;{let h=`geo:${o},${c}`;return l&&(h=h+`;u=${l}`),h}}catch{return""}}get label(){return this.i18n`${this.displayName} sent their location`}}class tp extends xs{get shape(){return"announcement"}get announcement(){const e=this._entry.content;return`${this._entry.displayName||this._entry.sender} named the room "${e==null?void 0:e.name}"`}}class sp extends xs{get shape(){return"announcement"}get announcement(){var h,a;const{sender:e,content:t,prevContent:s,stateKey:i}=this._entry,r=this._entry.displayName||e,o=e===i?r:((h=this._entry.content)==null?void 0:h.displayname)||i,c=t&&t.membership,l=s&&s.membership;if(l==="join"&&c==="join"){if(t.avatar_url!==s.avatar_url)return`${r} changed their avatar`;if(t.displayname!==s.displayname)return t.displayname?`${(a=s.displayname)!=null?a:i} changed their name to ${t.displayname}`:`${i} removed their name (${s.displayname})`}else{if(c==="join")return`${o} joined the room`;if(c==="invite")return`${o} was invited to the room by ${r}`;if(l==="invite"){if(c==="join")return`${o} accepted the invitation to join the room`;if(c==="leave")return`${o} declined the invitation to join the room`}else if(c==="leave"){if(i===e)return`${o} left the room`;{const u=t.reason;return`${o} was kicked from the room by ${r}${u?`: ${u}`:""}`}}else if(c==="ban")return`${o} was banned from the room by ${r}`}return`${e} membership changed to ${t.membership}`}}class ip extends uc{updateEntry(e,t){const s=super.updateEntry(e,t);return e.eventType!=="m.room.encrypted"?Fe.Replace("shape"):s}get shape(){return"message-status"}_getBody(){const e=this._entry.decryptionError,t=e==null?void 0:e.code;let s;return t==="MEGOLM_NO_SESSION"?s=this.i18n`The sender hasn't sent us the key for this message yet.`:s=(e==null?void 0:e.message)||this.i18n`Could not decrypt message because of unknown reason.`,s}}class rp extends xs{get shape(){return"announcement"}get announcement(){const e=this._entry.displayName||this._entry.sender;return this.i18n`${e} has enabled end-to-end encryption`}}class np extends ns{get shape(){return"missing-attachment"}get label(){const e=this._getContent().body;return this._getContent().msgtype==="m.image"?this.i18n`The image ${e} wasn't fully sent previously and could not be recovered.`:this.i18n`The file ${e} wasn't fully sent previously and could not be recovered.`}}class op extends xs{constructor(e,t){super(e,t);const s=this.getOption("session").callHandler.calls;this._callSubscription=void 0,this._memberSizeSubscription=void 0;const i=s.get(this._entry.stateKey);i&&!i.isTerminated&&(this._call=i,this.memberViewModels=this._setupMembersList(this._call),this._callSubscription=this.track(this._call.disposableOn("change",()=>{this._onCallUpdate()})),this._memberSizeSubscription=this.track(this._call.members.observeSize().subscribe(()=>{this.emitChange("memberCount")})),this._onCallUpdate())}_onCallUpdate(){this._call.isTerminated?(this._durationInterval=this.disposeTracked(this._durationInterval),this._callSubscription=this.disposeTracked(this._callSubscription),this._call=void 0):this._durationInterval||(this._durationInterval=this.track(this.platform.clock.createInterval(()=>{this.emitChange("duration")},1e3))),this.emitChange()}_setupMembersList(e){return e.members.mapValues((t,s)=>new ap(this.childOptions({member:t,emitChange:s,mediaRepository:this.getOption("room").mediaRepository}))).sortValues((t,s)=>t.userId.localeCompare(s.userId))}get memberCount(){return this._call?this._call.members.size:0}get confId(){return this._entry.stateKey}get duration(){return this._call&&this._call.duration?this.timeFormatter.formatDuration(this._call.duration):""}get shape(){return"call"}get canJoin(){return this._call&&!this._call.hasJoined&&!this._call.usesFoci}get canLeave(){return this._call&&this._call.hasJoined}get title(){return this._call?this.type===yr.Video?`${this.displayName} started a video call`:`${this.displayName} started a voice call`:this.type===yr.Video?"Video call ended":"Voice call ended"}get typeLabel(){return this._call&&this._call.usesFoci?"This call uses a stream-forwarding unit, which isn't supported yet, so you can't join this call.":this.type===yr.Video?"Video call":"Voice call"}get type(){return this._entry.event.content["m.type"]}async join(){await this.logAndCatch("CallTile.join",async e=>{if(this.canJoin){const t=await this.platform.mediaDevices.getMediaTracks(!1,!0),s=new At().withUserMedia(t);await this._call.join(s,e)}})}async leave(){await this.logAndCatch("CallTile.leave",async e=>{this.canLeave&&await this._call.leave(e)})}}class ap extends L{get _member(){return this.getOption("member")}get userId(){return this._member.userId}get avatarLetter(){return Ee(this._member.member.name)}get avatarColorNumber(){return Re(this._member.userId)}avatarUrl(e){const{avatarUrl:t}=this._member.member,s=this.getOption("mediaRepository");return Be(t,e,this.platform,s)}get avatarTitle(){return this._member.member.name}}var Ai=(n=>(n[n.Ready=0]="Ready",n[n.InProgress=1]="InProgress",n[n.Completed=2]="Completed",n[n.Cancelled=3]="Cancelled",n))(Ai||{});class cp extends xs{constructor(e,t){super(e,t),this.status=0,this.request=new pr(this.lowerEntry),this.updateStatusFromAvailableContextForEntries()}get shape(){return me.Verification}get description(){return this.i18n`${this.sender} wants to verify`}accept(){this.getOption("session").crossSigning.get().receivedSASVerifications.set(this.eventId,this.request),this.openVerificationPanel(this.eventId)}async reject(){await this.logAndCatch("VerificationTile.reject",async e=>{const t=this.getOption("session").crossSigning.get();await this.request.reject(t,this._room,e)})}openVerificationPanel(e){let t=this.navigation.path.until("room");t=t.with(this.navigation.segment("right-panel",!0)),t=t.with(this.navigation.segment("verification",e)),this.navigation.applyPath(t)}updateEntry(e,t){return t==="context-added"?this.updateStatusFromAvailableContextForEntries()?Fe.Update(t):Fe.Nothing():super.updateEntry(e,t)}updateStatusFromAvailableContextForEntries(){var t;let e=!1;for(const s of(t=this.lowerEntry.contextForEntries)!=null?t:[])switch(s.eventType){case P.Cancel:return this.status=3,this.isCancelledByUs=s.sender===this.getOption("session").userId,!0;case P.Done:return this.status=2,!0;default:this.status=1,e=!0}return e}}function lp(n,e){if(n.isGap)return M_;if(n.isPending&&n.pendingEvent.isMissingAttachments)return np;if(n.eventType)switch(n.eventType){case"m.room.message":{if(n.isRedacted)return No;const t=n.content;switch(t&&t.msgtype){case"m.text":case"m.notice":case"m.emote":return z_;case"m.image":return J_;case"m.video":return Q_;case"m.file":return Z_;case"m.location":return ep;case"m.key.verification.request":const i=!e.session.features.crossSigning,r=e.session.userId;return i||n.sender===r?void 0:cp;default:return}}case"m.room.name":return tp;case"m.room.member":return sp;case"m.room.encrypted":return n.isRedacted?No:ip;case"m.room.encryption":return rp;case"org.matrix.msc3401.call":return e.features.calls&&n.stateKey&&!n.prevContent?op:void 0;default:return}}async function _c(n,e){var t,s,i,r;try{const o=await e.joinRoom(n);return await(await e.observeRoomStatus(o)).waitFor(l=>l===se.Joined),o}catch(o){throw((t=o.statusCode)!=null?t:o.status)===400?new Error(`'${n}' is not a legal room ID or alias`):((s=o.statusCode)!=null?s:o.status)===404||((i=o.statusCode)!=null?i:o.status)===502||o.message=="Internal Server eor"?new Error(`Room '${n}' could not be found`):((r=o.statusCode)!=null?r:o.status)===403?new Error(`You are not invited to join '${n}'`):o}}class Do extends ot{constructor(e){var i;super(e);const{room:t,tileClassForEntry:s}=e;this._sendReadReceipt=(i=e.sendReadReceipt)!=null?i:!0,this._room=t,this._timelineVM=null,this._tileClassForEntry=s!=null?s:lp,this._tileOptions=void 0,this._onRoomChange=this._onRoomChange.bind(this),this._composerVM=null,t.isArchived?this._composerVM=this.track(new dp(this.childOptions({archivedRoom:t}))):this._recreateComposerOnPowerLevelChange(),this._clearUnreadTimout=null,this._closeUrl=this.urlRouter.urlUntilSegment("session"),this._setupCallViewModel()}_setupCallViewModel(){if(!this.features.calls)return;const e=this.getOption("session").callHandler.calls;this._callObservable=new rl(e.filterValues(s=>s.roomId===this._room.id&&s.hasJoined)),this._callViewModel=void 0,this.track(this._callObservable.subscribe(s=>{s&&this._callViewModel&&s.id===this._callViewModel.id||(this._callViewModel=this.disposeTracked(this._callViewModel),s&&(this._callViewModel=this.track(new Ro(this.childOptions({call:s,room:this._room})))),this.emitChange("callViewModel"))}));const t=this._callObservable.get();t&&(this._callViewModel=this.track(new Ro(this.childOptions({call:t,room:this._room}))))}async load(){await this.logAndCatch("RoomViewModel.load",async e=>{this._room.on("change",this._onRoomChange);const t=await this._room.openTimeline(e);this.track(()=>t.release()),this._tileOptions=this.childOptions({session:this.getOption("session"),roomVM:this,timeline:t,tileClassForEntry:this._tileClassForEntry}),this._timelineVM=this.track(new w_(this.childOptions({tileOptions:this._tileOptions,timeline:t}))),this.emitChange("timelineViewModel"),await this._clearUnreadAfterDelay(e)})}async _recreateComposerOnPowerLevelChange(){const e=await this._room.observePowerLevels(),t=()=>e.get().canSendType("m.room.message");let s=t();const i=r=>{this._composerVM=this.disposeTracked(this._composerVM),r?this._composerVM=this.track(new v_(this)):this._composerVM=this.track(new up(this.childOptions())),this.emitChange("powerLevelObservable")};this.track(e.subscribe(()=>{const r=t();s!==r&&(i(r),s=r)})),i(s)}async _clearUnreadAfterDelay(e){if(!(this._room.isArchived||this._clearUnreadTimout)){this._clearUnreadTimout=this.clock.createTimeout(2e3);try{await this._clearUnreadTimout.elapsed(),await this._room.clearUnread(e,this._sendReadReceipt),this._clearUnreadTimout=null}catch(t){if(t.name==="AbortError")e.set("clearUnreadCancelled",!0);else throw t}}}focus(){this.logAndCatch("RoomViewModel.focus",async e=>{this._clearUnreadAfterDelay(e)})}dispose(){super.dispose(),this._room.off("change",this._onRoomChange),this._room.isArchived&&this._room.release(),this._clearUnreadTimout&&(this._clearUnreadTimout.abort(),this._clearUnreadTimout=null)}_onRoomChange(){var e;(e=this._composerVM)==null||e.emitChange(),this.emitChange()}get kind(){return"room"}get closeUrl(){return this._closeUrl}get name(){return this._room.name||this.i18n`Empty Room`}get id(){return this._room.id}get timelineViewModel(){return this._timelineVM}get isEncrypted(){return this._room.isEncrypted}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this._room.avatarColorId)}avatarUrl(e){return Be(this._room.avatarUrl,e,this.platform,this._room.mediaRepository)}get avatarTitle(){return this.name}get canLeave(){return this._room.isJoined}leaveRoom(){this._room.leave()}get canForget(){return this._room.isArchived}forgetRoom(){this._room.forget()}get canRejoin(){return this._room.isArchived}rejoinRoom(){this._room.join()}_createTile(e){if(this._tileOptions){const t=this._tileOptions.tileClassForEntry(e,this._tileOptions);if(t)return new t(e,this._tileOptions)}}_sendMessage(e,t){return this.logAndCatch("RoomViewModel.sendMessage",async s=>{let i=!1;if(!this._room.isArchived&&e){let r="m.text";if(e.startsWith("//"))e=e.substring(1).trim();else if(e.startsWith("/")){const c=await this._processCommand(e);r=c.msgtype,e=c.message}let o;t?(s.set("replyingTo",t.eventId),o=await t.createReplyContent(r,e)):o={msgtype:r,body:e},await this._room.sendEvent("m.room.message",o,void 0,s),i=!0}return s.set("success",i),i},!1)}async _processCommandJoin(e){try{const t=this._options.client.session,s=await _c(e,t);this.navigation.push("room",s)}catch(t){this.reportError(t)}}async _processCommand(e){let t;const[s,...i]=e.substring(1).split(" ");switch(s){case"me":e=i.join(" "),t="m.emote";break;case"join":if(i.length===1){const r=i[0];await this._processCommandJoin(r)}else this.reportError(new Error("join syntax: /join "));break;case"invite":if(i.length===1){const r=i[0];await this._room.inviteUser(r)}else this.reportError(new Error("invite syntax: /invite "));break;case"shrug":e="\xAF\\_(\u30C4)_/\xAF "+i.join(" "),t="m.text";break;case"tableflip":e="(\u256F\xB0\u25A1\xB0\uFF09\u256F\uFE35 \u253B\u2501\u253B "+i.join(" "),t="m.text";break;case"unflip":e="\u252C\u2500\u2500\u252C \u30CE( \u309C-\u309C\u30CE) "+i.join(" "),t="m.text";break;case"lenny":e="( \u0361\xB0 \u035C\u0296 \u0361\xB0) "+i.join(" "),t="m.text";break;default:this.reportError(new Error(`no command name "${s}". To send the message instead of executing, please type "/${e}"`)),e=void 0}return{msgtype:t,message:e}}_pickAndSendFile(){return this.logAndCatch("RoomViewModel.sendFile",async e=>{const t=await this.platform.openFile();if(!t){e.set("cancelled",!0);return}return this._sendFile(t,e)})}async _sendFile(e,t){const s={body:e.name,msgtype:"m.file"};await this._room.sendEvent("m.room.message",s,{url:this._room.createAttachment(e.blob,e.name)},t)}_pickAndSendVideo(){return this.logAndCatch("RoomViewModel.sendVideo",async e=>{if(!this.platform.hasReadPixelPermission())throw new Error("Please allow canvas image data access, so we can scale your images down.");const t=await this.platform.openFile("video/*");if(!t)return;if(!t.blob.mimeType.startsWith("video/"))return this._sendFile(t,e);let s;try{s=await this.platform.loadVideo(t.blob)}catch(h){throw h instanceof window.MediaError&&h.code===4?new Error(`this browser does not support videos of type ${t==null?void 0:t.blob.mimeType}.`):h}const i={body:t.name,msgtype:"m.video",info:hp(s)},r={url:this._room.createAttachment(s.blob,t.name)},c=await this.platform.settingsStorage.getInt("sentImageSizeLimit")||Math.min(s.maxDimension,800),l=await s.scale(c);i.info.thumbnail_info=Ni(l),r["info.thumbnail_url"]=this._room.createAttachment(l.blob,t.name),await this._room.sendEvent("m.room.message",i,r,e)})}async _pickAndSendPicture(){this.logAndCatch("RoomViewModel.sendPicture",async e=>{if(!this.platform.hasReadPixelPermission()){alert("Please allow canvas image data access, so we can scale your images down.");return}const t=await this.platform.openFile("image/*");if(!t){e.set("cancelled",!0);return}if(!t.blob.mimeType.startsWith("image/"))return this._sendFile(t,e);let s=await this.platform.loadImage(t.blob);const i=await this.platform.settingsStorage.getInt("sentImageSizeLimit");if(i&&s.maxDimension>i){const c=await s.scale(i);s.dispose(),s=c}const r={body:t.name,msgtype:"m.image",info:Ni(s)},o={url:this._room.createAttachment(s.blob,t.name)};if(s.maxDimension>600){const c=await s.scale(400);r.info.thumbnail_info=Ni(c),o["info.thumbnail_url"]=this._room.createAttachment(c.blob,t.name)}await this._room.sendEvent("m.room.message",r,o,e)})}get room(){return this._room}get composerViewModel(){return this._composerVM}get callViewModel(){return this._callViewModel}openDetailsPanel(){let e=this.navigation.path.until("room");e=e.with(this.navigation.segment("right-panel",!0)),e=e.with(this.navigation.segment("details",!0)),this.navigation.applyPath(e)}startReply(e){this._room.isArchived||this._composerVM.setReplyingTo(e)}startCall(){return this.logAndCatch("RoomViewModel.startCall",async e=>{if(!this.features.calls){e.set("feature_disbled",!0);return}e.set("roomId",this._room.id);let t;try{const r=await this.platform.mediaDevices.getMediaTracks(!1,!0);t=new At().withUserMedia(r)}catch(r){throw new Error(`Could not get local audio and/or video stream: ${r.message}`)}const s=this.getOption("session");let i;try{i=await s.callHandler.createCall(this._room.id,"m.video","A call "+Math.round(this.platform.random()*100),void 0,e)}catch(r){throw new Error(`Could not create call: ${r.message}`)}try{await i.join(t,e)}catch(r){throw new Error(`Could not join call: ${r.message}`)}})}}function hp(n){const e=Ni(n);return e.duration=n.duration,e}class dp extends L{constructor(e){super(e),this._archivedRoom=e.archivedRoom}get description(){return this._archivedRoom.isKicked?this._archivedRoom.kickReason?this.i18n`You were kicked from the room by ${this._archivedRoom.kickedBy.name} because: ${this._archivedRoom.kickReason}`:this.i18n`You were kicked from the room by ${this._archivedRoom.kickedBy.name}.`:this._archivedRoom.isBanned?this._archivedRoom.kickReason?this.i18n`You were banned from the room by ${this._archivedRoom.kickedBy.name} because: ${this._archivedRoom.kickReason}`:this.i18n`You were banned from the room by ${this._archivedRoom.kickedBy.name}.`:this.i18n`You left this room`}get kind(){return"disabled"}}class up extends L{get description(){return this.i18n`You do not have the powerlevel necessary to send messages`}get kind(){return"disabled"}}class mp extends L{constructor(e){super(e);const{roomIdOrAlias:t,session:s}=e;this._session=s,this.roomIdOrAlias=t,this._error=null,this._busy=!1,this._closeUrl=this.urlRouter.urlUntilSegment("session")}get closeUrl(){return this._closeUrl}get error(){var e;return(e=this._error)==null?void 0:e.message}async join(){this._busy=!0,this.emitChange("busy");try{const e=await this._session.joinRoom(this.roomIdOrAlias);this.navigation.push("room",e)}catch(e){this._error=e,this._busy=!1,this.emitChange("error")}}get busy(){return this._busy}get kind(){return"unknown"}}class _p extends L{constructor(e){super(e);const{invite:t,mediaRepository:s}=e;this._invite=t,this._mediaRepository=s,this._onInviteChange=this._onInviteChange.bind(this),this._error=null,this._closeUrl=this.urlRouter.urlUntilSegment("session"),this._invite.on("change",this._onInviteChange),this._inviter=null,this._invite.inviter&&(this._inviter=new pp(this._invite.inviter,s,this.platform)),this._roomDescription=this._createRoomDescription()}get kind(){return"invite"}get closeUrl(){return this._closeUrl}get name(){return this._invite.name}get id(){return this._invite.id}get isEncrypted(){return this._invite.isEncrypted}get isDirectMessage(){return this._invite.isDirectMessage}get inviter(){return this._inviter}get busy(){return this._invite.accepting||this._invite.rejecting}get error(){return this._error?`Something went wrong: ${this._error.message}`:""}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this._invite.avatarColorId)}avatarUrl(e){return Be(this._invite.avatarUrl,e,this.platform,this._mediaRepository)}_createRoomDescription(){const e=[];return this._invite.isPublic?e.push("Public room"):e.push("Private room"),this._invite.canonicalAlias&&e.push(this._invite.canonicalAlias),e.join(" \u2022 ")}get roomDescription(){return this._roomDescription}get avatarTitle(){return this.name}focus(){}async accept(){try{await this._invite.accept()}catch(e){this._error=e,this.emitChange("error")}}async reject(){try{await this._invite.reject()}catch(e){this._error=e,this.emitChange("error")}}_onInviteChange(){this.emitChange()}dispose(){super.dispose(),this._invite.off("change",this._onInviteChange)}}class pp{constructor(e,t,s){this._member=e,this._mediaRepository=t,this._platform=s}get id(){return this._member.userId}get name(){return this._member.name}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this._member.userId)}avatarUrl(e){return Be(this._member.avatarUrl,e,this._platform,this._mediaRepository)}get avatarTitle(){return this.name}}class gp extends L{constructor(e){super(e);const{roomBeingCreated:t,mediaRepository:s}=e;this._roomBeingCreated=t,this._mediaRepository=s,this._onRoomChange=this._onRoomChange.bind(this),this._closeUrl=this.urlRouter.urlUntilSegment("session"),this._roomBeingCreated.on("change",this._onRoomChange)}get kind(){return"roomBeingCreated"}get closeUrl(){return this._closeUrl}get name(){return this._roomBeingCreated.name}get id(){return this._roomBeingCreated.id}get isEncrypted(){return this._roomBeingCreated.isEncrypted}get error(){const{error:e}=this._roomBeingCreated;return e?e.name==="ConnectionError"?this.i18n`You seem to be offline`:e.message:""}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this._roomBeingCreated.avatarColorId)}get avatarTitle(){return this.name}avatarUrl(e){var t;return(t=this._roomBeingCreated.avatarBlobUrl)!=null?t:Be(this._roomBeingCreated.avatarUrl,e,this.platform,this._mediaRepository)}focus(){}_onRoomChange(){this.emitChange()}cancel(){this._roomBeingCreated.cancel(),this.navigation.applyPath(this.navigation.path.until("session"))}dispose(){super.dispose(),this._roomBeingCreated.off("change",this._onRoomChange)}}class fp extends L{constructor(e){super(e),this._eventId=e.eventId,this._unencryptedImageUrl=null,this._decryptedImage=null,this._closeUrl=this.urlRouter.urlUntilSegment("room"),this._date=null,this._subscribeToEvent(e.room,e.eventId)}_subscribeToEvent(e,t){const s=e.observeEvent(t);this.track(s.subscribe(i=>{this._loadEvent(e,i)})),this._loadEvent(e,s.get())}async _loadEvent(e,t){if(!t)return;const{mediaRepository:s}=e;this._eventEntry=t;const{content:i}=this._eventEntry;this._date=this._eventEntry.timestamp?new Date(this._eventEntry.timestamp):null,i.url?(this._unencryptedImageUrl=s.mxcUrl(i.url),this.emitChange("imageUrl")):i.file&&(this._decryptedImage=this.track(await s.downloadEncryptedFile(i.file)),this.emitChange("imageUrl"))}get imageWidth(){var e,t,s;return(s=(t=(e=this._eventEntry)==null?void 0:e.content)==null?void 0:t.info)==null?void 0:s.w}get imageHeight(){var e,t,s;return(s=(t=(e=this._eventEntry)==null?void 0:e.content)==null?void 0:t.info)==null?void 0:s.h}get name(){var e,t;return(t=(e=this._eventEntry)==null?void 0:e.content)==null?void 0:t.body}get sender(){var e;return(e=this._eventEntry)==null?void 0:e.displayName}get imageUrl(){return this._decryptedImage?this._decryptedImage.url:this._unencryptedImageUrl?this._unencryptedImageUrl:""}get date(){return this._date&&this._date.toLocaleDateString({},{weekday:"long",year:"numeric",month:"long",day:"numeric"})}get time(){return this._date&&this._date.toLocaleTimeString({},{hour:"numeric",minute:"2-digit"})}get closeUrl(){return this._closeUrl}close(){this.platform.history.pushUrl(this.closeUrl)}}const ke=oi("Disconnected","Connecting","FirstSync","Sending","Syncing","SyncError");class yp extends L{constructor(e){super(e);const{sync:t,reconnector:s,session:i}=e;this._sync=t,this._reconnector=s,this._status=this._calculateState(s.connectionStatus.get(),t.status.get()),this._session=i,this._setupKeyBackupUrl=this.urlRouter.urlForSegment("settings"),this._dismissSecretStorage=!1}start(){const e=()=>this._updateStatus();this.track(this._sync.status.subscribe(e)),this.track(this._reconnector.connectionStatus.subscribe(e)),this.track(this._session.needsKeyBackup.subscribe(()=>{this.emitChange()}))}get setupKeyBackupUrl(){return this._setupKeyBackupUrl}get isShown(){return this._session.needsKeyBackup.get()&&!this._dismissSecretStorage||this._status!==ke.Syncing}get statusLabel(){switch(this._status){case ke.Disconnected:{const e=Math.round(this._reconnector.retryIn/1e3);return this.i18n`Disconnected, trying to reconnect in ${e}s…`}case ke.Connecting:return this.i18n`Trying to reconnect now…`;case ke.FirstSync:return this.i18n`Catching up with your conversations…`;case ke.SyncError:return this.i18n`Sync failed because of ${this._sync.error}`}return this._session.needsKeyBackup.get()?this.i18n`Set up session backup to decrypt older messages.`:""}get isWaiting(){switch(this._status){case ke.Connecting:case ke.FirstSync:return!0;default:return!1}}_updateStatus(){const e=this._calculateState(this._reconnector.connectionStatus.get(),this._sync.status.get());e!==this._status&&(e===ke.Disconnected?this._retryTimer=this.track(this.clock.createInterval(()=>{this.emitChange("statusLabel")},1e3)):this._retryTimer=this.disposeTracked(this._retryTimer),this._status=e,this.emitChange())}_calculateState(e,t){if(e!==Ys.Online)switch(e){case Ys.Reconnecting:return ke.Connecting;case Ys.Waiting:return ke.Disconnected}else if(t!==te.Syncing)switch(t){case te.InitialSync:case te.CatchupSync:return ke.FirstSync;case te.Stopped:return ke.SyncError}else return ke.Syncing}get isConnectNowShown(){return this._status===ke.Disconnected}get isSecretStorageShown(){return this._status===ke.Syncing&&this._session.needsKeyBackup.get()&&!this._dismissSecretStorage}get canDismiss(){return this.isSecretStorageShown}dismiss(){this.isSecretStorageShown&&(this._dismissSecretStorage=!0,this.emitChange())}connectNow(){this.isConnectNowShown&&this._reconnector.tryNow()}}function Uo(n){return n.map((e,t)=>{if(!n.slice(0,t).includes(e))return e})}class wp extends L{constructor(e){super(e),this._width=e.width,this._height=e.height,this._createRoomViewModelObservable=e.createRoomViewModelObservable,this._selectedIndex=0,this._viewModelsObservables=[],this._setupNavigation()}_setupNavigation(){const e=this.navigation.observe("empty-grid-tile");this.track(e.subscribe(s=>{typeof s=="number"&&this._setFocusIndex(s)})),typeof e.get()=="number"&&(this._selectedIndex=e.get());const t=this.navigation.observe("room");this.track(t.subscribe(s=>{s&&this._setFocusRoom(s)}))}roomViewModelAt(e){var t;return(t=this._viewModelsObservables[e])==null?void 0:t.get()}get focusIndex(){return this._selectedIndex}get width(){return this._width}get height(){return this._height}_switchToRoom(e){let t=this.navigation.path.until("rooms");t=t.with(this.navigation.segment("room",e)),t=mn(this.navigation,t),this.navigation.applyPath(t)}focusTile(e){if(e===this._selectedIndex)return;const t=this._viewModelsObservables[e];t?this._switchToRoom(t.id):this.navigation.push("empty-grid-tile",e)}initializeRoomIdsAndTransferVM(e,t){e=Uo(e);let s=!1;if(t){const r=e.indexOf(t.id);r!==-1&&(this._viewModelsObservables[r]=this.track(t),t.subscribe(o=>this._refreshRoomViewModel(o)),s=!0)}this.setRoomIds(e);const i=this.navigation.path.get("room");if(i){const r=this._viewModelsObservables.findIndex(o=>o&&o.id===i.value);r!==-1&&(this._selectedIndex=r)}return s}setRoomIds(e){e=Uo(e);let t=!1;const s=this._height*this._width;for(let i=0;ithis._refreshRoomViewModel(l)),c.initialize()}t=!0}}return t&&this.emitChange(),t}_refreshRoomViewModel(e){this.emitChange(),e==null||e.focus()}releaseRoomViewModel(e){const t=this._viewModelsObservables.findIndex(s=>s&&s.id===e);if(t!==-1){const s=this._viewModelsObservables[t];return this.untrack(s),s.unsubscribeAll(),this._viewModelsObservables[t]=null,s}}_setFocusIndex(e){var s;if(e===this._selectedIndex||e>=this._width*this._height)return;this._selectedIndex=e;const t=this._viewModelsObservables[this._selectedIndex];(s=t==null?void 0:t.get())==null||s.focus(),this.emitChange("focusIndex")}_setFocusRoom(e){const t=this._viewModelsObservables.findIndex(s=>(s==null?void 0:s.id)===e);t>=0&&this._setFocusIndex(t)}}var st=(n=>(n[n.Enabled=0]="Enabled",n[n.SetupWithPassphrase=1]="SetupWithPassphrase",n[n.SetupWithRecoveryKey=2]="SetupWithRecoveryKey",n[n.Pending=3]="Pending",n[n.NewVersionAvailable=4]="NewVersionAvailable",n))(st||{}),wr=(n=>(n[n.Writing=0]="Writing",n[n.Stopped=1]="Stopped",n[n.Done=2]="Done",n[n.Pending=3]="Pending",n))(wr||{});class vp extends L{constructor(e){super(e),this._error=void 0,this._isBusy=!1,this._dehydratedDeviceId=void 0,this._status=3,this._backupOperationSubscription=void 0,this._keyBackupSubscription=void 0,this._progress=void 0,this._setupKeyType=mt.RecoveryKey;const t=s=>{s&&!this._keyBackupSubscription?this._keyBackupSubscription=this.track(this._session.keyBackup.get().disposableOn("change",()=>{this._onKeyBackupChange()})):!s&&this._keyBackupSubscription&&(this._keyBackupSubscription=this.disposeTracked(this._keyBackupSubscription)),this._onKeyBackupChange()};this.track(this._session.keyBackup.subscribe(t)),this.track(this._session.crossSigning.subscribe(()=>{this.emitChange("crossSigning")})),t(this._keyBackup)}get _session(){return this.getOption("session")}get _keyBackup(){return this._session.keyBackup.get()}get _crossSigning(){return this._session.crossSigning.get()}_onKeyBackupChange(){const e=this._keyBackup;if(e){const{operationInProgress:t}=e;t&&!this._backupOperationSubscription?this._backupOperationSubscription=this.track(t.disposableOn("change",()=>{this._progress=t.progress,this.emitChange("backupPercentage")})):this._backupOperationSubscription&&!t&&(this._backupOperationSubscription=this.disposeTracked(this._backupOperationSubscription),this._progress=void 0)}this.emitChange("status")}get status(){const e=this._keyBackup;if(e)return e.needsNewKey?4:e.version===void 0?3:e.needsNewKey?4:0;switch(this._setupKeyType){case mt.RecoveryKey:return 2;case mt.Passphrase:return 1}}get decryptAction(){return this.i18n`Set up`}get purpose(){return this.i18n`set up key backup`}offerDehydratedDeviceSetup(){return!0}get dehydratedDeviceId(){return this._dehydratedDeviceId}get isBusy(){return this._isBusy}get backupVersion(){var e,t;return(t=(e=this._keyBackup)==null?void 0:e.version)!=null?t:""}get isMasterKeyTrusted(){var e,t;return(t=(e=this._crossSigning)==null?void 0:e.isMasterKeyTrusted)!=null?t:!1}get canSignOwnDevice(){return!!this._crossSigning}async _signOwnDevice(){const e=this._crossSigning;e&&await this.logger.run("KeyBackupViewModel.signOwnDevice",async t=>{await e.signOwnDevice(t)})}navigateToVerification(){this.navigation.push("device-verification",!0)}get backupWriteStatus(){const e=this._keyBackup;return!e||e.version===void 0?3:e.hasStopped?1:e.operationInProgress?0:e.hasBackedUpAllKeys?2:3}get backupError(){var e,t;return(t=(e=this._keyBackup)==null?void 0:e.error)==null?void 0:t.message}get error(){var e;return(e=this._error)==null?void 0:e.message}showPhraseSetup(){this._setupKeyType=mt.Passphrase,this.emitChange("status")}showKeySetup(){this._setupKeyType=mt.RecoveryKey,this.emitChange("status")}async _enterCredentials(e,t,s){if(t)try{this._isBusy=!0,this.emitChange("isBusy");const i=await this._session.enableSecretStorage(e,t);s&&(this._dehydratedDeviceId=await this._session.setupDehydratedDevice(i)),await this._signOwnDevice()}catch(i){console.error(i),this._error=i,this.emitChange("error")}finally{this._isBusy=!1,this.emitChange()}}enterSecurityPhrase(e,t){return this._enterCredentials(mt.Passphrase,e,t)}enterSecurityKey(e,t){return this._enterCredentials(mt.RecoveryKey,e,t)}async disable(){try{this._isBusy=!0,this.emitChange("isBusy"),await this._session.disableSecretStorage()}catch(e){console.error(e),this._error=e,this.emitChange("error")}finally{this._isBusy=!1,this.emitChange()}}get isBackingUp(){var e;return((e=this._keyBackup)==null?void 0:e.operationInProgress)!==void 0}get backupPercentage(){return this._progress?Math.round(this._progress.finished/this._progress.total*100):0}get backupInProgressLabel(){return this._progress?this.i18n`${this._progress.finished} of ${this._progress.total}`:this.i18n`…`}cancelBackup(){var e,t;(t=(e=this._keyBackup)==null?void 0:e.operationInProgress)==null||t.abort()}startBackup(){this.logger.run("KeyBackupViewModel.startBackup",e=>{var t;(t=this._keyBackup)==null||t.flush(e)})}}class bp extends L{constructor(e){super(e),this.featureViewModels=[new Oo(this.childOptions({name:this.i18n`Audio/video calls`,description:this.i18n`Allows starting and participating in A/V calls compatible with Element Call (MSC3401). Look for the start call option in the room menu ((...) in the right corner) to start a call.`,feature:dn.Calls})),new Oo(this.childOptions({name:this.i18n`Cross-Signing`,description:this.i18n`Allows verifying the identity of people you chat with. This feature is still evolving constantly, expect things to break.`,feature:dn.CrossSigning}))]}}class Oo extends L{get enabled(){return this.features.isFeatureEnabled(this.getOption("feature"))}async enableFeature(e){let t;e?t=this.features.withFeature(this.getOption("feature")):t=this.features.withoutFeature(this.getOption("feature")),await t.store(this.platform.settingsStorage),this.platform.restart()}get id(){return`${this.getOption("feature")}`}get name(){return this.getOption("name")}get description(){return this.getOption("description")}}class Sp{constructor(){this.supported=null,this.enabled=!1,this.updating=!1,this.enabledOnServer=null,this.serverError=null}}function kp(n){const t=Math.ceil(n.length/4);let s="";for(let i=0;ithis.maxSentImageSizeLimit||etypeof s.export=="function").export()).asBlob()}get canSendLogsToServer(){return!!this.platform.config.bugReportEndpointUrl}get logsServer(){const{bugReportEndpointUrl:e}=this.platform.config;try{if(e)return new URL(e).hostname}catch{}return""}async sendLogsToServer(){this._logsFeedbackMessage=this.i18n`Sending logs…`;try{await cc(this._session,this.platform),this._logsFeedbackMessage=this.i18n`Logs sent succesfully!`}catch(e){this._logsFeedbackMessage=e.message,this.emitChange()}}get logsFeedbackMessage(){return this._logsFeedbackMessage}async togglePushNotifications(){this.pushNotifications.updating=!0,this.pushNotifications.enabledOnServer=null,this.pushNotifications.serverError=null,this.emitChange("pushNotifications.updating");try{await this._session.enablePushNotifications(!this.pushNotifications.enabled)&&(this.pushNotifications.enabled=!this.pushNotifications.enabled,this.pushNotifications.enabled&&this.platform.notificationService.showNotification(this.i18n`Push notifications are now enabled`))}finally{this.pushNotifications.updating=!1,this.emitChange("pushNotifications.updating")}}async checkPushEnabledOnServer(){this.pushNotifications.enabledOnServer=null,this.pushNotifications.serverError=null;try{this.pushNotifications.enabledOnServer=await this._session.checkPusherEnabledOnHomeserver(),this.emitChange("pushNotifications.enabledOnServer")}catch(e){this.pushNotifications.serverError=e,this.emitChange("pushNotifications.serverError")}}changeThemeOption(e,t){this.platform.themeLoader.setTheme(e,t),this.emitChange("themeOption")}}class Mp extends L{constructor(e){super(e);const{session:t}=e;this._session=t,this._name=void 0,this._topic=void 0,this._roomAlias=void 0,this._isPublic=!1,this._isEncrypted=!0,this._isAdvancedShown=!1,this._isFederationDisabled=!1,this._avatarScaledBlob=void 0,this._avatarFileName=void 0,this._avatarInfo=void 0,this._closeUrl=this.urlRouter.urlUntilSegment("session")}get isPublic(){return this._isPublic}get isEncrypted(){return this._isEncrypted}get canCreate(){return!!this._name}avatarUrl(){return this._avatarScaledBlob.url}get avatarTitle(){return this._name}get avatarLetter(){return""}get avatarColorNumber(){return 0}get hasAvatar(){return!!this._avatarScaledBlob}get isFederationDisabled(){return this._isFederationDisabled}get isAdvancedShown(){return this._isAdvancedShown}get closeUrl(){return this._closeUrl}setName(e){this._name=e,this.emitChange("canCreate")}setRoomAlias(e){this._roomAlias=e}setTopic(e){this._topic=e}setPublic(e){this._isPublic=e,this.emitChange("isPublic")}setEncrypted(e){this._isEncrypted=e,this.emitChange("isEncrypted")}setFederationDisabled(e){this._isFederationDisabled=e,this.emitChange("isFederationDisabled")}toggleAdvancedShown(){this._isAdvancedShown=!this._isAdvancedShown,this.emitChange("isAdvancedShown")}create(){var s,i;let e;this._avatarScaledBlob&&(e={info:this._avatarInfo,name:this._avatarFileName,blob:this._avatarScaledBlob});const t=this._session.createRoom({type:this.isPublic?Le.Public:Le.Private,name:(s=this._name)!=null?s:void 0,topic:(i=this._topic)!=null?i:void 0,isEncrypted:!this.isPublic&&this._isEncrypted,isFederationDisabled:this._isFederationDisabled,alias:this.isPublic?Cp(this._roomAlias):void 0,avatar:e});this.navigation.push("room",t.id)}async selectAvatar(){if(!this.platform.hasReadPixelPermission()){alert("Please allow canvas image data access, so we can scale your images down.");return}this._avatarScaledBlob&&this._avatarScaledBlob.dispose(),this._avatarScaledBlob=void 0,this._avatarFileName=void 0,this._avatarInfo=void 0;const e=await this.platform.openFile("image/*");if(!e||!e.blob.mimeType.startsWith("image/")){this.emitChange("hasAvatar");return}let t=await this.platform.loadImage(e.blob);const s=800;if(t.maxDimension>s){const i=await t.scale(s);t.dispose(),t=i}this._avatarScaledBlob=t.blob,this._avatarInfo=Ni(t),this._avatarFileName=e.name,this.emitChange("hasAvatar")}}function Cp(n){n.startsWith("#")&&(n=n.substr(1));const e=n.indexOf(":");return e!==-1&&(n=n.substr(0,e)),n}class Ep extends L{constructor(e){super(e),this._joinInProgress=!1,this._session=e.session,this._closeUrl=this.urlRouter.urlUntilSegment("session")}get closeUrl(){return this._closeUrl}async join(e){this._error=void 0,this._joinInProgress=!0,this.emitChange("joinInProgress");try{const t=await _c(e,this._session);this.navigation.push("room",t)}catch(t){this._error=t,this._joinInProgress=!1,this.emitChange("error")}}get joinInProgress(){return this._joinInProgress}get status(){if(this._error)return this._error.message;if(this._joinInProgress)return"Joining room"}}class Rp extends L{async cancel(){await this.options.sas.abort()}get title(){const e=this.getOption("sas").isCrossSigningAnotherUser?"Waiting for the other user to accept the verification request":"Waiting for any of your device to accept the verification request";return this.i18n`${e}`}get description(){const e=this.getOption("sas").isCrossSigningAnotherUser?"Ask the other user to accept the request from their client!":"Accept the request from the device you wish to verify!";return this.i18n`${e}`}get kind(){return"waiting-for-user"}}class pc extends ot{dismiss(){if(this.getOption("sas").isCrossSigningAnotherUser){const e=this.navigation.path.until("room");this.navigation.applyPath(e)}else this.navigation.push("settings",!0)}}class Tp extends pc{get cancelCode(){return this.options.cancellation.code}get isCancelledByUs(){return this.options.cancellation.cancelledByUs}get kind(){return"verification-cancelled"}get title(){return this.isCancelledByUs?this.i18n`You cancelled the verification!`:this.getOption("sas").isCrossSigningAnotherUser?this.i18n`The other user cancelled the verification!`:this.i18n`The other device cancelled the verification!`}get description(){var c;const e={[A.InvalidMessage]:"Your other device sent an invalid message.",[A.KeyMismatch]:"The key could not be verified.",[A.TimedOut]:"The verification process timed out.",[A.UnexpectedMessage]:"Your other device sent an unexpected message.",[A.UnknownMethod]:"Your other device is using an unknown method for verification.",[A.UnknownTransaction]:"Your other device sent a message with an unknown transaction id.",[A.UserMismatch]:"The expected user did not match the user verified.",[A.MismatchedCommitment]:"The hash commitment does not match.",[A.MismatchedSAS]:"The emoji/decimal did not match."},t={[A.UserCancelled]:"Your other device cancelled the verification!",[A.InvalidMessage]:"Invalid message sent to the other device.",[A.KeyMismatch]:"The other device could not verify our keys",[A.TimedOut]:"The verification process timed out.",[A.UnexpectedMessage]:"Unexpected message sent to the other device.",[A.UnknownMethod]:"Your other device does not understand the method you chose",[A.UnknownTransaction]:"Your other device rejected our message.",[A.UserMismatch]:"The expected user did not match the user verified.",[A.MismatchedCommitment]:"Your other device was not able to verify the hash commitment",[A.MismatchedSAS]:"The emoji/decimal did not match."},s={[A.InvalidMessage]:"The other user sent an invalid message.",[A.KeyMismatch]:"The key could not be verified.",[A.TimedOut]:"The verification process timed out.",[A.UnexpectedMessage]:"The other user sent an unexpected message.",[A.UnknownMethod]:"The other user is using an unknown method for verification.",[A.UnknownTransaction]:"The other user sent a message with an unknown transaction id.",[A.UserMismatch]:"The expected user did not match the user verified.",[A.MismatchedCommitment]:"The hash commitment does not match.",[A.MismatchedSAS]:"The emoji/decimal did not match."},i={[A.UserCancelled]:"The other user cancelled the verification!",[A.InvalidMessage]:"Invalid message sent to the other user.",[A.KeyMismatch]:"The other user could not verify our keys",[A.TimedOut]:"The verification process timed out.",[A.UnexpectedMessage]:"Unexpected message sent to the other user.",[A.UnknownMethod]:"The other user does not understand the method you chose",[A.UnknownTransaction]:"The other user rejected our message.",[A.UserMismatch]:"The expected user did not match the user verified.",[A.MismatchedCommitment]:"The other user was not able to verify the hash commitment",[A.MismatchedSAS]:"The emoji/decimal did not match."};let r;this.getOption("sas").isCrossSigningAnotherUser?r=this.isCancelledByUs?s:i:r=this.isCancelledByUs?e:t;const o=(c=r[this.cancelCode])!=null?c:"";return this.i18n`${o}`}}class Ap extends ot{constructor(){super(...arguments),this.hasProceeded=!1}async proceed(){await this.logAndCatch("SelectMethodViewModel.proceed",async e=>{await this.options.stage.selectEmojiMethod(e),this.hasProceeded=!0,this.emitChange("hasProceeded")})}async cancel(){await this.logAndCatch("SelectMethodViewModel.cancel",async()=>{await this.options.sas.abort()})}get deviceName(){return this.options.stage.otherDeviceName}get otherUserId(){return this.getOption("sas").otherUserId}get kind(){return"select-method"}get isCrossSigningAnotherUser(){return this.getOption("sas").isCrossSigningAnotherUser}}class xp extends ot{constructor(){super(...arguments),this._isWaiting=!1}async setEmojiMatch(e){await this.logAndCatch("VerifyEmojisViewModel.setEmojiMatch",async()=>{await this.options.stage.setEmojiMatch(e),this._isWaiting=!0,this.emitChange("isWaiting")})}get emojis(){return this.options.stage.emoji}get kind(){return"verify-emojis"}get isWaiting(){return this._isWaiting}}class Vp extends pc{get otherDeviceId(){return this.options.deviceId}get otherUsername(){return this.getOption("sas").otherUserId}get kind(){return"verification-completed"}get verificationSuccessfulMessage(){return this.getOption("sas").isCrossSigningAnotherUser?this.i18n`You successfully verified user ${this.otherUsername}`:this.i18n`You successfully verified device ${this.otherDeviceId}`}}class Np extends L{gotoSettings(){this.navigation.push("settings",!0)}get kind(){return"keys-missing"}}const Po=["m.cross_signing.master","m.cross_signing.self_signing","m.cross_signing.user_signing"];class gc extends ot{constructor(e){super(e),this.start(e)}async start(e){var i,r;const t=e.room;let s;s=(r=(i=e.request)!=null?i:e.userId)!=null?r:this.getOption("session").userId,await this.startVerification(s,t)}async startVerification(e,t){await this.logAndCatch("DeviceVerificationViewModel.startVerification",async s=>{const r=await this.getOption("session").crossSigning.waitFor(o=>!!o).promise;if(this.sas=r.startVerification(e,t,s),!this.sas)throw new Error("CrossSigning.startVerification did not return a sas object!");if(!!await this.performPreVerificationChecks(r,e,s))return this.addEventListeners(),typeof e=="string"&&this.updateCurrentStageViewModel(new Rp(this.childOptions({sas:this.sas}))),this.sas.isCrossSigningAnotherUser?r.signUser(this.sas,s):r.signDevice(this.sas,s)})}async performPreVerificationChecks(e,t,s){return await s.wrap("DeviceVerificationViewModel.performPreVerificationChecks",async i=>{const r=await e.areWeVerified(s),c=(typeof t=="string"?t:t.sender)===this.getOption("session").userId;if(this._needsToRequestSecret=c&&!r,this._needsToRequestSecret)return!0;const l=this.getOption("session"),h=Po.map(u=>l.secretFetcher.getSecret(u)),a=await Promise.all(h);for(const u of a)if(!u)return this.updateCurrentStageViewModel(new Np(this.childOptions({}))),!1;return!0})}addEventListeners(){this.track(this.sas.disposableOn("SelectVerificationStage",e=>{this.updateCurrentStageViewModel(new Ap(this.childOptions({sas:this.sas,stage:e})))})),this.track(this.sas.disposableOn("EmojiGenerated",e=>{this.updateCurrentStageViewModel(new xp(this.childOptions({stage:e})))})),this.track(this.sas.disposableOn("VerificationCancelled",e=>{this.updateCurrentStageViewModel(new Tp(this.childOptions({cancellation:e,sas:this.sas})))})),this.track(this.sas.disposableOn("VerificationCompleted",e=>{this.updateCurrentStageViewModel(new Vp(this.childOptions({deviceId:e,sas:this.sas}))),this.requestSecrets()}))}async requestSecrets(){await this.platform.logger.run("DeviceVerificationViewModel.requestSecrets",async e=>{if(this._needsToRequestSecret){const t=this.getOption("session").secretSharing,s=Po.map(c=>t.requestSecret(c,e)),r=(await Promise.all(s)).map(c=>c.waitForResponse());await Promise.all(r),this.getOption("session").crossSigning.get().start(e)}})}updateCurrentStageViewModel(e){this._currentStageViewModel=this.disposeTracked(this._currentStageViewModel),this._currentStageViewModel=this.track(e),this.emitChange("currentStageViewModel")}dispose(){this.sas&&!this.sas.finished&&this.sas.abort().catch(e=>{console.error(e)}),super.dispose()}get currentStageViewModel(){return this._currentStageViewModel}get type(){return"verification"}get isHappeningInRoom(){return!!this.navigation.path.get("room")}}class Fo extends Vt{constructor(e,t){super(null),this._statusSubscription=null,this._sessionViewModel=e,this.id=t}async initialize(){const{session:e}=this._sessionViewModel._client,t=await e.observeRoomStatus(this.id);this.set(await this._statusToViewModel(t.get())),this._statusSubscription=t.subscribe(async s=>{var i;(i=this.get())==null||i.dispose(),this.set(await this._statusToViewModel(s))})}async _statusToViewModel(e){if(e&se.Replaced)if(e&se.BeingCreated){const{session:t}=this._sessionViewModel._client,s=t.roomsBeingCreated.get(this.id);this._sessionViewModel.notifyRoomReplaced(s.id,s.roomId)}else throw new Error("Don't know how to replace a room with this status: "+(e^se.Replaced));else return e&se.BeingCreated?this._sessionViewModel._createRoomBeingCreatedViewModel(this.id):e&se.Invited?this._sessionViewModel._createInviteViewModel(this.id):e&se.Joined?this._sessionViewModel._createRoomViewModelInstance(this.id):e&se.Archived?await this._sessionViewModel._createArchivedRoomViewModel(this.id):this._sessionViewModel._createUnknownRoomViewModel(this.id)}dispose(){var e;this._statusSubscription&&(this._statusSubscription=this._statusSubscription()),this.unsubscribeAll(),(e=this.get())==null||e.dispose()}}class Dp extends L{constructor(e){super(e),this._room=e.room,this._onRoomChange=this._onRoomChange.bind(this),this._room.on("change",this._onRoomChange)}get type(){return"room-details"}get shouldShowBackButton(){return!1}get previousSegmentName(){return!1}get roomId(){return this._room.id}get canonicalAlias(){return this._room.canonicalAlias}get name(){return this._room.name}get isEncrypted(){return!!this._room.isEncrypted}get memberCount(){return this._room.joinedMemberCount}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this._room.avatarColorId)}avatarUrl(e){return Be(this._room.avatarUrl,e,this.platform,this._room.mediaRepository)}get avatarTitle(){return this.name}_onRoomChange(){this.emitChange()}dispose(){super.dispose(),this._room.off("change",this._onRoomChange)}openPanel(e){let t=this.navigation.path.until("room");t=t.with(this.navigation.segment("right-panel",!0)),t=t.with(this.navigation.segment(e,!0)),this.navigation.applyPath(t)}}class Up extends L{constructor(e){super(e),this._member=this._options.member,this._mediaRepository=e.mediaRepository,this._previousName=null,this._nameChanged=!0}get name(){return`${this._member.name}${this._disambiguationPart}`}get _disambiguationPart(){return this._disambiguate?` (${this.userId})`:""}get userId(){return this._member.userId}get previousName(){return this._previousName}get nameChanged(){return this._nameChanged}get detailsUrl(){const e=this.navigation.path.get("room").value;return`${this.urlRouter.openRoomActionUrl(e)}/member/${encodeURIComponent(this._member.userId)}`}_updatePreviousName(e){const t=this._member.name;t!==e?(this._previousName=t,this._nameChanged=!0):this._nameChanged=!1}setDisambiguation(e){this._disambiguate=e,this.emitChange()}updateFrom(e){this._updatePreviousName(e.name),this._member=e}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this.userId)}avatarUrl(e){return Be(this._member.avatarUrl,e,this.platform,this._mediaRepository)}get avatarTitle(){return this.name}}function Op(n){const e=new Intl.Collator,t=s=>s.charAt(0)==="@"?s.slice(1):s;return function(i,r){const o=n.getUserLevel(i.userId),c=n.getUserLevel(r.userId);if(o!==c)return c-o;const l=t(i.name),h=t(r.name);return e.compare(l,h)}}class Pp{constructor(){this._map=new Map}_unDisambiguate(e,t){const s=t.indexOf(e);if(s!==-1){const[i]=t.splice(s,1);i.setDisambiguation(!1)}}_handlePreviousName(e){const t=e.previousName;if(typeof t!="string")return;const s=this._map.get(t);if(Array.isArray(s)){if(this._unDisambiguate(e,s),s.length===1){const i=s[0];i.setDisambiguation(!1),this._map.set(t,i)}}else this._map.delete(t)}_updateMap(e){const t=e.name,s=this._map.get(t);if(s){if(Array.isArray(s))return s.findIndex(i=>i.userId===e.userId)!==-1?void 0:(s.push(e),s);if(e.userId!==s.userId){const i=[s,e];return this._map.set(t,i),i}}else this._map.set(t,e)}disambiguate(e){if(!e.nameChanged)return;this._handlePreviousName(e);const t=this._updateMap(e);t==null||t.forEach(s=>s.setDisambiguation(!0))}}class Fp extends L{constructor(e){super(e);const t=e.members,s=e.powerLevelsObservable;this.track(s.subscribe(()=>{}));const i=s.get();this.memberTileViewModels=this._mapTileViewModels(t.members.filterValues(r=>r.membership==="join")).sortValues(Op(i)),this.nameDisambiguator=new Pp,this.mediaRepository=e.mediaRepository}get type(){return"member-list"}get shouldShowBackButton(){return!0}get previousSegmentName(){return"details"}_mapTileViewModels(e){const t=(i,r)=>{const o=this.mediaRepository,c=new Up(this.childOptions({member:i,emitChange:r,mediaRepository:o}));return this.nameDisambiguator.disambiguate(c),c},s=(i,r,o)=>{r.updateFrom(o),this.nameDisambiguator.disambiguate(r)};return e.mapValues(t,s)}openInvitePanel(){let e=this.navigation.path.until("room");e=e.with(this.navigation.segment("right-panel",!0)),e=e.with(this.navigation.segment("invite",!0)),this.navigation.applyPath(e)}}class Lp extends L{constructor(e){super(e),this._observableMember=e.observableMember,this._mediaRepository=e.mediaRepository,this._member=this._observableMember.get(),this._isEncrypted=e.isEncrypted,this._powerLevelsObservable=e.powerLevelsObservable,this._session=e.session,this.track(this._powerLevelsObservable.subscribe(()=>this._onPowerLevelsChange())),this.track(this._observableMember.subscribe(()=>this._onMemberChange())),this._userTrust=void 0,this._userTrustSubscription=void 0,this.features.crossSigning&&this.track(this._session.crossSigning.subscribe(()=>{this._onCrossSigningChange()})),this._onCrossSigningChange()}get name(){return this._member.name}get userId(){return this._member.userId}get canVerifyUser(){return this._member.userId!==this._session.userId}get trustDescription(){var e;switch((e=this._userTrust)==null?void 0:e.get()){case et.Trusted:return this.i18n`You have verified this user. This user has verified all of their sessions.`;case et.UserNotSigned:return this.i18n`You have not verified this user.`;case et.UserSignatureMismatch:return this.i18n`You appear to have signed this user, but the signature is invalid.`;case et.UserDeviceNotSigned:return this.i18n`You have verified this user, but they have one or more unverified sessions.`;case et.UserDeviceSignatureMismatch:return this.i18n`This user has a session signature that is invalid.`;case et.UserSetupError:return this.i18n`This user hasn't set up cross-signing correctly`;case et.OwnSetupError:return this.i18n`Cross-signing wasn't set up correctly on your side.`;case void 0:default:return this.i18n`Please wait…`}}get trustShieldColor(){var e;if(!this._isEncrypted)return"";switch((e=this._userTrust)==null?void 0:e.get()){case void 0:case et.OwnSetupError:return"";case et.Trusted:return"green";case et.UserNotSigned:return"black";default:return"red"}}get type(){return"member-details"}get shouldShowBackButton(){return!0}get previousSegmentName(){return"members"}get role(){return this.powerLevel>=100?this.i18n`Admin`:this.powerLevel>=50?this.i18n`Moderator`:this.powerLevel===0?this.i18n`Default`:this.i18n`Custom (${this.powerLevel})`}_onMemberChange(){this._member=this._observableMember.get(),this.emitChange("member")}_onPowerLevelsChange(){this.emitChange("role")}async signUser(){const e=this._session.crossSigning.get();e&&await this.logger.run("MemberDetailsViewModel.signUser",async t=>{await e.signUser(this.userId,t)})}async verifyUser(){await this.logger.run("MemberDetailsViewModel.verifyUser",async()=>{const e=this._session.findDirectMessageForUserId(this.userId);let t=e==null?void 0:e.id;t||(t=(await this._session.createRoom({type:Le.DirectMessage,invites:[this.userId]})).roomId),await(await this._session.observeRoomStatus(t)).waitFor(r=>r===se.Joined).promise;let i=this.navigation.path.until("session");i=i.with(this.navigation.segment("room",t)),i=i.with(this.navigation.segment("right-panel",!0)),i=i.with(this.navigation.segment("verification",this.userId)),this.navigation.applyPath(i)})}get avatarLetter(){return Ee(this.name)}get avatarColorNumber(){return Re(this.userId)}avatarUrl(e){return Be(this._member.avatarUrl,e,this.platform,this._mediaRepository)}get avatarTitle(){return this.name}get isEncrypted(){return this._isEncrypted}get powerLevel(){var e;return(e=this._powerLevelsObservable.get())==null?void 0:e.getUserLevel(this._member.userId)}get linkToUser(){return`https://matrix.to/#/${encodeURIComponent(this._member.userId)}`}async openDirectMessage(){const e=this._session.findDirectMessageForUserId(this.userId);let t=e==null?void 0:e.id;t||(t=(await this._session.createRoom({type:Le.DirectMessage,invites:[this.userId]})).id),this.navigation.push("room",t)}_onCrossSigningChange(){const e=this._session.crossSigning.get();this._userTrustSubscription=this.disposeTracked(this._userTrustSubscription),this._userTrust=void 0,e&&this.logger.run("MemberDetailsViewModel.observeUserTrust",t=>{this._userTrust=e.observeUserTrust(this.userId,t),this._userTrustSubscription=this.track(this._userTrust.subscribe(()=>{this.emitChange("trustShieldColor")}))}),this.emitChange("trustShieldColor")}}class Kp extends ot{constructor(e){super(e)}get type(){return"invite"}get shouldShowBackButton(){return!0}get previousSegmentName(){return"members"}get roomName(){return this.getOption("room").name}async invite(e){await this.logAndCatch("InvitePanelViewModel.invite",async()=>{await this.getOption("room").inviteUser(e);const s=this.navigation.path.until("room");this.navigation.applyPath(s)})}}class Bp extends L{constructor(e){super(e),this._room=e.room,this._session=e.session,this._members=null,this._setupNavigation()}get activeViewModel(){return this._activeViewModel}async _getMemberListArguments(){this._members||(this._members=await this._room.loadMemberList(),this.track(()=>this._members.release()));const e=this._room,t=await this._room.observePowerLevels();return{members:this._members,powerLevelsObservable:t,mediaRepository:e.mediaRepository}}async _getMemberDetailsArguments(){const t=this.navigation.path.get("member").value,s=await this._room.observeMember(t);if(!s)return!1;const i=this._room.isEncrypted,r=await this._room.observePowerLevels();return{observableMember:s,isEncrypted:i,powerLevelsObservable:r,mediaRepository:this._room.mediaRepository,session:this._session}}_setupNavigation(){this._hookUpdaterToSegment("details",Dp,()=>({room:this._room})),this._hookUpdaterToSegment("invite",Kp,()=>({room:this._room})),this._hookUpdaterToSegment("members",Fp,()=>this._getMemberListArguments()),this._hookUpdaterToSegment("member",Lp,()=>this._getMemberDetailsArguments(),()=>{const e=`${this.urlRouter.urlUntilSegment("room")}/members`;this.urlRouter.pushUrl(e)}),this._hookUpdaterToSegment("verification",gc,()=>{var s,i;const e={session:this._session,room:this._room},t=this.navigation.path.get("verification").value;if(typeof t=="string"){const r=(i=(s=this._session)==null?void 0:s.crossSigning.get())==null?void 0:i.receivedSASVerifications.get(t);Object.assign(e,r?{request:r}:{userId:t})}return e})}async _hookUpdaterToSegment(e,t,s,i){const r=this.navigation.observe(e),o=await this._setupUpdater(e,t,s,i);this.track(r.subscribe(o))}async _setupUpdater(e,t,s,i){const r=async(o=!1)=>{var l;if(this._activeViewModel instanceof t)return;if(o||(this._activeViewModel=this.disposeTracked(this._activeViewModel)),!!((l=this.navigation.path.get(e))!=null&&l.value)){const h=await s();if(!h&&i){i();return}this._activeViewModel=this.track(new t(this.childOptions(h)))}this.emitChange("activeViewModel")};return await r(!0),r}closePanel(){const e=this.navigation.path.until("room");this.navigation.applyPath(e)}showPreviousPanel(){const e=this.activeViewModel.previousSegmentName;if(e){let t=this.navigation.path.until("room");t=t.with(this.navigation.segment("right-panel",!0)),t=t.with(this.navigation.segment(e,!0)),this.navigation.applyPath(t)}}}class fc extends ot{constructor(e){super(e)}dismiss(){this.getOption("dismiss")()}}class $p extends fc{constructor(e){super(e),this.track(this.call.members.observeSize().subscribe(()=>{this.emitChange("memberCount")})),this.track(this.navigation.observe("room").subscribe(t=>{t===this.call.roomId&&this.dismiss()}))}get kind(){return"calls"}async join(){await this.logAndCatch("CallToastNotificationViewModel.join",async e=>{const t=await this.platform.mediaDevices.getMediaTracks(!1,!0),s=new At().withUserMedia(t);await this.call.join(s,e);const i=this.urlRouter.openRoomActionUrl(this.call.roomId);this.urlRouter.pushUrl(i)})}get call(){return this.getOption("call")}get room(){return this.getOption("room")}get roomName(){return this.room.name}get memberCount(){return this.call.members.size}get avatarLetter(){return Ee(this.roomName)}get avatarColorNumber(){return Re(this.room.avatarColorId)}avatarUrl(e){return Be(this.room.avatarUrl,e,this.platform,this.room.mediaRepository)}get avatarTitle(){return this.roomName}}class jp extends L{constructor(e){super(e),this.toastViewModels=new gn;const t=this.getOption("session");if(this.features.calls){const s=t.callHandler.calls;this.track(s.subscribe(this))}}async onAdd(e,t){if(this._shouldShowNotification(t)){const s=await this._findRoomForCall(t),i=()=>{const r=this.toastViewModels.array.findIndex(o=>o.call===t);r!==-1&&this.toastViewModels.remove(r)};this.toastViewModels.append(new $p(this.childOptions({call:t,room:s,dismiss:i})))}}onRemove(e,t){const s=this.toastViewModels.array.findIndex(i=>i.call===t);s!==-1&&this.toastViewModels.remove(s)}onUpdate(e,t){const s=this.toastViewModels.array.findIndex(i=>i.call===t);s!==-1&&this.toastViewModels.update(s,this.toastViewModels.at(s))}onReset(){for(let e=0;ec===se.Joined).promise,i.get(t)}_shouldShowNotification(e){var s;const t=(s=this.navigation.path.get("room"))==null?void 0:s.value;return!e.isLoadedFromStorage&&e.roomId!==t&&!e.usesFoci}}class qp extends fc{constructor(e){super(e)}get kind(){return"verification"}get request(){return this.getOption("request")}get otherDeviceId(){return this.request.deviceId}accept(){this.navigation.push("device-verification",this.request.id),this.dismiss()}}class Hp extends L{constructor(e){super(e),this.toastViewModels=new gn,this.subscribeToSASRequests()}async subscribeToSASRequests(){await this.getOption("session").crossSigning.waitFor(t=>!!t).promise;const e=this.getOption("session").crossSigning.get();this.track(e.receivedSASVerifications.subscribe(this))}async onAdd(e,t){if(t.sender!==this.getOption("session").userId)return;const s=()=>{const i=this.toastViewModels.array.findIndex(r=>r.request.id===t.id);i!==-1&&this.toastViewModels.remove(i)};this.toastViewModels.append(this.track(new qp(this.childOptions({request:t,dismiss:s}))))}onRemove(e,t){const s=this.toastViewModels.array.findIndex(i=>i.request.id===t.id);s!==-1&&this.toastViewModels.remove(s)}onUpdate(e,t){const s=this.toastViewModels.array.findIndex(i=>i.request.id===t.id);s!==-1&&this.toastViewModels.update(s,this.toastViewModels.at(s))}onReset(){for(let e=0;er.toastViewModels);i.length!==0&&(this.toastViewModels=new ca(...i))}}class zp extends L{constructor(e){super(e);const{client:t}=e;this._client=this.track(t),this._sessionStatusViewModel=this.track(new yp(this.childOptions({sync:t.sync,reconnector:t.reconnector,session:t.session}))),this._leftPanelViewModel=this.track(new f_(this.childOptions({session:this._client.session}))),this._settingsViewModel=null,this._roomViewModelObservable=null,this._gridViewModel=null,this._createRoomViewModel=null,this._joinRoomViewModel=null,this._verificationViewModel=null,this._toastCollectionViewModel=this.track(new Wp(this.childOptions({session:this._client.session}))),this._setupNavigation(),this._setupForcedLogoutOnAccessTokenInvalidation()}_setupNavigation(){const e=this.navigation.observe("rooms");this.track(e.subscribe(l=>{this._updateGrid(l)})),e.get()&&this._updateGrid(e.get());const t=this.navigation.observe("room");this.track(t.subscribe(l=>{this._gridViewModel||this._updateRoom(l),this._updateRightPanel()})),this._gridViewModel||this._updateRoom(t.get());const s=this.navigation.observe("settings");this.track(s.subscribe(l=>{this._updateSettings(l)})),this._updateSettings(s.get());const i=this.navigation.observe("create-room");this.track(i.subscribe(l=>{this._updateCreateRoom(l)})),this._updateCreateRoom(i.get());const r=this.navigation.observe("join-room");if(this.track(r.subscribe(l=>{this._updateJoinRoom(l)})),this._updateJoinRoom(r.get()),this.features.crossSigning){const l=this.navigation.observe("device-verification");this.track(l.subscribe(h=>{this._updateVerification(h)})),this._updateVerification(l.get())}const o=this.navigation.observe("lightbox");this.track(o.subscribe(l=>{this._updateLightbox(l)})),this._updateLightbox(o.get());const c=this.navigation.observe("right-panel");this.track(c.subscribe(()=>this._updateRightPanel())),this._updateRightPanel()}_setupForcedLogoutOnAccessTokenInvalidation(){this.track(this._client.sync.status.subscribe(e=>{if(e===te.Stopped){const t=this._client.sync.error;if((t==null?void 0:t.errcode)==="M_UNKNOWN_TOKEN"){const s=[this.navigation.segment("logout",this.id),this.navigation.segment("forced",!0)],i=this.navigation.pathFrom(s);this.navigation.applyPath(i)}}}))}get id(){return this._client.sessionId}start(){this._sessionStatusViewModel.start(),this.features.calls&&(this._client.session.callHandler.loadCalls("m.ring"),this._client.session.callHandler.loadCalls("m.prompt"))}get activeMiddleViewModel(){var e;return((e=this._roomViewModelObservable)==null?void 0:e.get())||this._gridViewModel||this._settingsViewModel||this._createRoomViewModel||this._joinRoomViewModel||this._verificationViewModel}get roomGridViewModel(){return this._gridViewModel}get leftPanelViewModel(){return this._leftPanelViewModel}get sessionStatusViewModel(){return this._sessionStatusViewModel}get settingsViewModel(){return this._settingsViewModel}get currentRoomViewModel(){var e;return(e=this._roomViewModelObservable)==null?void 0:e.get()}get rightPanelViewModel(){return this._rightPanelViewModel}get createRoomViewModel(){return this._createRoomViewModel}get joinRoomViewModel(){return this._joinRoomViewModel}get verificationViewModel(){return this._verificationViewModel}get toastCollectionViewModel(){return this._toastCollectionViewModel}_updateGrid(e){var i;const t=!(this._gridViewModel&&e),s=this.navigation.path.get("room");if(e)this._gridViewModel?this._gridViewModel.setRoomIds(e):(this._gridViewModel=this.track(new wp(this.childOptions({width:3,height:2,createRoomViewModelObservable:r=>new Fo(this,r)}))),(i=this._roomViewModelObservable)==null||i.unsubscribeAll(),this._gridViewModel.initializeRoomIdsAndTransferVM(e,this._roomViewModelObservable)?this._roomViewModelObservable=this.untrack(this._roomViewModelObservable):this._roomViewModelObservable&&(this._roomViewModelObservable=this.disposeTracked(this._roomViewModelObservable)));else if(this._gridViewModel&&!e){if(s){const r=this._gridViewModel.releaseRoomViewModel(s.value);r&&(this._roomViewModelObservable=this.track(r),this._roomViewModelObservable.subscribe(()=>{this.emitChange("activeMiddleViewModel")}))}this._gridViewModel=this.disposeTracked(this._gridViewModel)}t&&this.emitChange("activeMiddleViewModel")}_createRoomViewModelInstance(e){const t=this._client.session.rooms.get(e);if(t){const s=new Do(this.childOptions({room:t,session:this._client.session}));return s.load(),s}return null}_createUnknownRoomViewModel(e){return new mp(this.childOptions({roomIdOrAlias:e,session:this._client.session}))}async _createArchivedRoomViewModel(e){const t=await this._client.session.loadArchivedRoom(e);if(t){const s=new Do(this.childOptions({room:t,session:this._client.session}));return s.load(),s}return null}_createInviteViewModel(e){const t=this._client.session.invites.get(e);return t?new _p(this.childOptions({invite:t,mediaRepository:this._client.session.mediaRepository})):null}_createRoomBeingCreatedViewModel(e){const t=this._client.session.roomsBeingCreated.get(e);return t?new gp(this.childOptions({roomBeingCreated:t,mediaRepository:this._client.session.mediaRepository})):null}_updateRoom(e){var s;if(((s=this._roomViewModelObservable)==null?void 0:s.id)===e)return;if(this._roomViewModelObservable&&(this._roomViewModelObservable=this.disposeTracked(this._roomViewModelObservable)),!e){this.emitChange("activeMiddleViewModel");return}const t=new Fo(this,e);this._roomViewModelObservable=this.track(t),this._roomViewModelObservable.subscribe(()=>{this.emitChange("activeMiddleViewModel")}),t.initialize()}_updateSettings(e){this._settingsViewModel&&(this._settingsViewModel=this.disposeTracked(this._settingsViewModel)),e&&(this._settingsViewModel=this.track(new Ip(this.childOptions({client:this._client}))),this._settingsViewModel.load()),this.emitChange("activeMiddleViewModel")}_updateCreateRoom(e){this._createRoomViewModel&&(this._createRoomViewModel=this.disposeTracked(this._createRoomViewModel)),e&&(this._createRoomViewModel=this.track(new Mp(this.childOptions({session:this._client.session})))),this.emitChange("activeMiddleViewModel")}_updateJoinRoom(e){this._joinRoomViewModel&&(this._joinRoomViewModel=this.disposeTracked(this._joinRoomViewModel)),e&&(this._joinRoomViewModel=this.track(new Ep(this.childOptions({session:this._client.session})))),this.emitChange("activeMiddleViewModel")}_updateVerification(e){var t;if(this._verificationViewModel&&(this._verificationViewModel=this.disposeTracked(this._verificationViewModel)),e){const s=(t=this._client.session.crossSigning.get())==null?void 0:t.receivedSASVerifications.get(e);this._verificationViewModel=this.track(new gc(this.childOptions({session:this._client.session,request:s})))}this.emitChange("activeMiddleViewModel")}_updateLightbox(e){if(this._lightboxViewModel&&(this._lightboxViewModel=this.disposeTracked(this._lightboxViewModel)),e){const t=this._roomFromNavigation();this._lightboxViewModel=this.track(new fp(this.childOptions({eventId:e,room:t})))}this.emitChange("lightboxViewModel")}get lightboxViewModel(){return this._lightboxViewModel}_roomFromNavigation(){var s;const e=(s=this.navigation.path.get("room"))==null?void 0:s.value;return this._client.session.rooms.get(e)}_updateRightPanel(){var t;if(this._rightPanelViewModel=this.disposeTracked(this._rightPanelViewModel),!!((t=this.navigation.path.get("right-panel"))!=null&&t.value)){const s=this._roomFromNavigation();this._rightPanelViewModel=this.track(new Bp(this.childOptions({room:s,session:this._client.session})))}this.emitChange("rightPanelViewModel")}notifyRoomReplaced(e,t){this.navigation.push("room",t)}}class Gp extends L{constructor(e){super(e),this._accountSetup=e.accountSetup,this._dehydratedDevice=void 0,this._decryptDehydratedDeviceViewModel=void 0,this._accountSetup.encryptedDehydratedDevice&&(this._decryptDehydratedDeviceViewModel=new Yp(this,t=>{this._dehydratedDevice=t,this._decryptDehydratedDeviceViewModel=void 0,this.emitChange("deviceDecrypted")}))}get decryptDehydratedDeviceViewModel(){return this._decryptDehydratedDeviceViewModel}get deviceDecrypted(){return!!this._dehydratedDevice}get dehydratedDeviceId(){return this._accountSetup.encryptedDehydratedDevice.deviceId}finish(){this._accountSetup.finish(this._dehydratedDevice)}}class Yp extends L{constructor(e,t){super(e.options),this._accountSetupViewModel=e,this._isBusy=!1,this._status=st.SetupWithRecoveryKey,this._error=void 0,this._decryptedCallback=t}get decryptAction(){return this.i18n`Restore`}get purpose(){return this.i18n`claim your dehydrated device`}get offerDehydratedDeviceSetup(){return!1}get dehydratedDeviceId(){var e;return(e=this._accountSetupViewModel._dehydratedDevice)==null?void 0:e.deviceId}get isBusy(){return this._isBusy}get backupVersion(){return 0}get status(){return this._status}get error(){var e;return(e=this._error)==null?void 0:e.message}showPhraseSetup(){this._status===st.SetupWithRecoveryKey&&(this._status=st.SetupWithPassphrase,this.emitChange("status"))}showKeySetup(){this._status===st.SetupWithPassphrase&&(this._status=st.SetupWithRecoveryKey,this.emitChange("status"))}async _enterCredentials(e,t){if(t)try{this._isBusy=!0,this.emitChange("isBusy");const{encryptedDehydratedDevice:s}=this._accountSetupViewModel._accountSetup,i=await s.decrypt(e,t);this._decryptedCallback(i)}catch(s){console.error(s),this._error=s,this.emitChange("error")}finally{this._isBusy=!1,this.emitChange("")}}enterSecurityPhrase(e){this._enterCredentials(mt.Passphrase,e)}enterSecurityKey(e){this._enterCredentials(mt.RecoveryKey,e)}disable(){}}class yc extends L{constructor(e){super(e);const{client:t,ready:s,homeserver:i,deleteSessionOnCancel:r}=e;this._client=t,this._ready=s,this._homeserver=i,this._deleteSessionOnCancel=r,this._loading=!1,this._error=null,this.backUrl=this.urlRouter.urlForSegment("session",!0),this._accountSetupViewModel=void 0}async start(){if(!this._loading)try{this._loading=!0,this.emitChange("loading"),this._waitHandle=this._client.loadStatus.waitFor(s=>(s===W.AccountSetup?this._accountSetupViewModel=new Gp(this.childOptions({accountSetup:this._client.accountSetup})):this._accountSetupViewModel=void 0,this.emitChange("loadLabel"),s===W.FirstSync&&this._client.sync.status.get()===te.CatchupSync||s===W.LoginFailed||s===W.Error||s===W.Ready));try{await this._waitHandle.promise}catch{return}const e=this._client.loadStatus.get(),t=this._client.loadError;if(e===W.FirstSync||e===W.Ready){const s=this._client;this._client=null,this._ready(s)}t&&console.error("session load error",t.stack)}catch(e){this._error=e,console.error("error thrown during session load",e.stack)}finally{this._loading=!1,this.emitChange("loading")}}dispose(){this._client&&(this._client.dispose(),this._client=null),this._waitHandle&&(this._waitHandle.dispose(),this._waitHandle=null)}get loading(){const e=this._client;return e&&e.loadStatus.get()===W.AccountSetup?!1:this._loading}get loadLabel(){const e=this._client,t=this._getError();if(t||e&&e.loadStatus.get()===W.Error)return`Something went wrong: ${t&&t.message}.`;if(e)switch(e.loadStatus.get()){case W.QueryAccount:return"Querying account encryption setup\u2026";case W.AccountSetup:return"";case W.SessionSetup:return"Setting up your encryption keys\u2026";case W.Loading:return"Loading your conversations\u2026";case W.FirstSync:return"Getting your conversations from the server\u2026";default:return this._client.loadStatus.get()}return"Preparing\u2026"}_getError(){var e;return this._error||((e=this._client)==null?void 0:e.loadError)}get hasError(){return!!this._getError()}async exportLogs(){const e=await this.logger.export();this.platform.saveFileAs(e.asBlob(),`hydrogen-logs-${this.platform.clock.now()}.json`)}async logout(){await this._client.startLogout(this.navigation.path.get("session").value),this.navigation.push("session",!0)}get accountSetupViewModel(){return this._accountSetupViewModel}}class Jp extends L{constructor(e){super(e),this._isBusy=!1,this._errorMessage="";const{loginOptions:t,attemptLogin:s}=e;this._loginOptions=t,this._attemptLogin=s}get isBusy(){return this._isBusy}get errorMessage(){return this._errorMessage}setBusy(e){this._isBusy=e,this.emitChange("isBusy")}_showError(e){this._errorMessage=e,this.emitChange("errorMessage")}async login(e,t){this._errorMessage="",this.emitChange("errorMessage");const s=await this._attemptLogin(this._loginOptions.password(e,t));let i="";switch(s){case Pt.Credentials:i=this.i18n`Your username and/or password don't seem to be correct.`;break;case Pt.Connection:i=this.i18n`Can't connect to ${this._loginOptions.homeserver}.`;break;case Pt.Unknown:i=this.i18n`Something went wrong while checking your login and password.`;break}i&&this._showError(i)}}class Qp extends L{constructor(e){super(e),this._isBusy=!1,this._sso=e.loginOptions.sso,this._isBusy=!1}get isBusy(){return this._isBusy}setBusy(e){this._isBusy=e,this.emitChange("isBusy")}async startSSOLogin(){await this.platform.settingsStorage.setString("sso_ongoing_login_homeserver",this._sso.homeserver);const e=this._sso.createSSORedirectURL(this.urlRouter.createSSOCallbackURL());this.platform.openUrl(e)}}class Xp extends L{constructor(e){super(e),this._errorMessage="";const{loginToken:t,client:s,attemptLogin:i}=e;this._loginToken=t,this._client=s,this._attemptLogin=i,this._errorMessage="",this.performSSOLoginCompletion()}get errorMessage(){return this._errorMessage}_showError(e){this._errorMessage=e,this.emitChange("errorMessage")}async performSSOLoginCompletion(){if(!this._loginToken)return;const e=await this.platform.settingsStorage.getString("sso_ongoing_login_homeserver");let t;try{t=await this._client.queryLogin(e).result}catch(r){this._showError(r.message);return}if(!t.token){this.navigation.push("session");return}const s=await this._attemptLogin(t.token(this._loginToken));let i="";switch(s){case Pt.Credentials:i=this.i18n`Your login token is invalid.`;break;case Pt.Connection:i=this.i18n`Can't connect to ${e}.`;break;case Pt.Unknown:i=this.i18n`Something went wrong while checking your login token.`;break}i&&this._showError(i)}}class Zp extends L{constructor(e){super(e),this._hideHomeserver=!1,this._isBusy=!1,this._errorMessage="";const{ready:t,defaultHomeserver:s,loginToken:i}=e;this._ready=t,this._loginToken=i,this._client=new Nr(this.platform,this.features),this._homeserver=s,this._initViewModels()}get passwordLoginViewModel(){return this._passwordLoginViewModel}get startSSOLoginViewModel(){return this._startSSOLoginViewModel}get completeSSOLoginViewModel(){return this._completeSSOLoginViewModel}get homeserver(){return this._homeserver}get resolvedHomeserver(){var e;return(e=this._loginOptions)==null?void 0:e.homeserver}get errorMessage(){return this._errorMessage}get showHomeserver(){return!this._hideHomeserver}get loadViewModel(){return this._loadViewModel}get isBusy(){return this._isBusy}get isFetchingLoginOptions(){return!!this._abortQueryOperation}goBack(){this.navigation.push("session")}_initViewModels(){this._loginToken?(this._hideHomeserver=!0,this._completeSSOLoginViewModel=this.track(new Xp(this.childOptions({client:this._client,attemptLogin:e=>this.attemptLogin(e),loginToken:this._loginToken}))),this.emitChange("completeSSOLoginViewModel")):this.queryHomeserver()}_showPasswordLogin(){this._passwordLoginViewModel=this.track(new Jp(this.childOptions({loginOptions:this._loginOptions,attemptLogin:e=>this.attemptLogin(e)}))),this.emitChange("passwordLoginViewModel")}_showSSOLogin(){this._startSSOLoginViewModel=this.track(new Qp(this.childOptions({loginOptions:this._loginOptions}))),this.emitChange("startSSOLoginViewModel")}_showError(e){this._errorMessage=e,this.emitChange("errorMessage")}_setBusy(e){var t,s;this._isBusy=e,(t=this._passwordLoginViewModel)==null||t.setBusy(e),(s=this._startSSOLoginViewModel)==null||s.setBusy(e),this.emitChange("isBusy")}async attemptLogin(e){this._setBusy(!0),this._client.startWithLogin(e,{inspectAccountSetup:!0});const t=this._client.loadStatus;return await t.waitFor(r=>r!==W.Login).promise,this._setBusy(!1),t.get()===W.LoginFailed?this._client.loginFailure:(this._hideHomeserver=!0,this.emitChange("hideHomeserver"),this._disposeViewModels(),this._createLoadViewModel(),null)}_createLoadViewModel(){this._loadViewModelSubscription=this.disposeTracked(this._loadViewModelSubscription),this._loadViewModel=this.disposeTracked(this._loadViewModel),this._loadViewModel=this.track(new yc(this.childOptions({ready:e=>{this._client=null,this._ready(e)},client:this._client,homeserver:this._homeserver}))),this._loadViewModel.start(),this.emitChange("loadViewModel"),this._loadViewModelSubscription=this.track(this._loadViewModel.disposableOn("change",()=>{this._loadViewModel.loading||(this._loadViewModelSubscription=this.disposeTracked(this._loadViewModelSubscription)),this._setBusy(!1)}))}_disposeViewModels(){this._startSSOLoginViewModel=this.disposeTracked(this._startSSOLoginViewModel),this._passwordLoginViewModel=this.disposeTracked(this._passwordLoginViewModel),this._completeSSOLoginViewModel=this.disposeTracked(this._completeSSOLoginViewModel),this.emitChange("disposeViewModels")}async setHomeserver(e){this._homeserver=e,this._loginOptions=void 0,this._queriedHomeserver=void 0,this._showError(""),this._disposeViewModels(),this._abortQueryOperation=this.disposeTracked(this._abortQueryOperation),this.emitChange("loginViewModels"),this.disposeTracked(this._abortHomeserverQueryTimeout);const t=this.clock.createTimeout(1e3);this._abortHomeserverQueryTimeout=this.track(()=>t.abort());try{await t.elapsed()}catch(s){if(s.name==="AbortError")return;throw s}this._abortHomeserverQueryTimeout=this.disposeTracked(this._abortHomeserverQueryTimeout),this.queryHomeserver()}async queryHomeserver(){if(!(this._homeserver===this._queriedHomeserver||this._homeserver==="")){this._queriedHomeserver=this._homeserver,this._abortHomeserverQueryTimeout=this.disposeTracked(this._abortHomeserverQueryTimeout),this._abortQueryOperation=this.disposeTracked(this._abortQueryOperation);try{const e=this._client.queryLogin(this._homeserver);this._abortQueryOperation=this.track(()=>e.abort()),this.emitChange("isFetchingLoginOptions"),this._loginOptions=await e.result,this.emitChange("resolvedHomeserver")}catch(e){if(e.name==="AbortError")return;this._loginOptions=void 0}finally{this._abortQueryOperation=this.disposeTracked(this._abortQueryOperation),this.emitChange("isFetchingLoginOptions")}this._loginOptions?(this._loginOptions.sso&&this._showSSOLogin(),this._loginOptions.password&&this._showPasswordLogin(),!this._loginOptions.sso&&!this._loginOptions.password&&this._showError("This homeserver supports neither SSO nor password based login flows")):this._showError(`Could not query login methods supported by ${this.homeserver}`)}}dispose(){super.dispose(),this._client&&this._client.deleteSession()}}class eg extends L{constructor(e){super(e),this._sessionId=e.sessionId,this._busy=!1,this._showConfirm=!0,this._error=void 0}get showConfirm(){return this._showConfirm}get busy(){return this._busy}get cancelUrl(){return this.urlRouter.urlForSegment("session",!0)}async logout(){this._busy=!0,this._showConfirm=!1,this.emitChange("busy");try{await new Nr(this.platform).startLogout(this._sessionId),this.navigation.push("session",!0)}catch(e){this._error=e,this._busy=!1,this.emitChange("busy")}}get status(){return this._error?this.i18n`Could not log out of device: ${this._error.message}`:this.i18n`Logging out… Please don't close the app.`}}class tg extends L{constructor(e){super(e),this._showStatus=!1,this._showSpinner=!1,this._sessionId=e.sessionId,this._logoutPromise=this.forceLogout()}async forceLogout(){try{await new Nr(this.platform).startForcedLogout(this._sessionId)}catch(e){this._error=e,this._showSpinner=!1,this._showStatus=!0,this.emitChange("error")}}async proceed(){this._showSpinner=!0,this._showStatus=!0,this.emitChange("showStatus"),await this._logoutPromise,this._error||this.navigation.push("login",!0)}get status(){return this._error?this.i18n`Could not log out of device: ${this._error.message}`:this.i18n`Logging out… Please don't close the app.`}get showStatus(){return this._showStatus}get showSpinner(){return this._showSpinner}}class sg extends L{constructor(e,t){super(e),this._pickerVM=t,this._sessionInfo=e.sessionInfo,this._isDeleting=!1,this._isClearing=!1,this._error=null,this._exportDataUrl=null}get error(){return this._error&&this._error.message}get id(){return this._sessionInfo.id}get openUrl(){return this.urlRouter.urlForSegment("session",this.id)}get label(){const{userId:e,comment:t}=this._sessionInfo;return t?`${e} (${t})`:e}get sessionInfo(){return this._sessionInfo}get exportDataUrl(){return this._exportDataUrl}get avatarColorNumber(){return Re(this._sessionInfo.userId)}get avatarInitials(){return Ee(this._sessionInfo.userId)}}class ig extends L{constructor(e){super(e),this._sessions=new fn((t,s)=>t.id.localeCompare(s.id)),this._loadViewModel=null,this._error=null}async load(){const e=await this.platform.sessionInfoStorage.getAll();this._sessions.setManyUnsorted(e.map(t=>new sg(this.childOptions({sessionInfo:t}),this)))}get loadViewModel(){return this._loadViewModel}get sessions(){return this._sessions}get cancelUrl(){return this.urlRouter.urlForSegment("login")}}class rg extends L{constructor(e){super(e),this._error=null,this._sessionPickerViewModel=null,this._sessionLoadViewModel=null,this._loginViewModel=null,this._logoutViewModel=null,this._forcedLogoutViewModel=null,this._sessionViewModel=null,this._pendingClient=null}async load(){this.track(this.navigation.observe("login").subscribe(()=>this._applyNavigation())),this.track(this.navigation.observe("session").subscribe(()=>this._applyNavigation())),this.track(this.navigation.observe("sso").subscribe(()=>this._applyNavigation())),this.track(this.navigation.observe("logout").subscribe(()=>this._applyNavigation())),this._applyNavigation(!0)}async _applyNavigation(e){var c,l,h,a;const t=this.navigation.path.get("login"),s=(c=this.navigation.path.get("logout"))==null?void 0:c.value,i=(l=this.navigation.path.get("forced"))==null?void 0:l.value,r=(h=this.navigation.path.get("session"))==null?void 0:h.value,o=(a=this.navigation.path.get("sso"))==null?void 0:a.value;if(t)this.activeSection!=="login"&&this._showLogin();else if(s&&i)this.activeSection!=="forced-logout"&&this._showForcedLogout(s);else if(s)this.activeSection!=="logout"&&this._showLogout(s);else if(r===!0)this.activeSection!=="picker"&&this._showPicker();else if(r){if(!this._sessionViewModel||this._sessionViewModel.id!==r)if(this._pendingClient&&this._pendingClient.sessionId===r){const u=this._pendingClient;this._pendingClient=null,this._showSession(u)}else this._pendingClient&&(this._pendingClient.dispose(),this._pendingClient=null),this._showSessionLoader(r)}else if(o)this.urlRouter.normalizeUrl(),this.activeSection!=="login"&&this._showLogin(o);else try{if(!(e&&this.urlRouter.tryRestoreLastUrl())){const u=await this.platform.sessionInfoStorage.getAll();u.length===0?this.navigation.push("login"):u.length===1?this.navigation.push("session",u[0].id):this.navigation.push("session")}}catch(u){this._setSection(()=>this._error=u)}}async _showPicker(){this._setSection(()=>{this._sessionPickerViewModel=new ig(this.childOptions())});try{await this._sessionPickerViewModel.load()}catch(e){this._setSection(()=>this._error=e)}}_showLogin(e){this._setSection(()=>{this._loginViewModel=new Zp(this.childOptions({defaultHomeserver:this.platform.config.defaultHomeServer,ready:t=>{this._pendingClient=t,this.navigation.push("session",t.sessionId)},loginToken:e}))})}_showLogout(e){this._setSection(()=>{this._logoutViewModel=new eg(this.childOptions({sessionId:e}))})}_showForcedLogout(e){this._setSection(()=>{this._forcedLogoutViewModel=new tg(this.childOptions({sessionId:e}))})}_showSession(e){this._setSection(()=>{this._sessionViewModel=new zp(this.childOptions({client:e})),this._sessionViewModel.start()})}_showSessionLoader(e){const t=new Nr(this.platform,this.features);t.startWithExistingSession(e),this._setSection(()=>{this._sessionLoadViewModel=new yc(this.childOptions({client:t,ready:s=>this._showSession(s)})),this._sessionLoadViewModel.start()})}get activeSection(){return this._error?"error":this._sessionViewModel?"session":this._loginViewModel?"login":this._logoutViewModel?"logout":this._forcedLogoutViewModel?"forced-logout":this._sessionPickerViewModel?"picker":this._sessionLoadViewModel?"loading":"redirecting"}_setSection(e){this._error=null,this._sessionPickerViewModel=this.disposeTracked(this._sessionPickerViewModel),this._sessionLoadViewModel=this.disposeTracked(this._sessionLoadViewModel),this._loginViewModel=this.disposeTracked(this._loginViewModel),this._logoutViewModel=this.disposeTracked(this._logoutViewModel),this._forcedLogoutViewModel=this.disposeTracked(this._forcedLogoutViewModel),this._sessionViewModel=this.disposeTracked(this._sessionViewModel),e(),this._sessionPickerViewModel&&this.track(this._sessionPickerViewModel),this._sessionLoadViewModel&&this.track(this._sessionLoadViewModel),this._loginViewModel&&this.track(this._loginViewModel),this._logoutViewModel&&this.track(this._logoutViewModel),this._forcedLogoutViewModel&&this.track(this._forcedLogoutViewModel),this._sessionViewModel&&this.track(this._sessionViewModel),this.emitChange("activeSection")}get error(){return this._error}get sessionViewModel(){return this._sessionViewModel}get loginViewModel(){return this._loginViewModel}get logoutViewModel(){return this._logoutViewModel}get forcedLogoutViewModel(){return this._forcedLogoutViewModel}get sessionPickerViewModel(){return this._sessionPickerViewModel}get sessionLoadViewModel(){return this._sessionLoadViewModel}}async function ng(n){try{await n.init();const e=await Xs.load(n.settingsStorage),t=h_();n.setNavigation(t);const s=d_({navigation:t,history:n.history});s.attach();const i=new rg({platform:n,urlRouter:s,navigation:t,features:e});await i.load(),n.createAndMountRootView(i)}catch(e){console.error(`${e.message}: +${e.stack}`)}}function og(n,e,t,s){const i=n(e);let r=!1;return i.elapsed().then(()=>{r=!0,t.abort()},()=>{}),s.then(o=>(i.abort(),o),o=>{throw i.abort(),o.name==="AbortError"&&r?new Ut(`Request timed out after ${e}ms`,!0):o})}function wc(n,e=Math.random){return n.includes("?")?n=n+"&":n=n+"?",n+`_cacheBuster=${Math.ceil(e()*Number.MAX_SAFE_INTEGER)}`}function vc(n){var t;const e=new FormData;for(const[s,i]of n)((t=i.blob)==null?void 0:t.nativeBlob)&&i.name?e.set(s,i.blob.nativeBlob,i.name):e.set(s,i);return e}class ag{constructor(e,t){this._promise=e,this._xhr=t}abort(){this._xhr.abort()}response(){return this._promise}}function cg(n,{method:e,headers:t,timeout:s,format:i,uploadProgress:r}){const o=new XMLHttpRequest;if(r&&o.upload.addEventListener("progress",c=>r(c.loaded)),o.open(e,n),i==="buffer"&&(o.responseType="arraybuffer"),t)for(const[c,l]of t.entries())try{o.setRequestHeader(c,l)}catch(h){console.info(`Could not set ${c} header: ${h.message}`)}return s&&(o.timeout=s),o}function lg(n,e,t){return new Promise((s,i)=>{n.addEventListener("load",()=>s(n)),n.addEventListener("abort",()=>i(new rt)),n.addEventListener("error",()=>i(new Ut(`Error ${e} ${t}`))),n.addEventListener("timeout",()=>i(new Ut(`Timeout ${e} ${t}`,!0)))})}function bc(n,e){let{cache:t,format:s,body:i,method:r}=e;t||(n=wc(n));const o=cg(n,e),c=lg(o,r,n).then(l=>{const{status:h}=l;let a=null;return s==="buffer"?a=l.response:l.getResponseHeader("Content-Type")==="application/json"&&(a=JSON.parse(l.responseText)),{status:h,body:a}});return i!=null&&i.nativeBlob&&(i=i.nativeBlob),i instanceof Map&&(i=vc(i)),o.send(i||null),new ag(c,o)}class Lo{constructor(e,t){if(t)this.promise=e,this._controller=t;else{const s=new Promise((i,r)=>{this._controller={abort(){const o=new Error("fetch request aborted");o.name="AbortError",r(o)}}});this.promise=Promise.race([e,s])}}abort(){this._controller.abort()}response(){return this.promise}}function hg(n,e){return function(s,i){if(e!=null&&e.haltRequests)return new Lo(new Promise(()=>{}),{});if(i!=null&&i.uploadProgress)return bc(s,i);let{method:r,headers:o,body:c,timeout:l,format:h,cache:a=!1}=i;const u=typeof AbortController=="function"?new AbortController:null;c!=null&&c.nativeBlob&&(c=c.nativeBlob),c instanceof Map&&(c=vc(c));let p={method:r,body:c};if(u&&(p=Object.assign(p,{signal:u.signal})),a||(s=wc(s)),p=Object.assign(p,{mode:"cors",credentials:"omit",referrer:"no-referrer",cache:"default"}),o){const v=new Headers;for(const[M,R]of o.entries())v.append(M,R);p.headers=v}const g=fetch(s,p).then(async v=>{const{status:M}=v;let R;try{h==="json"?R=await v.json():h==="buffer"?R=await v.arrayBuffer():h==="text"&&(R=await v.text())}catch(N){if(!(N.name==="SyntaxError"&&M>=400))throw N}return{status:M,body:R}},v=>{throw v.name==="AbortError"?new rt:v instanceof TypeError?new Ut(`${r} ${s}: ${v.message}`):v}),f=new Lo(g,u);return l&&(f.promise=og(n,l,f,f.promise)),f}}class dg{constructor(e){this._name=e}getAll(){const e=localStorage.getItem(this._name);if(e){const t=JSON.parse(e);if(Array.isArray(t))return Promise.resolve(t)}return Promise.resolve([])}async updateAccessToken(e,t){const s=await this.getAll(),i=s.find(r=>r.id===e);if(!i)throw Error("No session found");i.accessToken=t,localStorage.setItem(this._name,JSON.stringify(s))}async updateLastUsed(e,t){const s=await this.getAll(),i=s.find(r=>r.id===e);i&&(i.lastUsed=t,localStorage.setItem(this._name,JSON.stringify(s)))}async get(e){const t=await this.getAll();if(t)return t.find(s=>s.id===e)}async add(e){const t=await this.getAll();t.push(e),localStorage.setItem(this._name,JSON.stringify(t))}async delete(e){let t=await this.getAll();t=t.filter(s=>s.id!==e),localStorage.setItem(this._name,JSON.stringify(t))}}class ug{constructor(e){this._prefix=e}async setInt(e,t){this._set(e,t)}async getInt(e,t=0){const s=window.localStorage.getItem(`${this._prefix}${e}`);return typeof s=="string"?parseInt(s,10):t}async setBool(e,t){this._set(e,t)}async getBool(e,t=!1){const s=window.localStorage.getItem(`${this._prefix}${e}`);return typeof s=="string"?s==="true":t}async setString(e,t){this._set(e,t)}async getString(e){return window.localStorage.getItem(`${this._prefix}${e}`)}async remove(e){window.localStorage.removeItem(`${this._prefix}${e}`)}async _set(e,t){window.localStorage.setItem(`${this._prefix}${e}`,t)}}class mg{constructor(){this._encoder=null,this._decoder=null}encode(e){return this._encoder||(this._encoder=new TextEncoder),this._encoder.encode(e)}decode(e){return this._decoder||(this._decoder=new TextDecoder),this._decoder.decode(e)}}var Ms={};(function(){for(var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e=new Uint8Array(256),t=0;t>2],c+=n[(i[r]&3)<<4|i[r+1]>>4],c+=n[(i[r+1]&15)<<2|i[r+2]>>6],c+=n[i[r+2]&63];return o%3===2?c=c.substring(0,c.length-1)+"=":o%3===1&&(c=c.substring(0,c.length-2)+"=="),c},Ms.decode=function(s){var i=s.length*.75,r=s.length,o,c=0,l,h,a,u;s[s.length-1]==="="&&(i--,s[s.length-2]==="="&&i--);var p=new ArrayBuffer(i),g=new Uint8Array(p);for(o=0;o>4,g[c++]=(h&15)<<4|a>>2,g[c++]=(a&3)<<6|u&63;return p}})();class _g{encodeUnpadded(e){const t=Ms.encode(e),s=t.indexOf("=");return s!==-1?t.substr(0,s):t}encode(e){return Ms.encode(e)}decode(e){return Ms.decode(e)}}var Sc={isBuffer:function(n){return n instanceof Uint8Array},from:function(n){return n},allocUnsafe:function(n){return Sc.alloc(n)},alloc:function(n){return new Uint8Array(n)}},pg=Object.freeze(Object.defineProperty({__proto__:null,Buffer:Sc},Symbol.toStringTag,{value:"Module"})),gg=_a(pg),dr=gg.Buffer;function fg(n){if(n.length>=255)throw new TypeError("Alphabet too long");for(var e=new Uint8Array(256),t=0;t>>0,F=new Uint8Array(N);M!==R;){for(var T=g[M],D=0,B=N-1;(T!==0||D>>0,F[B]=T%o>>>0,T=T/o>>>0;if(T!==0)throw new Error("Non-zero carry");v=D,M++}for(var G=N-v;G!==N&&F[G]===0;)G++;for(var $e=c.repeat(f);G>>0,N=new Uint8Array(R);g[f];){var F=e[g.charCodeAt(f)];if(F===255)return;for(var T=0,D=R-1;(F!==0||T>>0,N[D]=F%256>>>0,F=F/256>>>0;if(F!==0)throw new Error("Non-zero carry");M=T,f++}if(g[f]!==" "){for(var B=R-M;B!==R&&N[B]===0;)B++;var G=dr.allocUnsafe(v+(R-B));G.fill(0,0,v);for(var $e=v;B!==R;)G[$e++]=N[B++];return G}}}function p(g){var f=u(g);if(f)return f;throw new Error("Non-base"+o+" character")}return{encode:a,decodeUnsafe:u,decode:p}}var yg=fg,wg=yg,vg="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",Ko=wg(vg);class bg{encode(e){return Ko.encode(e)}decode(e){return Ko.decode(e)}}class Sg{constructor(){this.utf8=new mg,this.base64=new _g,this.base58=new bg}}class kg{constructor(e){this._workerPool=e}megolmDecrypt(e,t){const s=e.export_session(e.first_known_index());return this._workerPool.send({type:"megolm_decrypt",ciphertext:t,sessionKey:s})}async createAccountAndOTKs(e,t){let s;window.msCrypto&&(s=[window.msCrypto.getRandomValues(new Uint8Array(64)),window.msCrypto.getRandomValues(new Uint8Array(t*32))]);const i=await this._workerPool.send({type:"olm_create_account_otks",randomValues:s,otkAmount:t}).response();e.unpickle("",i)}async createOutboundOlmSession(e,t,s,i){const r=e.pickle("");let o;window.msCrypto&&(o=[window.msCrypto.getRandomValues(new Uint8Array(64))]);const c=await this._workerPool.send({type:"olm_create_outbound",accountPickle:r,theirIdentityKey:s,theirOneTimeKey:i,randomValues:o}).response();t.unpickle("",c)}dispose(){this._workerPool.dispose()}}class Ig{constructor(e){var t;this.options=e,this._queuedItems=this._loadQueuedItems(),window.addEventListener("pagehide",this,!1),this._flushInterval=this.options.platform.clock.createInterval(()=>this._tryFlush(),(t=this.options.flushInterval)!=null?t:60*1e3)}setLogger(e){this.logger=e}reportItem(e,t,s){const i=this.prepareItemForQueue(e,t,s);i&&this._queuedItems.push(i)}async export(){const e=await this._openDB();try{const s=e.transaction(["logs"],"readonly").objectStore("logs"),i=await vh(s.openCursor(),()=>!1),r=this.getSerializedOpenItems(),o=i.concat(this._queuedItems).concat(r);return new Mg(o,this,this.options.platform)}finally{try{e.close()}catch{}}}dispose(){window.removeEventListener("pagehide",this,!1),this._flushInterval.dispose()}handleEvent(e){e.type==="pagehide"&&this._finishAllAndFlush()}async _tryFlush(){var t;const e=await this._openDB();try{const s=e.transaction(["logs"],"readwrite"),i=s.objectStore("logs"),r=this._queuedItems.length;for(const l of this._queuedItems)i.add(l);const o=await Me(i.count()),c=(t=this.options.limit)!=null?t:3e3;if(o>c){let l=o-c+Math.round(.1*c);await _e(i.openCursor(),(h,a,u)=>(u.delete(),l-=1,{done:l===0}))}await Pi(s),this._queuedItems.splice(0,r)}catch(s){console.error("Could not flush logs",s)}finally{try{e.close()}catch{}}}_finishAllAndFlush(){this.logger&&(this.logger.log({l:"pagehide, closing logs",t:"navigation"}),this.logger.forceFinish()),this._persistQueuedItems(this._queuedItems)}_loadQueuedItems(){const e=`${this.options.name}_queuedItems`;try{const t=window.localStorage.getItem(e);if(t)return window.localStorage.removeItem(e),JSON.parse(t)}catch(t){console.error("Could not load queued log items",t)}return[]}_openDB(){return In(this.options.name,e=>e.createObjectStore("logs",{keyPath:"id",autoIncrement:!0}),1)}prepareItemForQueue(e,t,s){let i=e.serialize(t,void 0,s);if(i)return this.options.serializedTransformer&&(i=this.options.serializedTransformer(i)),{json:JSON.stringify(i)}}_persistQueuedItems(e){try{window.localStorage.setItem(`${this.options.name}_queuedItems`,JSON.stringify(e))}catch(t){console.error("Could not persist queued log items in localStorage, they will likely be lost",t)}}async removeItems(e){const t=await this._openDB();try{const s=t.transaction(["logs"],"readwrite"),i=s.objectStore("logs");for(const r of e)if(typeof r.id=="number")i.delete(r.id);else{const o=this._queuedItems.indexOf(r);o===-1&&this._queuedItems.splice(o,1)}await Pi(s)}finally{try{t.close()}catch{}}}getSerializedOpenItems(){const e=[];if(!this.logger)return e;const t=new br;for(const s of this.logger.getOpenRootItems()){const i=this.prepareItemForQueue(s,t,!1);i&&e.push(i)}return e}}class Mg{constructor(e,t,s){this._items=e,this._logger=t,this._platform=s}get count(){return this._items.length}removeFromStore(){return this._logger.removeItems(this._items)}asBlob(){const e=this.toJSON(),t=this._platform.encoding.utf8.encode(e);return this._platform.createBlob(t,"application/json")}toJSON(){var s;const e={formatVersion:1,appVersion:(s=this._platform.updateService)==null?void 0:s.version,platform:this._platform.description,items:this._items.map(i=>JSON.parse(i.json))};return JSON.stringify(e)}}class Cg{reportItem(e){Ic(e)}setLogger(e){this.logger=e}printOpenItems(){if(!!this.logger)for(const e of this.logger.getOpenRootItems())this.reportItem(e)}}const Eg=["l","id"];function Rg(n){return Object.entries(n).filter(([e])=>!Eg.includes(e)).reduce((e,[t,s])=>(e=e||{},e[t]=s,e),null)}function kc(n){if(n.error)return!0;if(n.children){for(const e of n.children)if(kc(e))return!0}return!1}function Ic(n){const e=`${Tg(n)} (@${n.start}ms, duration: ${n.duration}ms)`,t=Rg(n.values),s=n.children||t;if(s?(kc(n)?console.group(e):console.groupCollapsed(e),n.error&&console.error(n.error)):n.error?console.error(n.error):console.log(e),t&&console.table(t),n.children)for(const i of n.children)Ic(i);s&&console.groupEnd()}function Tg(n){return n.values.t==="network"?`${n.values.method} ${n.values.url}`:n.values.l&&typeof n.values.id!="undefined"?`${n.values.l} ${n.values.id}`:n.values.l&&typeof n.values.status!="undefined"?`${n.values.l} (${n.values.status})`:n.values.l&&typeof n.values.type!="undefined"?`${n.values.l} (${n.values.type})`:n.values.l&&n.error?`${n.values.l} failed`:typeof n.values.ref!="undefined"?`ref ${n.values.ref}`:n.values.l||n.values.type}class Zs{constructor(e,t,s,i){this._discard=!1,this._logger=s,this.start=s._now(),this._values=typeof e=="string"?{l:e}:e,this.logLevel=t,this._filterCreator=i}discard(){this._discard=!0}runDetached(e,t,s,i){return this._logger.runDetached(e,t,s,i)}wrapDetached(e,t,s,i){this.refDetached(this.runDetached(e,t,s,i))}refDetached(e,t){e.ensureRefId(),this.log({ref:e.values.refId},t)}ensureRefId(){this._values.refId||this.set("refId",this._logger._createRefId())}wrap(e,t,s,i){return this.child(e,s,i).run(t)}get duration(){if(this.end)return this.end-this.start}durationWithoutType(e){const t=this.durationOfType(e);if(this.duration&&t)return this.duration-t}durationOfType(e){return this._values.t===e?this.duration:this._children?this._children.reduce((t,s)=>{const i=s.durationOfType(e);return t+(i!=null?i:0)},0):0}log(e,t){const s=this.child(e,t);return s.end=s.start,s}set(e,t){if(typeof e=="object"){const s=e;Object.assign(this._values,s)}else this._values[e]=t;return this}serialize(e,t,s){if(this._discard)return;if(this._filterCreator)try{e=this._filterCreator(new br(e),this)}catch(o){console.error("Error creating log filter",o)}let i=null;if(this._children&&(i=this._children.reduce((o,c)=>{const l=c.serialize(e,this.start,!1);return l&&(o===null&&(o=[]),o.push(l)),o},null)),e&&!e.filter(this,i))return;const r={s:typeof t=="number"?this.start-t:this.start,d:this.duration,v:this._values,l:this.logLevel};return this.error&&(r.e={stack:this.error.stack,name:this.error.name,message:this.error.message.split(` +`)[0]}),s&&(r.f=!0),i&&(r.c=i),r}run(e){this.end!==void 0&&console.trace("log item is finished, additional logs will likely not be recorded");try{const t=e(this);return t instanceof Promise?t.then(s=>(this.finish(),s),s=>{throw this.catch(s)}):(this.finish(),t)}catch(t){throw this.catch(t)}}finish(){if(this.end===void 0){if(this._children)for(const e of this._children)e.finish();this.end=this._logger._now()}}forceFinish(){this.finish()}get level(){return Ge}catch(e){return this.error=e,this.logLevel=Ge.Error,this.finish(),e}child(e,t,s){this.end&&console.trace(`log item ${this.values.l} finished, additional log ${JSON.stringify(e)} will likely not be recorded`),t||(t=this.logLevel||Ge.Info);const i=new Zs(e,t,this._logger,s);return this._children||(this._children=[]),this._children.push(i),i}get logger(){return this._logger}get values(){return this._values}get children(){return this._children}}class Ag{constructor({platform:e}){this._openItems=new Set,this.reporters=[],this._platform=e}log(e,t=Ge.Info){const s=new Zs(e,t,this);return s.end=s.start,this._persistItem(s,void 0,!1),s}child(e,t=Ge.Info,s){const i=new xg(e,t,this,s);return this._openItems.add(i),i}wrapOrRun(e,t,s,i,r){return e?e.wrap(t,s,i,r):this.run(t,s,i,r)}runDetached(e,t,s,i){s||(s=Ge.Info);const r=new Zs(e,s,this);return this._run(r,t,s,!1,i),r}run(e,t,s,i){s===void 0&&(s=Ge.Info);const r=new Zs(e,s,this);return this._run(r,t,s,!0,i)}_run(e,t,s,i,r){this._openItems.add(e);const o=()=>{let c=new br;if(r)try{c=r(c,e)}catch(l){console.error("Error while creating log filter",l)}else c=c.minLevel(s);try{this._persistItem(e,c,!1)}catch(l){console.error("Could not persist log item",l)}this._openItems.delete(e)};try{let c=e.run(t);if(c instanceof Promise){if(c=c.then(l=>(o(),l),l=>{if(o(),i)throw l}),i)return c}else if(o(),i)return c}catch(c){if(o(),i)throw c}}addReporter(e){e.setLogger(this),this.reporters.push(e)}getOpenRootItems(){return this._openItems}forceFinish(){for(const e of this._openItems){e.forceFinish();try{this._persistItem(e,new br,!0)}catch(t){console.error("Could not serialize log item",t)}}this._openItems.clear()}_removeItemFromOpenList(e){this._openItems.delete(e)}_persistItem(e,t,s){for(var i=0;i(typeof i=="function"&&(i=i(e)),i?t+(t.length?" ":"")+s:t),"")}function ei(n,e,t){e==="className"&&(e="class"),t===!1?n.removeAttribute(e):(t===!0&&(t=e),n.setAttribute(e,t))}function Vg(n,e,t){return Cc(Ln,n,e,t)}function Cc(n,e,t,s){t&&Mc(t)&&(s=t,t=void 0);const i=document.createElementNS(n,e);if(t)for(let[r,o]of Object.entries(t))typeof o=="object"&&(o=o!==null&&r==="className"?ri(o,void 0):!1),ei(i,r,o);if(s){Array.isArray(s)||(s=[s]);for(let r of s)typeof r=="string"&&(r=Ft(r)),i.appendChild(r)}return i}function Ft(n){return document.createTextNode(n)}const Ln="http://www.w3.org/1999/xhtml",Ng="http://www.w3.org/2000/svg",Ec={[Ln]:["br","a","ol","ul","li","div","h1","h2","h3","h4","h5","h6","p","strong","em","span","img","section","header","main","footer","dialog","article","aside","del","blockquote","details","summary","table","thead","tbody","tr","th","td","hr","pre","code","button","time","input","textarea","select","option","optgroup","label","form","progress","output","video","style"],[Ng]:["svg","g","path","circle","ellipse","rect","use"]},H={};for(const[n,e]of Object.entries(Ec))for(const t of e)H[t]=function(s,i){return Cc(n,t,s,i)};function Bi(n,e){let t;try{t=n.mount(e)}catch(s){console.error(s),t=Dg(s)}return t}function Dg(n){const e=new Error().stack;let t=null;return e&&(t=e.split(` +`)[1]),H.div([H.h2("Something went wrong\u2026"),H.h3(n.message),H.p(`This occurred while running ${t}.`),H.pre(n.stack)])}function Bo(n,e,t){if(e===n.childElementCount)n.appendChild(t);else{const i=n.children[e];n.insertBefore(t,i)}}function Ug(n){n.innerHTML=""}function Kn(n){return async e=>{var t,s;(t=e.target)==null||t.setAttribute("disabled","disabled"),await n(e),(s=e.target)==null||s.removeAttribute("disabled")}}class os{constructor({list:e,onItemClick:t,className:s,tagName:i="ul",parentProvidesUpdates:r=!0},o){this._onItemClick=t,this._list=e,this._className=s,this._tagName=i,this._root=void 0,this._subscription=void 0,this._childCreator=o,this._childInstances=void 0,this._mountArgs={parentProvidesUpdates:r}}root(){return this._root}update(e){if(e.list){if(this._subscription)for(this._unloadList();this._root.lastChild;)this._root.lastChild.remove();this._list=e.list,this.loadList()}}mount(){const e={};this._className&&(e.className=this._className);const t=this._root=Vg(this._tagName,e);return this.loadList(),this._onItemClick&&t.addEventListener("click",this),t}handleEvent(e){e.type==="click"&&this._handleClick(e)}unmount(){this._list&&this._unloadList()}_handleClick(e){if(e.target===this._root||!this._onItemClick)return;let t=e.target;for(;t.parentNode!==this._root;)t=t.parentNode;const s=Array.prototype.indexOf.call(this._root.childNodes,t),i=this._childInstances[s];i&&this._onItemClick(i,e)}_unloadList(){this._subscription=this._subscription();for(let e of this._childInstances)e.unmount();this._childInstances=void 0}loadList(){if(!this._list)return;this._subscription=this._list.subscribe(this),this._childInstances=[];const e=document.createDocumentFragment();for(let t of this._list){const s=this._childCreator(t);this._childInstances.push(s),e.appendChild(Bi(s,this._mountArgs))}this._root.appendChild(e)}onReset(){for(const e of this._childInstances)e.root().remove(),e.unmount();this._childInstances.length=0}onAdd(e,t){this.addChild(e,t)}onRemove(e,t){this.removeChild(e)}onMove(e,t,s){this.moveChild(e,t)}onUpdate(e,t,s){this.updateChild(e,t,s)}addChild(e,t){const s=this._childCreator(t);this._childInstances.splice(e,0,s),Bo(this._root,e,Bi(s,this._mountArgs))}removeChild(e){const[t]=this._childInstances.splice(e,1);t.root().remove(),t.unmount()}moveChild(e,t){const[s]=this._childInstances.splice(e,1);this._childInstances.splice(t,0,s),s.root().remove(),Bo(this._root,t,s.root())}updateChild(e,t,s){if(this._childInstances){const i=this._childInstances[e];i&&i.update(t,s)}}recreateItem(e,t){if(this._childInstances){const s=this._childCreator(t);if(!s)this.onRemove(e,t);else{const[i]=this._childInstances.splice(e,1,s);this._root.replaceChild(s.mount(this._mountArgs),i.root()),i.unmount()}}}getChildInstanceByIndex(e){var t;return(t=this._childInstances)==null?void 0:t[e]}}class Rc{constructor(e){this._value=e,this._boundUpdateFromValue=null}subscribeOnMount(e){e&&e.parentProvidesUpdates||this._subscribe()}unmount(){this._unsubscribe()}get value(){return this._value}_updateFromValue(e){this.update(this._value,e)}_subscribe(){var e;typeof((e=this._value)==null?void 0:e.on)=="function"&&(this._boundUpdateFromValue=this._updateFromValue.bind(this),this._value.on("change",this._boundUpdateFromValue))}_unsubscribe(){this._boundUpdateFromValue&&(typeof this._value.off=="function"&&this._value.off("change",this._boundUpdateFromValue),this._boundUpdateFromValue=null)}}function Og(n){for(const e of Object.values(n))if(typeof e=="function")return!0;return!1}class E extends Rc{constructor(){super(...arguments),this._eventListeners=void 0,this._bindings=void 0,this._root=void 0,this._subViews=void 0}_attach(){if(this._eventListeners)for(let{node:e,name:t,fn:s,useCapture:i}of this._eventListeners)e.addEventListener(t,s,i)}_detach(){if(this._eventListeners)for(let{node:e,name:t,fn:s,useCapture:i}of this._eventListeners)e.removeEventListener(t,s,i)}mount(e){const t=new Tc(this);try{this._root=this.render(t,this._value)}finally{t.close()}return this.subscribeOnMount(e),this._attach(),this._root}unmount(){if(this._detach(),super.unmount(),this._subViews)for(const e of this._subViews)e.unmount()}root(){return this._root}update(e,t){if(this._value=e,this._bindings)for(const s of this._bindings)s()}_addEventListener(e,t,s,i=!1){this._eventListeners||(this._eventListeners=[]),this._eventListeners.push({node:e,name:t,fn:s,useCapture:i})}_addBinding(e){this._bindings||(this._bindings=[]),this._bindings.push(e)}addSubView(e){this._subViews||(this._subViews=[]),this._subViews.push(e)}removeSubView(e){if(!this._subViews)return;const t=this._subViews.indexOf(e);t!==-1&&this._subViews.splice(t,1)}updateSubViews(e,t){if(this._subViews)for(const s of this._subViews)s.update(e,t)}}class Tc{constructor(e){this._closed=!1,this._templateView=e}close(){this._closed=!0}_addBinding(e){this._closed&&console.trace("Adding a binding after render will likely cause memory leaks"),this._templateView._addBinding(e)}get _value(){return this._templateView.value}addEventListener(e,t,s,i=!1){this._templateView._addEventListener(e,t,s,i)}_addAttributeBinding(e,t,s){let i;const r=()=>{const o=s(this._value);i!==o&&(i=o,ei(e,t,o))};this._addBinding(r),r()}_addClassNamesBinding(e,t){this._addAttributeBinding(e,"className",s=>ri(t,s))}_addTextBinding(e){const t=e(this._value)+"",s=Ft(t);let i=t;const r=()=>{const o=e(this._value)+"";i!==o&&(i=o,s.textContent=o)};return this._addBinding(r),s}_isEventHandler(e,t){return e.startsWith("on")&&e.length>2&&typeof t=="function"}_setNodeAttributes(e,t){for(let[s,i]of Object.entries(t))if(typeof i=="object"){if(s!=="className"||i===null)continue;Og(i)?this._addClassNamesBinding(e,i):ei(e,s,ri(i,this._value))}else if(this._isEventHandler(s,i)){const r=s.substr(2,1).toLowerCase()+s.substr(3),o=i;this._templateView._addEventListener(e,r,o)}else typeof i=="function"?this._addAttributeBinding(e,s,i):ei(e,s,i)}_setNodeChildren(e,t){Array.isArray(t)||(t=[t]);for(let s of t)typeof s=="function"?s=this._addTextBinding(s):typeof s=="string"&&(s=Ft(s)),e.appendChild(s)}_addReplaceNodeBinding(e,t){let s=e(this._value),i=t(null);const r=()=>{const o=e(this._value);if(s!==o){s=o;const c=t(i);i.parentNode&&i.parentNode.replaceChild(c,i),i=c}};return this._addBinding(r),i}el(e,t,s){return this.elNS(Ln,e,t,s)}elNS(e,t,s,i){let r;s&&(Mc(s)?i=s:r=s);const o=document.createElementNS(e,t);return r&&this._setNodeAttributes(o,r),i&&this._setNodeChildren(o,i),o}view(e,t){return this._templateView.addSubView(e),Bi(e,t)}mapView(e,t){return this._addReplaceNodeBinding(e,s=>{if(s&&s.nodeType!==Node.COMMENT_NODE){const r=this._templateView._subViews;if(r){const o=r.findIndex(c=>c.root()===s);if(o!==-1){const[c]=r.splice(o,1);c.unmount()}}}const i=t(e(this._value));return i?this.view(i):document.createComment("node binding placeholder")})}map(e,t){return this.mapView(e,s=>new $i(this._value,(i,r)=>{const o=t(s,i,r);return o||document.createComment("map placeholder")}))}ifView(e,t){return this.mapView(s=>!!e(s),s=>s?t(this._value):null)}if(e,t){return this.ifView(e,s=>new $i(s,t))}mapSideEffect(e,t){let s=e(this._value);const i=()=>{const r=e(this._value);s!==r&&(t(r,s,this._value),s=r)};this._addBinding(i),t(s,void 0,this._value)}}for(const[n,e]of Object.entries(Ec))for(const t of e)Tc.prototype[t]=function(s,i){return this.elNS(n,t,s,i)};class $i extends E{constructor(e,t){super(e),this._render=t}render(e,t){return this._render(e,t)}}function Ss(n,e,t=void 0){const s=!!n.avatarUrl(e);let i=ri({avatar:!0,[`size-${e}`]:!0,[`usercolor${n.avatarColorNumber}`]:!s});t&&(i+=` ${t}`);const r=s?Ac(n,e):Ft(n.avatarLetter),o=H.div({className:i,title:n.avatarTitle,"data-testid":"avatar"},[r]);return s&&(ei(o,"data-avatar-letter",n.avatarLetter),ei(o,"data-avatar-color",n.avatarColorNumber)),o}function Ac(n,e){const t=e.toString();return H.img({src:n.avatarUrl(e),width:t,height:t,title:n.avatarTitle})}function Pg(n){const e=n.target,t=e.parentElement;return e.tagName==="IMG"&&t.classList.contains("avatar")}function $o(n){if(!Pg(n))return;const e=n.target.parentElement,t=e.getAttribute("data-avatar-color");e.classList.add(`usercolor${t}`);const s=e.getAttribute("data-avatar-letter");e.textContent=s}class wt extends Rc{constructor(e,t){super(e),this._root=null,this._avatarUrl=null,this._avatarTitle=null,this._avatarLetter=null,this._size=t}_avatarUrlChanged(){return this.value.avatarUrl(this._size)!==this._avatarUrl?(this._avatarUrl=this.value.avatarUrl(this._size),!0):!1}_avatarTitleChanged(){return this.value.avatarTitle!==this._avatarTitle?(this._avatarTitle=this.value.avatarTitle,!0):!1}_avatarLetterChanged(){return this.value.avatarLetter!==this._avatarLetter?(this._avatarLetter=this.value.avatarLetter,!0):!1}mount(e){return this._avatarUrlChanged(),this._avatarLetterChanged(),this._avatarTitleChanged(),this._root=Ss(this.value,this._size),this.subscribeOnMount(e),this._root}root(){return this._root}update(e){if(this._avatarUrlChanged()){const s=`usercolor${e.avatarColorNumber}`;e.avatarUrl(this._size)?(this._root.replaceChild(Ac(e,this._size),this._root.firstChild),this._root.classList.remove(s)):(this._root.textContent=e.avatarLetter,this._root.classList.add(s))}const t=!!e.avatarUrl(this._size);if(this._avatarTitleChanged()&&t){const s=this._root.firstChild;s.tagName==="IMG"&&s.setAttribute("title",e.avatarTitle)}this._avatarLetterChanged()&&!t&&(this._root.textContent=e.avatarLetter)}}let Ii;function ye(n,e=void 0){Ii===void 0&&(Ii=document.querySelector(".hydrogen"));const t=Object.assign({spinner:!0},e);return Ii!=null&&Ii.classList.contains("legacy")?n.div({className:t},[n.div(),n.div(),n.div(),n.div()]):n.svg({className:t,viewBox:"0 0 100 100"},n.circle({cx:"50%",cy:"50%",r:"45%",pathLength:"100"}))}class Fg extends E{render(e,t){const s={active:i=>i.isOpen,hidden:i=>i.hidden};return e.li({className:s},[e.a({href:t.url},[e.view(new wt(t,32),{parentProvidesUpdates:!0}),e.div({className:"description"},[e.div({className:{name:!0,unread:i=>i.isUnread}},i=>i.name),e.map(i=>i.busy,i=>i?ye(e):e.div({className:{badge:!0,highlighted:r=>r.isHighlighted,hidden:r=>!r.badgeCount}},r=>r.badgeCount))])])])}update(e,t){super.update(e),this.updateSubViews(e,t)}}class ue extends E{static option(e,t){return new Lg(e,t)}constructor(e){super(),this._options=e}render(e){return e.ul({className:"menu",role:"menu"},this._options.map(t=>t.toDOM(e)))}}class Lg{constructor(e,t){this.label=e,this.callback=t,this.icon=null,this.destructive=!1}setIcon(e){return this.icon=e,this}setDestructive(){return this.destructive=!0,this}toDOM(e){const t={destructive:this.destructive};return this.icon&&(t.icon=!0,t[this.icon]=!0),e.li({className:t},e.button({className:"menu-item",onClick:this.callback},this.label))}}class Dr{constructor(e,t=null){this._view=e,this._target=null,this._arrangement=null,this._scroller=null,this._fakeRoot=null,this._trackingTemplateView=null,this._closeCallback=t}_getPopupContainer(){const e=this._target.closest(".hydrogen");let t=e.querySelector(".popupContainer");return t||(t=H.div({className:"popupContainer"}),e.appendChild(t)),t}trackInTemplateView(e){this._trackingTemplateView=e,this._trackingTemplateView.addSubView(this)}showRelativeTo(e,t=0){this._target=e,this._verticalPadding=t,this._scroller=Kg(this._target),this._view.mount(),this._getPopupContainer().appendChild(this._popup),this._position(),this._scroller&&document.body.addEventListener("scroll",this,!0),setTimeout(()=>{document.body.addEventListener("click",this,!1)},10)}get isOpen(){return!!this._view}close(){this._view&&(this._view.unmount(),this._trackingTemplateView.removeSubView(this),this._scroller&&document.body.removeEventListener("scroll",this,!0),document.body.removeEventListener("click",this,!1),this._popup.remove(),this._view=null,this._closeCallback&&this._closeCallback())}get _popup(){return this._view.root()}handleEvent(e){e.type==="scroll"?this._position()||this.close():e.type==="click"&&this._onClick(e)}_onClick(){this.close()}_position(){const e=this._target.getBoundingClientRect(),t=this._popup.clientWidth,s=this._popup.clientHeight,i=(this._scroller?this._scroller:document.documentElement).getBoundingClientRect();if(e.top>i.bottom||e.left>i.right||e.bottom=e.bottom+s)this._popup.style.top=`${e.bottom+this._verticalPadding}px`;else if(i.top<=e.top-s)this._popup.style.top=`${e.top-s-this._verticalPadding}px`;else return!1;if(i.right>=e.right+t)this._popup.style.left=`${e.left}px`;else if(i.left<=e.left-t)this._popup.style.left=`${e.right-t}px`;else return!1;return!0}root(){return this._fakeRoot}mount(){return this._fakeRoot=document.createComment("popup"),this._fakeRoot}unmount(){this.close()}update(){}}function Kg(n){let e=n;do if(e=e.parentElement,e.scrollHeight>e.clientHeight){const s=window.getComputedStyle(e).getPropertyValue("overflow-y");if(s==="auto"||s==="scroll")return e}while(e!==document.body)}class Bg extends E{render(e,t){const s=()=>{i.value="",i.blur(),r.blur(),t.clear()},i=e.input({type:"text",placeholder:t==null?void 0:t.label,"aria-label":t==null?void 0:t.label,autocomplete:t==null?void 0:t.autocomplete,enterkeyhint:"search",name:t==null?void 0:t.name,onInput:o=>t.set(o.target.value),onKeydown:o=>{(o.key==="Escape"||o.key==="Esc")&&s()},onFocus:()=>i.select()}),r=e.button({onClick:s,title:t.i18n`Clear`,"aria-label":t.i18n`Clear`});return e.div({className:"FilterField"},[i,r])}}class $g extends E{constructor(e){super(e),this._createMenuPopup=null}render(e,t){const s=o=>o.gridEnabled?o.i18n`Show single room`:o.i18n`Enable grid layout`,i=e.view(new os({className:"RoomList",list:t.tileViewModels},o=>new Fg(o))),r=e.div({className:"utilities"},[e.a({className:"button-utility close-session",href:t.closeUrl,"aria-label":t.i18n`Back to account list`,title:t.i18n`Back to account list`}),e.view(new Bg({i18n:t.i18n,label:t.i18n`Filter rooms…`,name:"room-filter",autocomplete:!0,set:o=>{t.setFilter(o)&&(i.scrollTop=0)},clear:()=>t.clearFilter()})),e.button({onClick:()=>t.toggleGrid(),className:{"button-utility":!0,grid:!0,on:o=>o.gridEnabled},title:s,"aria-label":s}),e.a({className:"button-utility settings",href:t.settingsUrl,"aria-label":t.i18n`Settings`,title:t.i18n`Settings`}),e.button({className:"button-utility create","aria-label":t.i18n`Create room`,onClick:o=>this._toggleCreateMenu(o)})]);return e.div({className:"LeftPanel"},[r,i])}_toggleCreateMenu(e){if(this._createMenuPopup&&this._createMenuPopup.isOpen)this._createMenuPopup.close();else{const t=this.value,s=[];s.push(ue.option(t.i18n`Create Room`,()=>t.showCreateRoomView())),s.push(ue.option(t.i18n`Join Room`,()=>t.showJoinRoomView())),this._createMenuPopup=new Dr(new ue(s)),this._createMenuPopup.trackInTemplateView(this),this._createMenuPopup.showRelativeTo(e.target,10)}}}function jo(n){return n.offsetTop+n.clientHeight}function qo(n,e,t=n.children.length-1){for(var s=t;s>=0;s--)if(n.children[s].offsetTop{this.restoreScrollPosition()}),this.tilesView=new qg(t.tiles,()=>this.restoreScrollPosition(),this.viewClassForTile);const s=e.div({className:"Timeline"},[e.div({className:"Timeline_scroller bottom-aligned-scroll",onScroll:()=>this.onScroll()},e.view(this.tilesView)),e.button({className:{Timeline_jumpDown:!0,hidden:i=>!i.showJumpDown},title:"Jump down",onClick:()=>this.jumpDown()})]);return typeof ResizeObserver=="function"&&(this.resizeObserver=new ResizeObserver(()=>{this.restoreScrollPosition()}),this.resizeObserver.observe(s)),s}get scrollNode(){return this.root().firstElementChild}get tilesNode(){return this.tilesView.root()}jumpDown(){const{scrollNode:e}=this;this.stickToBottom=!0,e.scrollTop=e.scrollHeight}unmount(){super.unmount(),this.resizeObserver&&(this.resizeObserver.unobserve(this.root()),this.resizeObserver=void 0)}restoreScrollPosition(){const{scrollNode:e,tilesNode:t}=this,s=e.clientHeight-t.clientHeight;if(s>0){t.style.setProperty("margin-top",`${s}px`);const i=this.value.tiles.length;this.updateVisibleRange(0,i-1)}else if(t.style.removeProperty("margin-top"),this.stickToBottom)e.scrollTop=e.scrollHeight;else if(this.anchoredNode){const i=jo(this.anchoredNode);if(i!==this.anchoredBottom){const r=i-this.anchoredBottom;typeof e.scrollBy=="function"?e.scrollBy(0,r):e.scrollTop=e.scrollTop+r,this.anchoredBottom=i}}}onScroll(){const{scrollNode:e,tilesNode:t}=this,{scrollHeight:s,scrollTop:i,clientHeight:r}=e;let o;if(this.stickToBottom=Math.abs(s-(i+r))<1,this.stickToBottom)o=this.value.tiles.length-1;else{const l=i+r,h=qo(t,l);this.anchoredNode=t.childNodes[h],this.anchoredBottom=jo(this.anchoredNode),o=h}let c=qo(t,i,o);this.updateVisibleRange(c,o)}updateVisibleRange(e,t){const s=this.tilesView.getChildInstanceByIndex(e),i=this.tilesView.getChildInstanceByIndex(t);this.value.setVisibleTileRange(s==null?void 0:s.value,i==null?void 0:i.value)}}class qg extends os{constructor(e,t,s){super({list:e,onItemClick:(i,r)=>i.onClick(r)},i=>{const r=s(i);return new r(i,s)}),this.viewClassForTile=s,this.onChanged=t}onReset(){super.onReset(),this.onChanged()}onUpdate(e,t,s){if(s==="shape"){const i=this.viewClassForTile(t),r=this.getChildInstanceByIndex(e);if(!i||!(r instanceof i)){super.recreateItem(e,t);return}}super.onUpdate(e,t,s),this.onChanged()}onAdd(e,t){super.onAdd(e,t),this.onChanged()}onRemove(e,t){super.onRemove(e,t),this.onChanged()}onMove(e,t,s){super.onMove(e,t,s),this.onChanged()}}class Hg extends E{render(e,t){return e.div({className:"TimelineLoadingView"},[ye(e),e.div(t.isEncrypted?t.i18n`Loading encrypted messages…`:t.i18n`Loading messages…`)])}}class Wg extends E{constructor(e,t){super(e),this._viewClassForTile=t,this._input=null,this._attachmentPopup=null,this._focusInput=null,this._rafResizeHandle=void 0}render(e,t){this._input=e.textarea({onKeydown:r=>this._onKeyDown(r),onInput:()=>{t.setInput(this._input.value),this._input.value?this._adjustHeight():this._clearHeight()},placeholder:r=>r.isEncrypted?"Send an encrypted message\u2026":"Send a message\u2026",rows:"1"}),this._focusInput=()=>this._input.focus(),this.value.on("focus",this._focusInput);const s=e.map(r=>r.replyViewModel,(r,o)=>{const c=r&&this._viewClassForTile(r);return c?o.div({className:"MessageComposer_replyPreview"},[o.span({className:"replying"},"Replying"),o.button({className:"cancel",onClick:()=>this._clearReplyingTo()},"Close"),o.view(new c(r,this._viewClassForTile,{interactive:!1},"div"))]):null}),i=e.div({className:"MessageComposer_input"},[this._input,e.button({className:"sendFile",title:t.i18n`Pick attachment`,onClick:r=>this._toggleAttachmentMenu(r)},t.i18n`Send file`),e.button({className:"send",title:t.i18n`Send`,onClick:()=>this._trySend()},t.i18n`Send`)]);return e.div({className:{MessageComposer:!0,MessageComposer_canSend:r=>r.canSend}},[s,i])}unmount(){this._focusInput&&this.value.off("focus",this._focusInput),super.unmount()}_clearReplyingTo(){this.value.clearReplyingTo()}async _trySend(){this._input.focus();const{value:e}=this._input,t=()=>{this._input.value=e,this._adjustHeight()};this._input.value="",this._clearHeight();try{await this.value.sendMessage(e)||t()}catch(s){t(),console.error(s)}}_onKeyDown(e){e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),this._trySend())}_toggleAttachmentMenu(e){if(this._attachmentPopup&&this._attachmentPopup.isOpen)this._attachmentPopup.close();else{const t=this.value;this._attachmentPopup=new Dr(new ue([ue.option(t.i18n`Send video`,()=>t.sendVideo()).setIcon("video"),ue.option(t.i18n`Send picture`,()=>t.sendPicture()).setIcon("picture"),ue.option(t.i18n`Send file`,()=>t.sendFile()).setIcon("file")])),this._attachmentPopup.trackInTemplateView(this),this._attachmentPopup.showRelativeTo(e.target,12)}}_adjustHeight(){this._rafResizeHandle||(this._rafResizeHandle=window.requestAnimationFrame(()=>{const e=this._input.scrollHeight;this._input.style.height=`${e}px`,this._rafResizeHandle=void 0}))}_clearHeight(){this._input.style.removeProperty("height")}}class zg extends E{render(e){return e.div({className:"DisabledComposerView"},e.h3(t=>t.description))}}class Vs extends E{constructor(e,t={inline:!1}){super(e),this.options=t}render(e,t){const s=e.button({className:"ErrorView_submit",onClick:Kn(async r=>{r.stopPropagation(),await t.submitLogs()?alert("Logs submitted!"):alert("Could not submit logs")})},"Submit logs"),i=e.button({className:"ErrorView_close",onClick:r=>{r.stopPropagation(),t.close()},title:"Dismiss error"});return e.div({className:{ErrorView:!0,ErrorView_inline:this.options.inline,ErrorView_block:!this.options.inline}},[e.p({className:"ErrorView_message"},t.message),s,i])}}class Gg extends E{render(e,t){const s=e.view(new os({className:"CallView_members",list:t.memberViewModels},i=>new Yg(i)));return this.bindMembersCssClasses(e,s),e.div({class:"CallView"},[s,e.div({class:"CallView_buttons"},[e.button({className:{CallView_mutedMicrophone:i=>i.isMicrophoneMuted,CallView_unmutedMicrophone:i=>!i.isMicrophoneMuted},onClick:Hr(()=>t.toggleMicrophone())}),e.button({className:{CallView_mutedCamera:i=>i.isCameraMuted,CallView_unmutedCamera:i=>!i.isCameraMuted},onClick:Hr(()=>t.toggleCamera())}),e.button({className:"CallView_hangup",onClick:Hr(()=>t.hangup())})]),e.if(i=>!!i.errorViewModel,i=>i.div({className:"CallView_error"},i.view(new Vs(t.errorViewModel))))])}bindMembersCssClasses(e,t){if(e.mapSideEffect(s=>s.memberCount,s=>{t.classList.forEach((i,r,o)=>{i.startsWith("size")&&o.remove(i)}),t.classList.add(`size${s}`)}),typeof ResizeObserver=="function"){const s=(i,r)=>{r?t.classList.add(i):t.classList.remove(i)};this.resizeObserver=new ResizeObserver(()=>{const i=t.clientWidth/t.clientHeight,r=i<.5,o=!r&&i<1.8,c=!r&&!o;s("tall",r),s("square",o),s("wide",c)}),this.resizeObserver.observe(t)}}unmount(){this.resizeObserver&&(this.resizeObserver.unobserve(this.root().querySelector(".CallView_members")),this.resizeObserver=void 0),super.unmount()}}class Yg extends E{render(e,t){const s=e.video({autoplay:!0,disablePictureInPicture:!0,className:{hidden:i=>i.isCameraMuted}});return e.mapSideEffect(i=>i.stream,i=>{s.srcObject=i}),e.div({className:"StreamView"},[s,e.div({className:{StreamView_avatar:!0,hidden:i=>!i.isCameraMuted}},e.view(new wt(t,96),{parentProvidesUpdates:!0})),e.div({className:{StreamView_muteStatus:!0,hidden:i=>!i.isCameraMuted&&!i.isMicrophoneMuted,microphoneMuted:i=>i.isMicrophoneMuted&&!i.isCameraMuted,cameraMuted:i=>i.isCameraMuted}}),e.if(i=>!!i.errorViewModel,i=>i.div({className:"StreamView_error"},i.view(new Vs(t.errorViewModel))))])}update(e,t){super.update(e),this.updateSubViews(e,t)}}function Hr(n){return async e=>{var t,s;(t=e.target)==null||t.setAttribute("disabled","disabled"),await n(e),(s=e.target)==null||s.removeAttribute("disabled")}}class xc extends E{constructor(e,t){super(e),this._viewClassForTile=t,this._optionsPopup=null}render(e,t){return e.main({className:"RoomView middle"},[e.div({className:"RoomHeader middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Close room`}),e.view(new wt(t,32)),e.div({className:"room-description"},[e.h2(s=>s.name)]),e.button({className:"button-utility room-options","aria-label":t.i18n`Room options`,onClick:s=>this._toggleOptionsMenu(s)})]),e.div({className:"RoomView_body"},[e.if(s=>s.errorViewModel,s=>s.div({className:"RoomView_error"},s.view(new Vs(t.errorViewModel)))),e.mapView(s=>s.callViewModel,s=>s?new Gg(s):null),e.mapView(s=>s.timelineViewModel,s=>s?new jg(s,this._viewClassForTile):new Hg(t)),e.mapView(s=>s.composerViewModel,s=>{switch(s==null?void 0:s.kind){case"composer":return new Wg(t.composerViewModel,this._viewClassForTile);case"disabled":return new zg(t.composerViewModel)}})])])}_toggleOptionsMenu(e){if(this._optionsPopup&&this._optionsPopup.isOpen)this._optionsPopup.close();else{const t=this.value,s=[];if(s.push(ue.option(t.i18n`Room details`,()=>t.openDetailsPanel())),t.features.calls&&s.push(ue.option(t.i18n`Start call`,()=>t.startCall())),t.canLeave&&s.push(ue.option(t.i18n`Leave room`,()=>this._confirmToLeaveRoom()).setDestructive()),t.canForget&&s.push(ue.option(t.i18n`Forget room`,()=>t.forgetRoom()).setDestructive()),t.canRejoin&&s.push(ue.option(t.i18n`Rejoin room`,()=>t.rejoinRoom())),!s.length)return;this._optionsPopup=new Dr(new ue(s)),this._optionsPopup.trackInTemplateView(this),this._optionsPopup.showRelativeTo(e.target,10)}}_confirmToLeaveRoom(){confirm(this.value.i18n`Are you sure you want to leave "${this.value.name}"?`)&&this.value.leaveRoom()}}class Jg extends E{render(e,t){return e.main({className:"UnknownRoomView middle"},[e.div({className:"UnknownRoomView_header middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Cancel room join`}),e.h2("Join room")]),e.div({className:"UnknownRoomView_body centered-column"},[e.div({className:"UnknownRoomView_container"},[e.h2([t.i18n`You are currently not in ${t.roomIdOrAlias}.`,e.br(),t.i18n`Want to join it?`]),e.button({className:"button-action primary",onClick:()=>t.join(),disabled:s=>s.busy},t.i18n`Join room`),e.if(s=>s.error,s=>s.p({className:"error"},t.error))])])])}}class ni{constructor(e,t=void 0){typeof e=="function"&&!t&&(t=e,e=null),this._root=t?t(H,e):this.render(H,e)}mount(){return this._root}root(){return this._root}unmount(){}update(){}}class Vc extends ni{constructor(e="Loading"){super(e,(t,s)=>t.div({className:"LoadingView"},[ye(t),s]))}}class Nc extends E{render(e,t){return e.main({className:"RoomView middle"},[e.div({className:"RoomHeader middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Close room`}),e.view(new wt(t,32)),e.div({className:"room-description"},[e.h2(s=>s.name)])]),e.div({className:"RoomView_body"},[e.mapView(s=>s.error,s=>s?new Qg(t):new Vc(t.i18n`Setting up the room…`))])])}}class Qg extends E{render(e,t){return e.div({className:"RoomBeingCreated_error centered-column"},[e.h3(t.i18n`Could not create the room, something went wrong:`),e.div({className:"RoomView_error form-group"},t.error),e.div({className:"button-row"},e.button({className:"button-action primary destructive",onClick:()=>t.cancel()},t.i18n`Cancel`))])}}class Dc extends E{render(e,t){var r;let s=[];t.isDirectMessage&&s.push(Ss(t,128,"InviteView_dmAvatar"));let i;return t.isDirectMessage?i=[e.strong(t.name),` (${(r=t.inviter)==null?void 0:r.id}) wants to chat with you.`]:t.inviter?i=[Ss(t.inviter,24),e.strong(t.inviter.name),` (${t.inviter.id}) invited you.`]:i="You were invited to join.",s.push(e.p({className:"InviteView_inviter"},i)),t.isDirectMessage||s.push(e.div({className:"InviteView_roomProfile"},[Ss(t,64,"InviteView_roomAvatar"),e.h3(t.name),e.p({className:"InviteView_roomDescription"},t.roomDescription)])),e.main({className:"InviteView middle"},[e.div({className:"RoomHeader middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Close invite`}),Ss(t,32),e.div({className:"room-description"},[e.h2(o=>o.name)])]),e.if(o=>o.error,o=>o.div({className:"RoomView_error"},c=>c.error)),e.div({className:"InviteView_body"},[e.div({className:"InviteView_invite"},[...s,e.div({className:"InviteView_buttonRow"},e.button({className:"button-action primary",disabled:o=>o.busy,onClick:()=>t.accept()},t.i18n`Accept`)),e.div({className:"InviteView_buttonRow"},e.button({className:"button-action primary destructive",disabled:o=>o.busy,onClick:()=>t.reject()},t.i18n`Reject`))])])])}}class Xg extends E{render(e,t){const s=e.a({href:t.closeUrl,title:t.i18n`Close`,className:"close"}),i=e.div({role:"img","aria-label":l=>l.name,title:l=>l.name,className:{picture:!0,hidden:l=>!l.imageUrl},style:l=>`background-image: url('${l.imageUrl}'); max-width: ${l.imageWidth}px; max-height: ${l.imageHeight}px;`}),r=e.div({className:{loading:!0,hidden:l=>!!l.imageUrl}},[ye(e),e.div(t.i18n`Loading image…`)]),o=e.div({className:"details"},[e.strong(l=>l.name),e.br(),"uploaded by ",e.strong(l=>l.sender),l=>` at ${l.time} on ${l.date}.`]),c=e.div({role:"dialog",className:"lightbox",onClick:l=>this.clickToClose(l),onKeydown:l=>this.closeOnEscKey(l)},[i,r,o,s]);return Zg(e,c),c}clickToClose(e){e.target===this.root()&&this.value.close()}closeOnEscKey(e){(e.key==="Escape"||e.key==="Esc")&&this.value.close()}}function Zg(n,e){const t=ef(e),s=t[0],i=t[t.length-1];n.addEventListener(e,"keydown",r=>{r.key==="Tab"&&(r.shiftKey?document.activeElement===s&&(i.focus(),r.preventDefault()):document.activeElement===i&&(s.focus(),r.preventDefault()))},!0),Promise.resolve().then(()=>{s.focus()})}function ef(n){return n.querySelectorAll("a[href], button, textarea, input, select")}class tf extends E{render(e,t){return e.div({className:{SessionStatusView:!0,hidden:s=>!s.isShown}},[ye(e,{hidden:s=>!s.isWaiting}),e.p(s=>s.statusLabel),e.if(s=>s.isConnectNowShown,s=>s.button({className:"link",onClick:()=>t.connectNow()},"Retry now")),e.if(s=>s.isSecretStorageShown,s=>s.a({href:t.setupKeyBackupUrl},"Go to settings")),e.if(s=>s.canDismiss,s=>s.div({className:"end"},s.button({className:"dismiss",onClick:()=>t.dismiss()})))])}}class sf extends E{constructor(e,t){super(e),this._viewClassForTile=t}render(e,t){const s=[];for(let i=0;it.focusTile(i),onFocusin:()=>t.focusTile(i),className:{container:!0,[`tile${i}`]:!0,focused:r=>r.focusIndex===i}},e.mapView(r=>r.roomViewModelAt(i),r=>r?r.kind==="roomBeingCreated"?new Nc(r):r.kind==="invite"?new Dc(r):new xc(r,this._viewClassForTile):new ni(o=>o.div({className:"room-placeholder"},[o.h2({className:"focused"},t.i18n`Select a room on the left`),o.h2({className:"unfocused"},t.i18n`Click to select this tile`)])))));return s.push(e.div({className:i=>`focus-ring tile${i.focusIndex}`})),e.div({className:"RoomGridView middle layout3x2"},s)}}class Uc extends E{render(e,t){return e.div([e.map(s=>s.status,(s,i,r)=>{switch(s){case st.Enabled:return rf(i,r);case st.NewVersionAvailable:return nf(i,r);case st.SetupWithPassphrase:return af(i,r);case st.SetupWithRecoveryKey:return of(i,r);case st.Pending:return i.p(r.i18n`Waiting to go online…`)}}),e.map(s=>s.backupWriteStatus,(s,i,r)=>{switch(s){case wr.Writing:{const o=i.progress({min:0+"",max:100+"",value:c=>c.backupPercentage});return i.div(["Backup in progress ",o," ",c=>c.backupInProgressLabel])}case wr.Stopped:{let o;return r.backupError?o=`Backup has stopped because of an error: ${r.backupError}`:o="Backup has stopped",i.p([o," ",i.button({onClick:()=>r.startBackup()},"Backup now")])}case wr.Done:return i.p("All keys are backed up.");default:return}}),e.if(s=>s.isMasterKeyTrusted,s=>s.p("Cross-signing master key found and trusted.")),e.if(s=>s.canSignOwnDevice,s=>s.div([s.button({onClick:Kn(async()=>{t.navigateToVerification()})},"Verify by emoji")]))])}}function rf(n,e){const t=[n.p([e.i18n`Key backup is enabled, using backup version ${e.backupVersion}. `,n.button({onClick:()=>e.disable()},e.i18n`Disable`)])];return e.dehydratedDeviceId&&t.push(n.p(e.i18n`A dehydrated device id was set up with id ${e.dehydratedDeviceId} which you can use during your next login with your secret storage key.`)),n.div(t)}function nf(n,e){const t=[n.p([e.i18n`A new backup version has been created from another device. Disable key backup and enable it again with the new key.`,n.button({onClick:()=>e.disable()},e.i18n`Disable`)])];return n.div(t)}function of(n,e){const t=n.button({className:"link",onClick:()=>e.showPhraseSetup()},e.i18n`use a security phrase`);return n.div([n.p(e.i18n`Enter your secret storage security key below to ${e.purpose}, which will enable you to decrypt messages received before you logged into this session. The security key is a code of 12 groups of 4 characters separated by a space that Element created for you when setting up security.`),Pc(n),Oc(n,e,e.i18n`Security key`,(s,i)=>e.enterSecurityKey(s,i)),n.p([e.i18n`Alternatively, you can `,t,e.i18n` if you have one.`])])}function af(n,e){const t=n.button({className:"link",onClick:()=>e.showKeySetup()},e.i18n`use your security key`);return n.div([n.p(e.i18n`Enter your secret storage security phrase below to ${e.purpose}, which will enable you to decrypt messages received before you logged into this session. The security phrase is a freeform secret phrase you optionally chose when setting up security in Element. It is different from your password to login, unless you chose to set them to the same value.`),Pc(n),Oc(n,e,e.i18n`Security phrase`,(s,i)=>e.enterSecurityPhrase(s,i)),n.p([e.i18n`You can also `,t,e.i18n`.`])])}function Oc(n,e,t,s){let i;const r=()=>s(o.value,(i==null?void 0:i.checked)||!1),o=n.input({type:"password",disabled:l=>l.isBusy,placeholder:t}),c=[n.p([o,n.button({disabled:l=>l.isBusy,onClick:r},e.decryptAction)])];if(e.offerDehydratedDeviceSetup){i=n.input({type:"checkbox",id:"enable-dehydrated-device"});const l=n.a({href:"https://github.com/uhoreg/matrix-doc/blob/dehydration/proposals/2697-device-dehydration.md",target:"_blank",rel:"noopener"},"more info");c.push(n.p([i,n.label({for:i.id},[e.i18n`Back up my device as well (`,l,")"])]))}return n.div({className:"row"},[n.div({className:"label"},t),n.div({className:"content"},c)])}function Pc(n){return n.if(e=>e.error!==void 0,(e,t)=>e.div([e.p({className:"error"},s=>s.i18n`Could not enable key backup: ${s.error}.`),e.p(t.i18n`Try double checking that you did not mix up your security key, security phrase and login password as explained above.`)]))}class cf extends E{render(e,t){return e.div({className:"FeaturesView"},[e.p("Enable experimental features here that are still in development. These are not yet ready for primetime, so expect bugs."),e.ul(t.featureViewModels.map(s=>e.li(e.view(new lf(s)))))])}}class lf extends E{render(e,t){let s=`feature_${t.id}`;return e.div({className:"FeatureView"},[e.input({type:"checkbox",id:s,checked:i=>i.enabled,onChange:i=>t.enableFeature(i.target.checked)}),e.div({class:"FeatureView_container"},[e.h4(e.label({for:s},t.name)),e.p(t.description)])])}}class hf extends E{render(e,t){let s=t.version;t.showUpdateButton&&(s=e.span([t.version,e.button({onClick:()=>t.checkForUpdate()},t.i18n`Check for updates`)]));const i=(c,l,h,a="")=>c.div({className:`row ${a}`},[c.div({className:"label"},l),c.div({className:"content"},h)]),r=[];r.push(e.h3("Session"),i(e,t.i18n`User ID`,t.userId),i(e,t.i18n`Session ID`,t.deviceId,"code"),i(e,t.i18n`Session key`,t.fingerprintKey,"code"),i(e,"",e.button({onClick:()=>t.logout(),disabled:c=>c.isLoggingOut},t.i18n`Log out`))),r.push(e.h3("Key backup & security"),e.view(new Uc(t.keyBackupViewModel))),r.push(e.h3("Notifications"),e.map(c=>c.pushNotifications.supported,(c,l)=>{if(c===null)return l.p(t.i18n`Loading…`);if(c){const h=u=>u.pushNotifications.enabled?u.i18n`Push notifications are enabled`:u.i18n`Push notifications are disabled`,a=u=>u.pushNotifications.enabled?u.i18n`Disable`:u.i18n`Enable`;return i(l,h,l.button({onClick:()=>t.togglePushNotifications(),disabled:u=>u.pushNotifications.updating},a))}else return l.p(t.i18n`Push notifications are not supported on this browser`)}),e.if(c=>c.pushNotifications.supported&&c.pushNotifications.enabled,c=>c.div([c.p(["If you think push notifications are not being delivered, ",c.button({className:"link",onClick:()=>t.checkPushEnabledOnServer()},"check")," if they got disabled on the server"]),c.map(l=>l.pushNotifications.enabledOnServer,(l,h)=>{if(l===!0)return h.p("Push notifications are still enabled on the server, so everything should be working. Sometimes notifications can get dropped if they can't be delivered within a given time.");if(l===!1)return h.p("Push notifications have been disabled on the server, likely due to a bug. Please re-enable them by clicking Disable and then Enable again above.")}),c.map(l=>l.pushNotifications.serverError,(l,h)=>{if(l)return h.p("Couldn't not check on server: "+l.message)})]))),r.push(e.h3("Preferences"),i(e,t.i18n`Scale down images when sending`,this._imageCompressionRange(e,t)),e.if(c=>c.activeTheme,(c,l)=>i(c,l.i18n`Use the following theme`,this._themeOptions(c,l))));const o=[];return t.canSendLogsToServer&&o.push(e.button({onClick:Kn(()=>t.sendLogsToServer())},`Submit logs to ${t.logsServer}`)),o.push(e.button({onClick:()=>t.exportLogs()},"Download logs")),r.push(e.h3("Experimental features"),e.view(new cf(t.featuresViewModel))),r.push(e.h3("Application"),i(e,t.i18n`Version`,s),i(e,t.i18n`Storage usage`,c=>`${c.storageUsage} / ${c.storageQuota}`),i(e,t.i18n`Debug logs`,o),e.p({className:{hidden:c=>!c.logsFeedbackMessage}},c=>c.logsFeedbackMessage),e.p(["Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited, the usernames of other users and the names of files you send. They do not contain messages. For more information, review our ",e.a({href:"https://element.io/privacy",target:"_blank",rel:"noopener"},"privacy policy"),"."]),e.p([])),e.main({className:"Settings middle"},[e.div({className:"middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Close settings`}),e.h2("Settings")]),e.div({className:"SettingsBody"},r)])}_imageCompressionRange(e,t){const i=Math.ceil(t.minSentImageSizeLimit/32)*32,r=(Math.floor(t.maxSentImageSizeLimit/32)+1)*32,o=c=>t.setSentImageSizeLimit(parseInt(c.target.value,10));return[e.input({type:"range",step:32,min:i,max:r,value:c=>c.sentImageSizeLimit||r,onInput:o,onChange:o})," ",e.output(c=>c.sentImageSizeLimit?c.i18n`resize to ${c.sentImageSizeLimit}px`:c.i18n`no resizing`)]}_themeOptions(e,t){const{themeName:s,themeVariant:i}=t.activeTheme,r=[];for(const f of Object.keys(t.themeMapping))r.push(e.option({value:f,selected:f===s},f));const o=e.select({onChange:f=>{const v=f.target.value;if(!("id"in t.themeMapping[v])){const M=a.checked?"dark":p.checked?"light":"default";c(M);return}t.changeThemeOption(v)}},r),c=f=>{const v=o.options[o.selectedIndex].value;t.changeThemeOption(v,f)},l=i==="dark",h=i==="light",a=e.input({type:"radio",name:"radio-chooser",value:"dark",id:"dark",checked:l}),u=e.input({type:"radio",name:"radio-chooser",value:"default",id:"default",checked:!(l||h)}),p=e.input({type:"radio",name:"radio-chooser",value:"light",id:"light",checked:h}),g=e.form({className:{hidden:()=>{const f=o.options[o.selectedIndex].value;return"id"in t.themeMapping[f]}},onChange:f=>c(f.target.value)},[u,e.label({for:"default"},"Match system theme"),a,e.label({for:"dark"},"dark"),p,e.label({for:"light"},"light")]);return e.div({className:"theme-chooser"},[o,g])}}class df extends E{render(e,t){return e.main({className:"CreateRoomView middle"},[e.div({className:"CreateRoomView_header middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Cancel room creation`}),e.h2("Create room")]),e.div({className:"CreateRoomView_body centered-column"},[e.form({className:"CreateRoomView_detailsForm form",onChange:s=>this.onFormChange(s),onSubmit:s=>this.onSubmit(s)},[e.div({className:"vertical-layout"},[e.button({type:"button",className:"CreateRoomView_selectAvatar",onClick:()=>t.selectAvatar()},e.mapView(s=>s.hasAvatar,s=>s?new wt(t,64):new ni(void 0,i=>i.div({className:"CreateRoomView_selectAvatarPlaceholder"})))),e.div({className:"stretch form-row text"},[e.label({for:"name"},t.i18n`Room name`),e.input({onInput:s=>t.setName(s.target.value),type:"text",name:"name",id:"name",placeholder:t.i18n`Enter a room name`})])]),e.div({className:"form-row text"},[e.label({for:"topic"},t.i18n`Topic (optional)`),e.textarea({onInput:s=>t.setTopic(s.target.value),name:"topic",id:"topic",placeholder:t.i18n`Topic`})]),e.div({className:"form-group"},[e.div({className:"form-row check"},[e.input({type:"radio",name:"isPublic",id:"isPrivate",value:"false",checked:!t.isPublic}),e.label({for:"isPrivate"},t.i18n`Private room, only upon invitation.`)]),e.div({className:"form-row check"},[e.input({type:"radio",name:"isPublic",id:"isPublic",value:"true",checked:t.isPublic}),e.label({for:"isPublic"},t.i18n`Public room, anyone can join`)])]),e.div({className:{"form-row check":!0,hidden:s=>s.isPublic}},[e.input({type:"checkbox",name:"isEncrypted",id:"isEncrypted",checked:t.isEncrypted}),e.label({for:"isEncrypted"},t.i18n`Enable end-to-end encryption`)]),e.div({className:{"form-row text":!0,hidden:s=>!s.isPublic}},[e.label({for:"roomAlias"},t.i18n`Room alias`),e.input({onInput:s=>t.setRoomAlias(s.target.value),type:"text",name:"roomAlias",id:"roomAlias",placeholder:t.i18n`Room alias (, or # or #:hs.tld`})]),e.div({className:"form-group"},[e.div(e.button({className:"link",type:"button",onClick:()=>t.toggleAdvancedShown()},s=>s.isAdvancedShown?s.i18n`Hide advanced settings`:s.i18n`Show advanced settings`)),e.div({className:{"form-row check":!0,hidden:s=>!s.isAdvancedShown}},[e.input({type:"checkbox",name:"isFederationDisabled",id:"isFederationDisabled",checked:t.isFederationDisabled}),e.label({for:"isFederationDisabled"},[t.i18n`Disable federation`,e.p({className:"form-row-description"},t.i18n`Can't be changed later. This will prevent people on other homeservers from joining the room. This is typically used when only people from your own organisation (if applicable) should be allowed in the room, and is otherwise not needed.`)])])]),e.div({className:"button-row"},[e.button({className:"button-action primary",type:"submit",disabled:s=>!s.canCreate},t.i18n`Create room`)])])])])}onFormChange(e){switch(e.target.name){case"isEncrypted":this.value.setEncrypted(e.target.checked);break;case"isPublic":this.value.setPublic(e.currentTarget.isPublic.value==="true");break;case"isFederationDisabled":this.value.setFederationDisabled(e.target.checked);break}}onSubmit(e){e.preventDefault(),this.value.create()}}class uf extends E{render(e,t){const s=()=>t.isEncrypted?t.i18n`On`:t.i18n`Off`;return e.div({className:"RoomDetailsView"},[e.div({className:"RoomDetailsView_avatar"},[e.view(new wt(t,52)),e.mapView(i=>i.isEncrypted,i=>new mf(i))]),e.div({className:"RoomDetailsView_name"},[e.h2(i=>i.name)]),this._createRoomAliasDisplay(t),e.div({className:"RoomDetailsView_rows"},[this._createRightPanelButtonRow(e,t.i18n`People`,{MemberCount:!0},i=>i.memberCount,()=>t.openPanel("members")),this._createRightPanelRow(e,t.i18n`Encryption`,{EncryptionStatus:!0},s)])])}_createRoomAliasDisplay(e){return e.canonicalAlias?H.div({className:"RoomDetailsView_id"},[e.canonicalAlias]):""}_createRightPanelRow(e,t,s,i){const r=ri(It({RoomDetailsView_label:!0},s));return e.div({className:"RoomDetailsView_row"},[e.div({className:r},[t]),e.div({className:"RoomDetailsView_value"},i)])}_createRightPanelButtonRow(e,t,s,i,r){const o=ri(It({RoomDetailsView_label:!0},s));return e.button({className:"RoomDetailsView_row",onClick:r},[e.div({className:o},[t]),e.div({className:"RoomDetailsView_value"},i)])}}class mf extends E{render(e,t){return e.div({className:"EncryptionIconView"},[e.div({className:t?"EncryptionIconView_encrypted":"EncryptionIconView_unencrypted"})])}}class _f{constructor(e,t){this.start=e,this.end=t}get length(){return this.end-this.start}contains(e){return e.start>=this.start&&e.end<=this.end}containsIndex(e){return e>=this.start&&e(n[n.Before=1]="Before",n[n.Inside=2]="Inside",n[n.After=3]="After",n))(Cs||{});class pf{constructor(e){this.range=e,this.idx=e.start-1}next(){return this.idxthis.range.start?(this.idx-=1,{value:this.idx,done:!1}):{value:void 0,done:!0}}}function ff(n,e){let t=0;for(;t(n[n.Move=0]="Move",n[n.Add=1]="Add",n[n.Remove=2]="Remove",n[n.RemoveAndAdd=3]="RemoveAndAdd",n[n.UpdateRange=4]="UpdateRange",n))(Gs||{});class Di extends _f{constructor(e,t,s,i=t-e){super(e,t),this._totalLength=s,this._viewportItemCount=i}expand(e){if(this.length===0)return this;const t=Math.max(0,this.start-e),s=Math.min(this.totalLength,this.end+e);return new Di(t,s,this.totalLength,this._viewportItemCount)}get totalLength(){return this._totalLength}get viewportItemCount(){return this._viewportItemCount}static fromViewport(e,t,s,i){const r=Math.min(Math.max(0,Math.floor(i/t)),e),o=e-r,c=s!==0?Math.ceil(s/t):0,l=Math.min(c,o);return new Di(r,r+l,e,c)}queryAdd(e,t,s){const i=this.viewportItemCount>this.length?this.end:this.end-1;if(e<=i){const r=this.clampIndex(e,i),o=r===e?t:ur(s[Symbol.iterator](),r);return this.createAddResult(r,o)}else return{type:4,newRange:this.deriveRange(1,0)}}queryRemove(e,t){if(ethis.length)return{type:1,addIdx:e,value:t,newRange:this.deriveRange(1,1)};{const s=this.clampIndex(Number.MAX_SAFE_INTEGER);return{type:3,removeIdx:s,addIdx:e,value:t,newRange:this.deriveRange(1,0)}}}createRemoveResult(e,t){if(this.endrequestAnimationFrame(t)),await new Promise(t=>requestAnimationFrame(t)),!this._list)return;this._subscription=this._list.subscribe(this);const e=this._getVisibleRange();this.renderRange=e.expand(this.overflowItems),this._childInstances=[],this.reRenderFullRange(this.renderRange)}_getVisibleRange(){const{clientHeight:e,scrollTop:t}=this.root();if(e===0)throw new Error("LazyListView height is 0");return Di.fromViewport(this._list.length,this.itemHeight,e,t)}reRenderFullRange(e){Ug(this._listElement);const t=document.createDocumentFragment(),s=this._list[Symbol.iterator]();this._childInstances.length=0,e.forEachInIterator(s,i=>{const r=this._childCreator(i);this._childInstances.push(r),t.appendChild(Bi(r,this._mountArgs))}),this._listElement.appendChild(t),this.adjustPadding(e)}renderUpdate(e,t){if(t.intersects(e)){for(const s of e.reverseIterable())if(!t.containsIndex(s)){const i=s-e.start;this.removeChild(i)}t.forEachInIterator(this._list[Symbol.iterator](),(s,i)=>{if(!e.containsIndex(i)){const r=i-t.start;this.addChild(r,s)}}),this.adjustPadding(t)}else this.reRenderFullRange(t)}adjustPadding(e){const t=e.start*this.itemHeight,s=(e.totalLength-e.end)*this.itemHeight,i=this._listElement.style;i.paddingTop=`${t}px`,i.paddingBottom=`${s}px`}mount(){const e=super.mount();return this.scrollContainer=H.div({className:"LazyListParent"},e),this.scrollContainer.addEventListener("scroll",this),this.scrollContainer}unmount(){this.root().removeEventListener("scroll",this),this.scrollContainer=void 0,super.unmount()}root(){return this.scrollContainer}get _listElement(){return super.root()}onAdd(e,t){const s=this.renderRange.queryAdd(e,t,this._list);this.applyRemoveAddResult(s)}onRemove(e,t){const s=this.renderRange.queryRemove(e,this._list);this.applyRemoveAddResult(s)}onMove(e,t,s){const i=this.renderRange.queryMove(e,t,s,this._list);i&&(i.type===Gs.Move?this.moveChild(this.renderRange.toLocalIndex(i.fromIdx),this.renderRange.toLocalIndex(i.toIdx)):this.applyRemoveAddResult(i))}onUpdate(e,t,s){this.renderRange.containsIndex(e)&&this.updateChild(this.renderRange.toLocalIndex(e),t,s)}applyRemoveAddResult(e){(e.type===Gs.Remove||e.type===Gs.RemoveAndAdd)&&this.removeChild(this.renderRange.toLocalIndex(e.removeIdx)),e.newRange&&(this.renderRange=e.newRange,this.adjustPadding(this.renderRange)),(e.type===Gs.Add||e.type===Gs.RemoveAndAdd)&&this.addChild(this.renderRange.toLocalIndex(e.addIdx),e.value)}}class wf extends E{render(e,t){return e.li({className:"MemberTileView"},e.a({href:t.detailsUrl},[e.view(new wt(t,32)),e.div({className:"MemberTileView_name"},s=>s.name)]))}}class vf extends E{render(e,t){const s=new yf({list:t.memberTileViewModels,className:"MemberListView__list",itemHeight:40},i=>new wf(i));return e.div({className:"MemberListView"},[e.div({className:"MemberListView__invite-container"},[e.button({className:"MemberListView__invite-btn button-action primary",onClick:()=>t.openInvitePanel()},t.i18n`Invite to this room`)]),e.view(s)])}}class bf extends E{render(e,t){const s=[e.p(t.isEncrypted?t.i18n`Messages in this room are end-to-end encrypted.`:t.i18n`Messages in this room are not end-to-end encrypted.`)];return t.features.crossSigning&&s.push(e.div({className:"MemberDetailsView_shield_container"},[e.span({className:i=>`MemberDetailsView_shield_${i.trustShieldColor}`}),e.p({className:"MemberDetailsView_shield_description"},i=>i.trustDescription)])),e.div({className:"MemberDetailsView"},[e.view(new wt(t,128)),e.div({className:"MemberDetailsView_name"},e.h2(i=>i.name)),e.div({className:"MemberDetailsView_id"},t.userId),this._createSection(e,t.i18n`Role`,i=>i.role),this._createSection(e,t.i18n`Security`,s),this._createOptions(e,t)])}_createSection(e,t,s){return e.div({className:"MemberDetailsView_section"},[e.div({className:"MemberDetailsView_label"},t),e.div({className:"MemberDetailsView_value"},s)])}_createOptions(e,t){const s=[e.a({href:t.linkToUser,target:"_blank",rel:"noopener"},t.i18n`Open Link to User`),e.button({className:"text",onClick:()=>t.openDirectMessage()},t.i18n`Open direct message`)];if(t.features.crossSigning){t.canVerifyUser&&s.push(e.button({className:"text",onClick:()=>t.verifyUser()},t.i18n`Verify`));const i=()=>{confirm("You don't want to do this with any account but a test account. This will cross-sign this user without verifying their keys first. You won't be able to undo this apart from resetting your cross-signing keys.")&&t.signUser()};s.push(e.button({className:"text",onClick:i},t.i18n`Cross-sign user (DO NOT USE, TESTING ONLY)`))}return e.div({className:"MemberDetailsView_section"},[e.div({className:"MemberDetailsView_label"},t.i18n`Options`),e.div({className:"MemberDetailsView_options"},s)])}}class Sf extends E{render(e,t){return e.div({className:"WaitingForOtherUserView"},[e.div({className:"WaitingForOtherUserView__heading"},[ye(e),e.h2({className:"WaitingForOtherUserView__title"},t.title)]),e.p({className:"WaitingForOtherUserView__description"},t.description),e.div({className:"WaitingForOtherUserView__actions"},e.button({className:{"button-action":!0,primary:!0,destructive:!0},onclick:()=>t.cancel()},"Cancel"))])}}class kf extends E{render(e,t){return e.div({className:"VerificationCancelledView"},[e.h2({className:"VerificationCancelledView__title"},t.title),e.p({className:"VerificationCancelledView__description"},t.description),e.div({className:"VerificationCancelledView__actions"},[e.button({className:{"button-action":!0,primary:!0},onclick:()=>t.dismiss()},"Got it")])])}}class If extends E{render(e){return e.div({className:"SelectMethodView"},[e.map(t=>t.hasProceeded,(t,s,i)=>t?ye(s):s.div([s.div({className:"SelectMethodView__heading"},[s.h2({className:"SelectMethodView__title"},this.getHeading(s,i))]),s.p({className:"SelectMethodView__description"},this.getSubheading(i)),s.div({className:"SelectMethodView__actions"},[s.button({className:{"button-action":!0,primary:!0,destructive:!0},onclick:()=>i.cancel()},"Cancel"),s.button({className:{"button-action":!0,primary:!0},onclick:()=>i.proceed()},"Proceed")])]))])}getHeading(e,t){return t.isCrossSigningAnotherUser?[t.i18n`Verify user `,e.span({className:"SelectMethodView__name"},t.otherUserId),t.i18n` by comparing emojis?`]:[t.i18n`Verify device`,e.span({className:"SelectMethodView__name"},t.deviceName),t.i18n` by comparing emojis?`]}getSubheading(e){return e.isCrossSigningAnotherUser?e.i18n`You are about to verify user (${e.otherUserId}) by comparing emojis.`:e.i18n`You are about to verify your other device (${e.deviceName}) by comparing emojis.`}}class Mf extends E{render(e,t){const s=t.emojis.reduce((r,[o,c])=>{const l=e.div({className:"EmojiContainer"},[e.div({className:"EmojiContainer__emoji"},o),e.div({className:"EmojiContainer__name"},c)]);return r.push(l),r},[]),i=e.div({className:"EmojiCollection"},s);return e.div({className:"VerifyEmojisView"},[e.div({className:"VerifyEmojisView__heading"},[e.h2({className:"VerifyEmojisView__title"},t.i18n`Do the emojis match?`)]),e.p({className:"VerifyEmojisView__description"},t.i18n`Confirm the emoji below are displayed on both devices, in the same order:`),e.div({className:"VerifyEmojisView__emojis"},i),e.map(r=>r.isWaiting,(r,o,c)=>r?o.div({className:"VerifyEmojisView__waiting"},[ye(o),o.span(c.i18n`Waiting for you to verify on your other device`)]):o.div({className:"VerifyEmojisView__actions"},[o.button({className:{"button-action":!0,primary:!0,destructive:!0},onclick:()=>c.setEmojiMatch(!1)},c.i18n`They don't match`),o.button({className:{"button-action":!0,primary:!0},onclick:()=>c.setEmojiMatch(!0)},c.i18n`They match`)]))])}}class Cf extends E{render(e,t){return e.div({className:"VerificationCompleteView"},[e.div({className:"VerificationCompleteView__icon"}),e.div({className:"VerificationCompleteView__heading"},[e.h2({className:"VerificationCompleteView__title"},t.i18n`Verification completed successfully!`)]),e.p({className:"VerificationCompleteView__description"},t.verificationSuccessfulMessage),e.div({className:"VerificationCompleteView__actions"},[e.button({className:{"button-action":!0,primary:!0},onclick:()=>t.dismiss()},"Got it")])])}}class Ef extends E{render(e,t){return e.div({className:"MissingKeysView"},[e.h2({className:"MissingKeysView__heading"},t.i18n`Verification is currently not possible!`),e.p({className:"MissingKeysView__description"},t.i18n`Some keys needed for verification are missing. You can fix this by enabling key backup in settings.`),e.div({className:"MissingKeysView__actions"},[e.button({className:{"button-action":!0,primary:!0},onclick:()=>t.gotoSettings()},"Open Settings")])])}}class Fc extends E{render(e,t){return e.div({className:{middle:!t.isHappeningInRoom,DeviceVerificationView:!0}},[e.mapView(s=>s.currentStageViewModel,s=>{switch(s==null?void 0:s.kind){case"waiting-for-user":return new Sf(s);case"verification-cancelled":return new kf(s);case"select-method":return new If(s);case"verify-emojis":return new Mf(s);case"verification-completed":return new Cf(s);case"keys-missing":return new Ef(s);default:return new $i(s,()=>ye(e))}})])}}class Rf extends E{render(e,t){const s=e.input({className:"InvitePanelView__input",type:"text",placeholder:"Enter user-id of user",onkeydown:i=>{i.key==="Enter"&&t.invite(s.value)}});return e.div({className:"InvitePanelView"},[e.h3({className:"InvitePanelView__heading"},i=>i.i18n`Invite to ${i.roomName}`),e.div({className:"InvitePanelView__form"},[s,e.button({className:"InvitePanelView__btn button-action primary",onClick:()=>t.invite(s.value)},"Invite")]),e.div({className:"InvitePanelView__error"},[e.ifView(i=>!!i.errorViewModel,i=>new Vs(i.errorViewModel))])])}}class Tf extends E{render(e){return e.div({className:"RightPanelView"},[e.ifView(t=>t.activeViewModel,t=>new Af(t)),e.mapView(t=>t.activeViewModel,t=>this._viewFromType(t))])}_viewFromType(e){switch(e==null?void 0:e.type){case"room-details":return new uf(e);case"member-list":return new vf(e);case"member-details":return new bf(e);case"invite":return new Rf(e);case"verification":return new Fc(e);default:return new Vc}}}class Af extends E{render(e,t){return e.div({className:"RightPanelView_buttons"},[e.button({className:{back:!0,"button-utility":!0,hide:s=>!s.activeViewModel.shouldShowBackButton},onClick:()=>t.showPreviousPanel()}),e.button({className:"close button-utility",onClick:()=>t.closePanel()})])}}class xf extends os{constructor(e){const t={className:"Timeline_messageReactions",tagName:"div",list:e.reactions,onItemClick:s=>s.onClick()};super(t,s=>new Vf(s))}}class Vf extends E{render(e,t){return e.button({className:{active:s=>s.isActive,pending:s=>s.isPending}},[t.key," ",s=>`${s.count}`])}onClick(){this.value.toggle()}}class hi extends E{constructor(e,t,s,i="li"){super(e),this._menuPopup=null,this._tagName=i,this._viewClassForTile=t,this._renderFlags=s}get _interactive(){var e,t;return(t=(e=this._renderFlags)==null?void 0:e.interactive)!=null?t:!0}get _isReplyPreview(){var e;return(e=this._renderFlags)==null?void 0:e.reply}render(e,t){const s=[this.renderMessageBody(e,t)];this._interactive&&s.push(e.button({className:"Timeline_messageOptions"},"\u22EF"));const i=e.el(this._tagName,{className:{Timeline_message:!0,own:t.isOwn,unsent:t.isUnsent,unverified:o=>o.isUnverified,disabled:!this._interactive,continuation:o=>o.isContinuation},"data-event-id":t.eventId},s);e.mapSideEffect(o=>o.isContinuation,(o,c)=>{if(o&&c===!1)i.removeChild(i.querySelector(".Timeline_messageAvatar")),i.removeChild(i.querySelector(".Timeline_messageSender"));else if(!o&&!this._isReplyPreview){const l=H.a({href:t.memberPanelLink,className:"Timeline_messageAvatar"},[Ss(t,30)]),h=H.div({className:`Timeline_messageSender usercolor${t.avatarColorNumber}`,title:t.sender},t.displayName);i.insertBefore(l,i.firstChild),i.insertBefore(h,i.firstChild)}});let r=null;return e.mapSideEffect(o=>o.reactions,o=>{o&&this._interactive&&!r?(r=new xf(o),this.addSubView(r),i.appendChild(Bi(r))):!o&&r&&(i.removeChild(r.root()),r.unmount(),this.removeSubView(r),r=null)}),i}onClick(e){e.target.className==="Timeline_messageOptions"&&this._toggleMenu(e.target)}_toggleMenu(e){if(this._menuPopup&&this._menuPopup.isOpen)this._menuPopup.close();else{const t=this.createMenuOptions(this.value);if(!t.length)return;this.root().classList.add("menuOpen");const s=()=>this.root().classList.remove("menuOpen");this._menuPopup=new Dr(new ue(t),s),this._menuPopup.trackInTemplateView(this),this._menuPopup.showRelativeTo(e,2)}}createMenuOptions(e){const t=[];return e.canReact&&e.shape!=="redacted"&&!e.isPending&&(t.push(new Nf(e)),t.push(ue.option(e.i18n`Reply`,()=>e.startReply()))),e.canAbortSending?t.push(ue.option(e.i18n`Cancel`,()=>e.abortSending())):e.canRedact&&t.push(ue.option(e.i18n`Delete`,()=>e.redact()).setDestructive()),t.push(ue.option(e.i18n`Copy matrix.to permalink`,()=>e.copyPermalink())),t}renderMessageBody(){}}class Nf{constructor(e){this._vm=e}toDOM(e){const t=["\u{1F44D}","\u{1F44E}","\u{1F604}","\u{1F389}","\u{1F615}","\u2764\uFE0F","\u{1F680}","\u{1F440}"].map(i=>e.button({onClick:()=>this._vm.react(i)},i)),s=e.button({onClick:()=>{const i=prompt("Enter your reaction (emoji)");i&&this._vm.react(i)}},"\u2026");return e.li({className:"quick-reactions"},[...t,s])}}class Df extends E{constructor(e,t){super(e),this._viewClassForTile=t}render(e,t){const s=this._viewClassForTile(t);if(!s)throw new Error(`Shape ${t.shape} is unrecognized.`);const i=new s(t,this._viewClassForTile,{reply:!0,interactive:!1});return e.div({className:"ReplyPreviewView"},e.blockquote([e.a({className:"link",target:"_blank",href:t.permaLink},"In reply to"),e.a({className:"pill",target:"_blank",href:t.senderProfileLink},[Ss(t,12,void 0),t.displayName]),e.br(),e.view(i)]))}}class Uf extends E{render(e){return e.blockquote({className:"ReplyPreviewView"},[e.div({className:"Timeline_messageBody statusMessage"},"This reply could not be found.")])}}class Of extends hi{renderMessageBody(e,t){const s=e.time({className:{hidden:!t.time}},t.time),i=e.div({className:{Timeline_messageBody:!0,statusMessage:o=>o.shape==="message-status"}},e.mapView(o=>o.replyTile,o=>this._isReplyPreview?null:t.isReply&&!o?new Uf:o?new Df(o,this._viewClassForTile):null)),r=o=>(o==null?void 0:o.nodeType)!==Node.COMMENT_NODE&&o.className!=="ReplyPreviewView";return e.mapSideEffect(o=>o.body,o=>{for(;r(i.lastChild);)i.removeChild(i.lastChild);for(const c of o.parts)i.appendChild(Lc(c));i.appendChild(s)}),i}}function Pf(n){const e=n.items.map(s=>H.li(Es(s))),t=n.startOffset;return t?H.ol({start:t},e):H.ul(e)}function Ff(n){const e={src:n.src};return n.width&&(e.width=n.width),n.height&&(e.height=n.height),n.alt&&(e.alt=n.alt),n.title&&(e.title=n.title),H.img(e)}function Lf(n){const e=`avatar size-12 usercolor${n.avatarColorNumber}`,t=H.div({class:e},Ft(n.avatarInitials)),s=Es(n.children);return s.unshift(t),H.a({class:"pill",href:n.href,rel:"noopener",target:"_blank"},s)}function Kf(n){const e=[];if(n.head){const s=n.head.map(i=>H.th(Es(i)));e.push(H.thead(H.tr(s)))}const t=[];for(const s of n.body){const i=s.map(r=>H.td(Es(r)));t.push(H.tr(i))}return e.push(H.tbody(t)),H.table(e)}const Bf={header:n=>H["h"+Math.min(6,n.level)](Es(n.inlines)),codeblock:n=>H.pre(H.code(Ft(n.text))),table:n=>Kf(n),code:n=>H.code(Ft(n.text)),text:n=>Ft(n.text),link:n=>H.a({href:n.url,className:"link",target:"_blank",rel:"noopener"},Es(n.inlines)),pill:Lf,format:n=>H[n.format](Es(n.children)),rule:()=>H.hr(),list:Pf,image:Ff,newline:()=>H.br()};function Lc(n){const e=Bf[n.type];return e?e(n):Ft(`[unknown part type ${n.type}]`)}function Es(n){return Array.from(n,Lc)}class Kc extends hi{renderMessageBody(e,t){let i=`padding-top: ${t.height/t.width*100}%;`;t.platform.isIE11&&(i=`height: ${t.height}px`);const r=[e.div({className:"spacer",style:i}),this.renderMedia(e,t),e.time(t.time)],o=e.div({className:{status:!0,hidden:c=>!c.status}},c=>c.status);if(r.push(o),t.isPending){const c=e.progress({min:0,max:100,value:l=>l.uploadPercentage,className:{hidden:l=>!l.isUploading}});r.push(c)}return e.div({className:"Timeline_messageBody"},[e.div({className:"media",style:`max-width: ${t.width}px`,"data-testid":"media"},r),e.if(c=>c.error,c=>c.p({className:"error"},t.error))])}createMenuOptions(e){const t=super.createMenuOptions(e);if(!e.isPending){let s;switch(e.shape){case"image":s=e.i18n`Download image`;break;case"video":s=e.i18n`Download video`;break;default:s=e.i18n`Download media`;break}t.push(ue.option(s,()=>e.downloadMedia()))}return t}}class $f extends Kc{renderMedia(e,t){const s=e.img({src:i=>i.thumbnailUrl,alt:i=>i.label,title:i=>i.label,style:`max-width: ${t.width}px; max-height: ${t.height}px;`});return t.isPending||!t.lightboxUrl?s:e.a({href:t.lightboxUrl},s)}}function Tr(n,e){return new Promise((t,s)=>{let i;const r=c=>{i(),s(c.target.error)},o=()=>{i(),t()};i=()=>{n.removeEventListener(e,o),n.removeEventListener("error",r)},n.addEventListener(e,o),n.addEventListener("error",r)})}async function jf(n){var e;try{if((e=navigator==null?void 0:navigator.clipboard)!=null&&e.writeText)return await navigator.clipboard.writeText(n),!0;{const t=document.createElement("textarea");t.value=n,t.style.top="0",t.style.left="0",t.style.position="fixed",document.body.appendChild(t);const s=document.getSelection();if(!s)return console.error("copyPlaintext: Unable to copy text to clipboard in fallback mode because `selection` was null/undefined"),!1;const i=document.createRange();i.selectNode(t),s.removeAllRanges(),s.addRange(i);const r=document.execCommand("copy");return s.removeAllRanges(),document.body.removeChild(t),r||console.error("copyPlaintext: Unable to copy text to clipboard in fallback mode because the `copy` command is unsupported or disabled"),r}}catch(t){console.error("copyPlaintext: Ran into an error",t)}return!1}class qf extends Kc{renderMedia(e){const t=e.video({src:s=>s.videoUrl||`data:${s.mimeType},`,title:s=>s.label,controls:!0,preload:"none",poster:s=>s.thumbnailUrl,onPlay:this._onPlay.bind(this),style:s=>`max-width: ${s.width}px; max-height: ${s.height}px;${s.isPending?"z-index: -1":""}`});return t.addEventListener("error",this._onError.bind(this)),t}async _onPlay(e){const t=this.value;if(!t.videoUrl)try{const s=e.target;await t.loadVideo();const i=Tr(s,"loadeddata");s.load(),await i,s.play()}catch{}}_onError(e){const t=this.value,s=e.target,i=s.error;if(i instanceof window.MediaError&&i.code===4)if(!s.src.startsWith("data:"))t.setViewError(new Error(`this browser does not support videos of type ${t.mimeType}.`));else return;else t.setViewError(i)}}class Hf extends hi{renderMessageBody(e,t){const s=[];return t.isPending?s.push(i=>i.label):s.push(e.button({className:"link",onClick:()=>t.download()},i=>i.label),e.time(t.time)),e.p({className:"Timeline_messageBody statusMessage"},s)}}class Wf extends hi{renderMessageBody(e,t){return e.p({className:"Timeline_messageBody statusMessage"},[e.span(t.label),e.a({className:"Timeline_locationLink",href:t.mapsLink,target:"_blank",rel:"noopener"},t.i18n`Open in maps`),e.time(t.time)])}}class zf extends hi{renderMessageBody(e,t){return e.p({className:"Timeline_messageBody statusMessage"},t.label)}}class Gf extends E{constructor(e){super(e)}render(e,t){return e.li({className:"AnnouncementView","data-event-id":t.eventId},e.div(s=>s.announcement))}onClick(){}}class Yf extends hi{renderMessageBody(e){return e.p({className:"Timeline_messageBody statusMessage"},t=>t.description)}createMenuOptions(e){const t=super.createMenuOptions(e);return e.isRedacting&&t.push(ue.option(e.i18n`Cancel`,()=>e.abortPendingRedaction())),t}}class Jf extends E{constructor(e){super(e)}render(e,t){const s={GapView:!0,isLoading:i=>i.isLoading,isAtTop:i=>i.isAtTop};return e.li({className:s},[e.div({class:"GapView_container"},[e.if(i=>i.showSpinner,i=>ye(i)),e.span(i=>i.status)]),e.if(i=>!!i.errorViewModel,i=>i.view(new Vs(t.errorViewModel,{inline:!0})))])}onClick(){}}class Qf extends E{render(e,t){return e.li({className:"CallTileView AnnouncementView"},e.div([e.if(s=>s.errorViewModel,s=>s.div({className:"CallTileView_error"},s.view(new Vs(t.errorViewModel,{inline:!0})))),e.div([e.div({className:"CallTileView_title"},s=>s.title),e.div({className:"CallTileView_subtitle"},[t.typeLabel," \u2022 ",e.span({className:"CallTileView_memberCount"},s=>s.memberCount)]),e.view(new os({className:"CallTileView_members",tagName:"div",list:t.memberViewModels},s=>new wt(s,24))),e.div(s=>s.duration),e.div([e.button({className:"CallTileView_join button-action primary",hidden:s=>!s.canJoin},"Join"),e.button({className:"CallTileView_leave button-action primary destructive",hidden:s=>!s.canLeave},"Leave")])])]))}onClick(e){e.target.classList.contains("CallTileView_join")?this.value.join():e.target.classList.contains("CallTileView_leave")&&this.value.leave()}}class Xf extends E{render(e,t){return e.h2({className:"DateHeader"},e.time({dateTime:t.machineReadableDate},t.relativeDate))}onClick(){}}class Zf extends E{render(e,t){return e.div({className:"VerificationTileView"},e.mapView(s=>s.status,s=>{switch(s){case Ai.Ready:return new ey(t);case Ai.Cancelled:return new ty(t);case Ai.Completed:return new sy(t);case Ai.InProgress:return new iy(t)}}))}onClick(e){var t;(t=this._subViews)==null||t.forEach(s=>{var i;return(i=s.onClick)==null?void 0:i.call(s,e)})}}class ey extends E{render(e,t){return e.div({className:"VerificationReadyTileView"},[e.div({className:"VerificationTileView__shield"}),e.div({className:"VerificationTileView__description"},[e.div(t.description)]),e.div({className:"VerificationTileView__actions"},[e.button({className:"VerificationTileView__accept button-action primary"},"Accept"),e.button({className:"VerificationTileView__reject button-action secondary"},"Reject")])])}onClick(e){e.target.classList.contains("VerificationTileView__accept")?this.value.accept():e.target.classList.contains("VerificationTileView__reject")&&this.value.reject()}}class ty extends E{render(e,t){return e.div({className:"VerificationCancelledTileView"},[e.div({className:"VerificationTileView__description"},t.i18n`${t.isCancelledByUs?"You":t.sender} cancelled the verification!`)])}}class sy extends E{render(e,t){return e.div({className:"VerificationCompletedTileView"},[e.div({className:"VerificationTileView__description"},[e.div({className:"VerificationTileView__shield"}),e.div(t.i18n`You verified ${t.sender}`)])])}}class iy extends E{render(e,t){return e.div({className:"VerificationInProgressTileView"},[e.div({className:"VerificationTileView__description"},t.i18n`Verification in progress`),e.div({className:"VerificationTileView__actions"},[ye(e)])])}}function Ho(n){switch(n.shape){case me.Gap:return Jf;case me.Announcement:return Gf;case me.Message:case me.MessageStatus:return Of;case me.Image:return $f;case me.Video:return qf;case me.File:return Hf;case me.Location:return Wf;case me.MissingAttachment:return zf;case me.Redacted:return Yf;case me.Call:return Qf;case me.DateHeader:return Xf;case me.Verification:return Zf;default:throw new Error(`Tiles of shape "${n.shape}" are not supported, check the tileClassForEntry function in the view model`)}}class ry extends E{render(e,t){const s=e.input({type:"text",name:"id",id:"id",placeholder:t.i18n`Enter a room id or alias`,disabled:i=>i.joinInProgress});return e.main({className:"JoinRoomView middle"},[e.div({className:"JoinRoomView_header middle-header"},[e.a({className:"button-utility close-middle",href:t.closeUrl,title:t.i18n`Cancel room join`}),e.h2("Join room")]),e.div({className:"JoinRoomView_body centered-column"},[e.form({className:"JoinRoomView_detailsForm form",onSubmit:i=>this.onSubmit(i,s.value)},[e.div({className:"vertical-layout"},[e.div({className:"stretch form-row text"},[e.label({for:"id"},t.i18n`Room id`),s])]),e.div({className:"button-row"},[e.button({className:"button-action primary",type:"submit",disabled:i=>i.joinInProgress},t.i18n`Join`)]),e.map(i=>i.status,(i,r)=>r.div({className:"JoinRoomView_status"},[ye(r,{hidden:o=>!o.joinInProgress}),r.span(i)]))])])])}onSubmit(e,t){e.preventDefault(),this.value.join(t)}}class ny extends E{render(e,t){return e.div({className:"CallToastNotificationView"},[e.div({className:"CallToastNotificationView__top"},[e.view(new wt(t,24)),e.span({className:"CallToastNotificationView__name"},s=>s.roomName),e.button({className:"button-action CallToastNotificationView__dismiss-btn",onClick:()=>t.dismiss()})]),e.div({className:"CallToastNotificationView__description"},[e.span(t.i18n`Video call started`)]),e.div({className:"CallToastNotificationView__info"},[e.span({className:"CallToastNotificationView__call-type"},t.i18n`Video`),e.span({className:"CallToastNotificationView__member-count"},s=>s.memberCount)]),e.div({className:"CallToastNotificationView__action"},[e.button({className:"button-action primary",onClick:()=>t.join()},t.i18n`Join`)]),e.if(s=>!!s.errorViewModel,s=>s.div({className:"CallView_error"},s.view(new Vs(t.errorViewModel))))])}}class oy extends E{render(e,t){return e.div({className:"VerificationToastNotificationView"},[e.div({className:"VerificationToastNotificationView__top"},[e.span({className:"VerificationToastNotificationView__title"},t.i18n`Device Verification`),e.button({className:"button-action VerificationToastNotificationView__dismiss-btn",onClick:()=>t.dismiss()})]),e.div({className:"VerificationToastNotificationView__description"},[e.span(t.i18n`Do you want to verify device ${t.otherDeviceId}?`)]),e.div({className:"VerificationToastNotificationView__action"},[e.button({className:"button-action primary destructive",onClick:()=>t.dismiss()},t.i18n`Ignore`),e.button({className:"button-action primary",onClick:()=>t.accept()},t.i18n`Accept`)])])}}function ay(n){switch(n.kind){case"calls":return new ny(n);case"verification":return new oy(n);default:throw new Error(`Cannot find view class for notification kind ${n.kind}`)}}class cy extends E{render(e,t){return e.div({className:"ToastCollectionView"},[e.ifView(s=>!!s.toastViewModels,s=>new os({list:t.toastViewModels,parentProvidesUpdates:!1},i=>ay(i)))])}}class ly extends E{render(e,t){return e.div({className:{SessionView:!0,"middle-shown":s=>!!s.activeMiddleViewModel,"right-shown":s=>!!s.rightPanelViewModel}},[e.view(new cy(t.toastCollectionViewModel)),e.view(new tf(t.sessionStatusViewModel)),e.view(new $g(t.leftPanelViewModel)),e.mapView(s=>s.activeMiddleViewModel,()=>t.roomGridViewModel?new sf(t.roomGridViewModel,Ho):t.settingsViewModel?new hf(t.settingsViewModel):t.createRoomViewModel?new df(t.createRoomViewModel):t.joinRoomViewModel?new ry(t.joinRoomViewModel):t.verificationViewModel?new Fc(t.verificationViewModel):t.currentRoomViewModel?t.currentRoomViewModel.kind==="invite"?new Dc(t.currentRoomViewModel):t.currentRoomViewModel.kind==="room"?new xc(t.currentRoomViewModel,Ho):t.currentRoomViewModel.kind==="roomBeingCreated"?new Nc(t.currentRoomViewModel):new Jg(t.currentRoomViewModel):new ni(s=>s.div({className:"room-placeholder"},s.h2(t.i18n`Choose a room on the left side.`)))),e.mapView(s=>s.lightboxViewModel,s=>s?new Xg(s):null),e.mapView(s=>s.rightPanelViewModel,s=>s?new Tf(s):null)])}}function Bc(n){return "3895512102"?n.a({target:"_blank",href:"https://github.com/vector-im/hydrogen-web/releases/tag/v0.5.1"},`Hydrogen v0.5.1 (${"3895512102"}) on Github`):n.a({target:"_blank",href:"https://github.com/vector-im/hydrogen-web"},"Hydrogen on Github")}class hy extends E{render(e,t){const s=o=>!!o.isBusy,i=e.input({id:"username",type:"text",placeholder:t.i18n`Username`,disabled:s}),r=e.input({id:"password",type:"password",placeholder:t.i18n`Password`,disabled:s});return e.div({className:"PasswordLoginView form"},[e.if(o=>o.error,o=>o.div({className:"error"},c=>c.error)),e.form({onSubmit:o=>{o.preventDefault(),t.login(i.value,r.value)}},[e.if(o=>o.errorMessage,(o,c)=>o.p({className:"error"},c.i18n(c.errorMessage))),e.div({className:"form-row text"},[e.label({for:"username"},t.i18n`Username`),i]),e.div({className:"form-row text"},[e.label({for:"password"},t.i18n`Password`),r]),e.div({className:"button-row"},[e.button({className:"button-action primary",type:"submit",disabled:s},t.i18n`Log In`)])])])}}class dy extends E{render(e,t){return e.div({className:"Settings"},[e.h3(t.i18n`Restore your encrypted history?`),e.ifView(s=>s.decryptDehydratedDeviceViewModel,s=>new Uc(s.decryptDehydratedDeviceViewModel)),e.map(s=>s.deviceDecrypted,(s,i)=>s?i.p(t.i18n`That worked out, you're good to go!`):i.p(t.i18n`This will claim the dehydrated device ${t.dehydratedDeviceId}, and will set up a new one.`)),e.div({className:"button-row"},[e.button({className:"button-action primary",onClick:()=>{t.finish()},type:"button"},s=>s.deviceDecrypted?s.i18n`Continue`:s.i18n`Continue without restoring`)])])}}class Ur extends E{render(e){const t=e.if(i=>i.hasError,(i,r)=>i.button({onClick:()=>r.exportLogs()},r.i18n`Export logs`)),s=e.if(i=>i.hasError,(i,r)=>i.button({onClick:()=>r.logout()},r.i18n`Log out`));return e.div({className:"SessionLoadStatusView"},[e.p({className:"status"},[ye(e,{hidden:i=>!i.loading}),e.p(i=>i.loadLabel),t,s]),e.ifView(i=>i.accountSetupViewModel,i=>new dy(i.accountSetupViewModel))])}}class uy extends E{render(e){return e.div({className:"CompleteSSOView"},[e.p({className:"CompleteSSOView_title"},"Finishing up your SSO Login"),e.if(t=>t.errorMessage,(t,s)=>t.p({className:"error"},s.i18n(s.errorMessage))),e.mapView(t=>t.loadViewModel,t=>t?new Ur(t):null)])}}class my extends E{render(e,t){const s=i=>i.isBusy;return e.div({className:"PreSessionScreen"},[e.button({className:"button-utility LoginView_back",onClick:()=>t.goBack(),disabled:s}),e.div({className:"logo"}),e.h1([t.i18n`Sign In`]),e.mapView(i=>i.completeSSOLoginViewModel,i=>i?new uy(i):null),e.if(i=>i.showHomeserver,(i,r)=>i.div({className:"LoginView_sso form-row text"},[i.label({for:"homeserver"},r.i18n`Homeserver`),i.input({id:"homeserver",type:"text",placeholder:r.i18n`Your matrix homeserver`,value:r.homeserver,disabled:s,onInput:o=>r.setHomeserver(o.target.value),onChange:()=>r.queryHomeserver()}),i.p({className:{LoginView_forwardInfo:!0,hidden:o=>!o.resolvedHomeserver}},o=>o.i18n`You will connect to ${o.resolvedHomeserver}.`),i.if(o=>o.errorMessage,(o,c)=>o.p({className:"error"},c.i18n(c.errorMessage)))])),e.if(i=>i.isFetchingLoginOptions,i=>i.div({className:"LoginView_query-spinner"},[ye(i),i.p("Fetching available login options...")])),e.mapView(i=>i.passwordLoginViewModel,i=>i?new hy(i):null),e.if(i=>i.passwordLoginViewModel&&i.startSSOLoginViewModel,i=>i.p({className:"LoginView_separator"},t.i18n`or`)),e.mapView(i=>i.startSSOLoginViewModel,i=>i?new _y(i):null),e.mapView(i=>i.loadViewModel,i=>i?new Ur(i):null),e.p(Bc(e))])}}class _y extends E{render(e,t){return e.div({className:"StartSSOLoginView"},e.button({className:"StartSSOLoginView_button button-action secondary",type:"button",onClick:()=>t.startSSOLogin(),disabled:s=>s.isBusy},t.i18n`Log in with SSO`))}}class py extends E{render(e,t){const s=new $i(t,r=>r.div([r.p("Are you sure you want to log out?"),r.div({className:"button-row"},[r.a({className:"button-action",type:"submit",href:t.cancelUrl},["Cancel"]),r.button({className:"button-action primary destructive",type:"submit",onClick:()=>t.logout()},t.i18n`Log out`)])])),i=new $i(t,r=>r.p({className:"status",hidden:o=>!o.showStatus},[ye(r,{hidden:o=>!o.busy}),r.span(o=>o.status)]));return e.div({className:"LogoutScreen"},[e.div({className:"content"},[e.mapView(r=>r.showConfirm,r=>r?s:i)])])}}class gy extends E{render(e){return e.div({className:"LogoutScreen"},[e.div({className:"content"},e.map(t=>t.showStatus,(t,s,i)=>t?s.p({className:"status"},[ye(s,{hidden:r=>!r.showSpinner}),s.span(r=>r.status)]):s.div([s.p("Your access token is no longer valid! You can reauthenticate in the next screen."),s.div({className:"button-row"},[s.button({className:"button-action primary",type:"submit",onClick:()=>i.proceed()},i.i18n`Proceed`)])])))])}}class fy extends E{render(e,t){return e.div({className:"PreSessionScreen"},[e.div({className:"logo"}),e.div({className:"SessionLoadView"},[e.view(new Ur(t))]),e.div({className:{"button-row":!0,hidden:s=>s.loading}},e.a({className:"button-action primary",href:t.backUrl},t.i18n`Go back`))])}}class yy extends E{_onDeleteClick(){confirm("Are you sure?")&&this.value.delete()}_onClearClick(){confirm("Are you sure?")&&this.value.clear()}render(e,t){return e.li([e.a({className:"session-info",href:t.openUrl},[e.div({className:`avatar usercolor${t.avatarColorNumber}`},s=>s.avatarInitials),e.div({className:"user-id"},s=>s.label)])])}}class wy extends E{render(e,t){const s=new os({list:t.sessions,parentProvidesUpdates:!1},i=>new yy(i));return e.div({className:"PreSessionScreen"},[e.div({className:"logo"}),e.div({className:"SessionPickerView"},[e.h1(["Continue as \u2026"]),e.view(s),e.div({className:"button-row"},[e.a({className:"button-action primary",href:t.cancelUrl},t.i18n`Sign In`)]),e.ifView(i=>i.loadViewModel,()=>new Ur(t.loadViewModel)),e.p(Bc(e))])])}}class vy extends E{render(e,t){return e.mapView(s=>s.activeSection,s=>{switch(s){case"error":return new ni(i=>i.div({className:"StatusView"},[i.h1("Something went wrong"),i.p(t.errorText)]));case"session":return new ly(t.sessionViewModel);case"login":return new my(t.loginViewModel);case"logout":return new py(t.logoutViewModel);case"forced-logout":return new gy(t.forcedLogoutViewModel);case"picker":return new wy(t.sessionPickerViewModel);case"redirecting":return new ni(i=>i.p("Redirecting..."));case"loading":return new fy(t.sessionLoadViewModel);default:throw new Error(`Unknown section: ${t.activeSection}`)}})}}class by{constructor(e){this._reject=null,this._handle=null,this._promise=new Promise((t,s)=>{this._reject=s,this._handle=setTimeout(()=>{this._reject=null,t()},e)})}elapsed(){return this._promise}abort(){this._reject&&(this._reject(new rt),clearTimeout(this._handle),this._handle=null,this._reject=null)}dispose(){this.abort()}}class Sy{constructor(e,t){this._handle=setInterval(t,e)}dispose(){this._handle&&(clearInterval(this._handle),this._handle=null)}}class ky{constructor(){this._start=window.performance.now()}measure(){return window.performance.now()-this._start}}class Iy{createMeasure(){return new ky}createTimeout(e){return new by(e)}createInterval(e,t){return new Sy(t,e)}now(){return Date.now()}}class My{constructor(e){this._waitingForReply=new Map,this._messageIdCounter=0,this._navigation=null,this._registration=null,this._registrationPromise=null,this._currentController=null,this._sessionInfoStorage=e,this.haltRequests=!1,this._authData={}}setNavigation(e){this._navigation=e}updateAuthData(e){if(!e.accessToken&&!e.homeserver)throw new Error("updateAuthData argument must contain accessToken, homeserver or both!");this._authData=It(It({},this._authData),e)}registerAndStart(e){this._registrationPromise=(async()=>{navigator.serviceWorker.addEventListener("message",this),navigator.serviceWorker.addEventListener("controllerchange",this),this._registration=await navigator.serviceWorker.register(e),await navigator.serviceWorker.ready,this._currentController=navigator.serviceWorker.controller,this._registration.addEventListener("updatefound",this),this._registrationPromise=null,this._registration.waiting&&this._registration.active&&this._proposeUpdate(),console.log("Service Worker registered")})()}async _onMessage(e){const{data:t}=e,s=t.replyTo;if(s){const i=this._waitingForReply.get(s);i&&(this._waitingForReply.delete(s),i(t.payload))}if(t.type==="hasSessionOpen"){const i=this._navigation.observe("session").get()===t.payload.sessionId;e.source.postMessage({replyTo:t.id,payload:i})}else if(t.type==="hasRoomOpen"){const i=this._navigation.observe("session").get()===t.payload.sessionId,r=this._navigation.observe("room").get()===t.payload.roomId;e.source.postMessage({replyTo:t.id,payload:i&&r})}else if(t.type==="closeSession"){const{sessionId:i}=t.payload;this._closeSessionIfNeeded(i).finally(()=>{e.source.postMessage({replyTo:t.id})})}else t.type==="haltRequests"?(this.haltRequests=!0,e.source.postMessage({replyTo:t.id})):t.type==="openRoom"?this._navigation.push("room",t.payload.roomId):t.type==="getAuthInfo"&&e.source.postMessage({replyTo:t.id,payload:this._authData})}_closeSessionIfNeeded(e){var s;const t=(s=this._navigation)==null?void 0:s.path.get("session");return e&&(t==null?void 0:t.value)===e?new Promise(i=>{const r=this._navigation.pathObservable.subscribe(o=>{const c=o.get("session");(!c||c.value!==e)&&(r(),i())});this._navigation.push("session")}):Promise.resolve()}async _proposeUpdate(){if(document.hidden)return;const e=await this._sendAndWaitForReply("version",null,this._registration.waiting);(this.version==="develop"||confirm(`Version ${e.version} (${e.buildHash}) is available. Reload to apply?`))&&(console.log("Service Worker has been updated!"),await this._sendAndWaitForReply("haltRequests"),this._send("skipWaiting",null,this._registration.waiting))}handleEvent(e){switch(e.type){case"message":this._onMessage(e);break;case"updatefound":this._registration.installing.addEventListener("statechange",this);break;case"statechange":{e.target.state==="installed"&&(this._proposeUpdate(),e.target.removeEventListener("statechange",this));break}case"controllerchange":this._currentController?document.location.reload():this._currentController=navigator.serviceWorker.controller;break}}async _send(e,t,s=void 0){this._registrationPromise&&await this._registrationPromise,s||(s=this._registration.active),s.postMessage({type:e,payload:t})}async _sendAndWaitForReply(e,t,s=void 0){this._registrationPromise&&await this._registrationPromise,s||(s=this._registration.active),this._messageIdCounter+=1;const i=this._messageIdCounter,r=new Promise(o=>{this._waitingForReply.set(i,o)});return s.postMessage({type:e,id:i,payload:t}),await r}async checkForUpdate(){this._registrationPromise&&await this._registrationPromise,this._registration.update()}get version(){return"0.5.1"}get buildHash(){return "3895512102"}async preventConcurrentSessionAccess(e){return this._sendAndWaitForReply("closeSession",{sessionId:e})}async getRegistration(){return this._registrationPromise&&await this._registrationPromise,this._registration}}class Cy{constructor(e,t){this._serviceWorkerHandler=e,this._pushConfig=t}async enablePush(e,t){var i;const s=await((i=this._serviceWorkerHandler)==null?void 0:i.getRegistration());if(s!=null&&s.pushManager){const o=(await s.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this._pushConfig.applicationServerKey})).toJSON(),c=o.keys.p256dh,l={endpoint:o.endpoint,auth:o.keys.auth,events_only:!0,default_payload:t};return e.httpPusher(this._pushConfig.gatewayUrl,this._pushConfig.appId,c,l)}}async disablePush(){var t;const e=await((t=this._serviceWorkerHandler)==null?void 0:t.getRegistration());if(e!=null&&e.pushManager){const s=await e.pushManager.getSubscription();s&&await s.unsubscribe()}}async isPushEnabled(){var t;const e=await((t=this._serviceWorkerHandler)==null?void 0:t.getRegistration());return e!=null&&e.pushManager?!!await e.pushManager.getSubscription():!1}async supportsPush(){var t;if(!this._pushConfig)return!1;const e=await((t=this._serviceWorkerHandler)==null?void 0:t.getRegistration());return e&&"pushManager"in e}async enableNotifications(){return"Notification"in window?await Notification.requestPermission()==="granted":!1}async supportsNotifications(){return"Notification"in window}async areNotificationsEnabled(){return"Notification"in window?Notification.permission==="granted":!1}async showNotification(e,t=void 0){var i;if("Notification"in window){new Notification(e,{body:t});return}const s=await((i=this._serviceWorkerHandler)==null?void 0:i.getRegistration());s==null||s.showNotification(e,{body:t})}}class Ey extends yt{constructor(){super(),this._lastSessionHash=void 0}handleEvent(e){e.type==="hashchange"&&(this.emit(this.get()),this._storeHash(this.get()))}get(){return document.location.search.includes("loginToken")?document.location.search:document.location.hash}replaceUrlSilently(e){window.history.replaceState(null,null,e),this._storeHash(e)}pushUrlSilently(e){window.history.pushState(null,null,e),this._storeHash(e)}pushUrl(e){document.location.hash=e}urlAsPath(e){return e.startsWith("#")?e.substr(1):e}pathAsUrl(e){return`#${e}`}onSubscribeFirst(){var e;this._lastSessionHash=(e=window.localStorage)==null?void 0:e.getItem("hydrogen_last_url_hash"),window.addEventListener("hashchange",this)}onUnsubscribeLast(){window.removeEventListener("hashchange",this)}_storeHash(e){var t;(t=window.localStorage)==null||t.setItem("hydrogen_last_url_hash",e)}getLastSessionUrl(){return this._lastSessionHash}}class Ry extends yt{constructor(){super(),this._onOffline=this._onOffline.bind(this),this._onOnline=this._onOnline.bind(this)}_onOffline(){this.emit(!1)}_onOnline(){this.emit(!0)}get(){return navigator.onLine}onSubscribeFirst(){window.addEventListener("offline",this._onOffline),window.addEventListener("online",this._onOnline)}onUnsubscribeLast(){window.removeEventListener("offline",this._onOffline),window.removeEventListener("online",this._onOnline)}}function Ie(n,e){return n instanceof Promise?n:new Promise((t,s)=>{n.oncomplete=i=>t(i.target.result),n.onerror=()=>s(new Error("Crypto error on "+e))})}class Ty{constructor(e){this._subtleCrypto=e}async verify(e,t,s,i){const r={name:"HMAC",hash:{name:Rs(i)}},o=await Ie(this._subtleCrypto.importKey("raw",e,r,!1,["verify"]),"importKey");return await Ie(this._subtleCrypto.verify(r,o,t,s),"verify")}async compute(e,t,s){const i={name:"HMAC",hash:{name:Rs(s)}},r=await Ie(this._subtleCrypto.importKey("raw",e,i,!1,["sign"]),"importKey"),o=await Ie(this._subtleCrypto.sign(i,r,t),"sign");return new Uint8Array(o)}}class Ay{constructor(e,t,s){this._subtleCrypto=e,this._crypto=t,this._cryptoExtras=s}async pbkdf2(e,t,s,i,r){if(!this._subtleCrypto.deriveBits)throw new Error("PBKDF2 is not supported");const o=await Ie(this._subtleCrypto.importKey("raw",e,{name:"PBKDF2"},!1,["deriveBits"]),"importKey"),c=await Ie(this._subtleCrypto.deriveBits({name:"PBKDF2",salt:s,iterations:t,hash:Rs(i)},o,r),"deriveBits");return new Uint8Array(c)}async hkdf(e,t,s,i,r){if(!this._subtleCrypto.deriveBits)return this._cryptoExtras.hkdf(this._crypto,e,t,s,i,r);const o=await Ie(this._subtleCrypto.importKey("raw",e,{name:"HKDF"},!1,["deriveBits"]),"importKey"),c=await Ie(this._subtleCrypto.deriveBits({name:"HKDF",salt:t,info:s,hash:Rs(i)},o,r),"deriveBits");return new Uint8Array(c)}}class xy{constructor(e,t){this._subtleCrypto=e,this._crypto=t}async decryptCTR({key:e,jwkKey:t,iv:s,data:i,counterLength:r=64}){const o={name:"AES-CTR",counter:s,length:r};let c;try{const l=e||t,h=t?"jwk":"raw";c=await Ie(this._subtleCrypto.importKey(h,l,o,!1,["decrypt"]),"importKey")}catch(l){throw new Error(`Could not import key for AES-CTR decryption: ${l.message}`)}try{const l=await Ie(this._subtleCrypto.decrypt(o,c,i),"decrypt");return new Uint8Array(l)}catch(l){throw new Error(`Could not decrypt with AES-CTR: ${l.message}`)}}async encryptCTR({key:e,jwkKey:t,iv:s,data:i}){const r={name:"AES-CTR",counter:s,length:64};let o;const c=e||t,l=t?"jwk":"raw";try{o=await Ie(this._subtleCrypto.importKey(l,c,r,!1,["encrypt"]),"importKey")}catch(h){throw new Error(`Could not import key for AES-CTR encryption: ${h.message}`)}try{const h=await Ie(this._subtleCrypto.encrypt(r,o,i),"encrypt");return new Uint8Array(h)}catch(h){throw new Error(`Could not encrypt with AES-CTR: ${h.message}`)}}async generateKey(e,t=256){const s=await Ie(this._subtleCrypto.generateKey({name:"AES-CTR",length:t},!0,["encrypt","decrypt"]));return Ie(this._subtleCrypto.exportKey(e,s))}async generateIV(){return $c(this._crypto)}}function $c(n){const e=n.getRandomValues(new Uint8Array(8)),t=new Uint8Array(16);for(let s=0;s{this._resolve=s,this._reject=i}),this._message=e,this._pool=t,this._worker=null}abort(){this._isNotDisposed&&(this._pool._abortRequest(this),this._dispose())}response(){return this._promise}_dispose(){this._reject=null,this._resolve=null}get _isNotDisposed(){return this._resolve&&this._reject}}class Ky{constructor(e,t){this._workers=[];for(let s=0;s{this._init={resolve:t,reject:s}});return this.sendAll({type:"ping"}).then(this._init.resolve,this._init.reject).finally(()=>{this._init=null}),e}handleEvent(e){if(e.type==="message"){const t=e.data,s=this._requests.get(t.replyToId);if(s){if(s._worker.busy=!1,s._isNotDisposed){if(t.type==="success")s._resolve(t.payload);else if(t.type==="error"){const i=new Error(t.message);i.stack=t.stack,s._reject(i)}s._dispose()}this._requests.delete(t.replyToId)}this._sendPending()}else e.type==="error"&&(this._init&&this._init.reject(new Error("worker error during init")),console.error("worker error",e))}_getPendingRequest(){for(const e of this._requests.values())if(!e._worker)return e}_getFreeWorker(){for(const e of this._workers)if(!e.busy)return e}_sendPending(){this._pendingFlag=!1;let e;do{e=!1;const t=this._getPendingRequest();if(t){const s=this._getFreeWorker();s&&(this._sendWith(t,s),e=!0)}}while(e)}_sendWith(e,t){e._worker=t,t.busy=!0,t.worker.postMessage(e._message)}_enqueueRequest(e){this._counter+=1,e.id=this._counter;const t=new Ly(e,this);return this._requests.set(e.id,t),t}send(e){const t=this._enqueueRequest(e),s=this._getFreeWorker();return s&&this._sendWith(t,s),t}sendAll(e){const t=this._workers.map(s=>{const i=this._enqueueRequest(Object.assign({},e));return this._sendWith(i,s),i.response()});return Promise.all(t)}dispose(){for(const e of this._workers)e.detach(this),e.worker.terminate()}_trySendPendingInNextTick(){this._pendingFlag||(this._pendingFlag=!0,Promise.resolve().then(()=>{this._sendPending()}))}_abortRequest(e){e._reject(new rt),e._worker&&(e._worker.busy=!1),this._requests.delete(e._message.id),this._trySendPendingInNextTick()}}class ji{static async fromBlob(e){const t=await zo(e),{width:s,height:i}=t;return new ji(e,s,i,t)}constructor(e,t,s,i){this.blob=e,this.width=t,this.height=s,this._domElement=i}get maxDimension(){return Math.max(this.width,this.height)}async _getDomElement(){return this._domElement||(this._domElement=await zo(this.blob)),this._domElement}async scale(e){const t=this.width/this.height,s=Math.min(1,e/(t>=1?this.width:this.height)),i=Math.round(this.width*s),r=Math.round(this.height*s),o=document.createElement("canvas");o.width=i,o.height=r;const c=o.getContext("2d"),l=await this._getDomElement();c.drawImage(l,0,0,i,r);let h=this.blob.mimeType==="image/jpeg"?"image/jpeg":"image/png",a;if(o.toBlob)a=await new Promise(p=>o.toBlob(p,h));else if(o.msToBlob)h="image/png",a=o.msToBlob();else throw new Error("canvas can't be turned into blob");const u=Ts.fromBlobUnsafe(a);return new ji(u,i,r,null)}dispose(){this.blob.dispose()}}class Bn extends ji{get duration(){if(typeof this._domElement.duration=="number")return Math.round(this._domElement.duration*1e3)}static async fromBlob(e){const t=await $y(e),{videoWidth:s,videoHeight:i}=t;return new Bn(e,s,i,t)}}function By(){const n=document.createElement("canvas");n.width=1,n.height=1;const e=n.getContext("2d"),t=[Math.round(Math.random()*255),Math.round(Math.random()*255),Math.round(Math.random()*255)];e.fillStyle=`rgb(${t[0]}, ${t[1]}, ${t[2]})`,e.fillRect(0,0,1,1);const s=e.getImageData(0,0,1,1).data;return s[0]===t[0]&&s[1]===t[1]&&s[2]===t[2]}async function zo(n){const e=document.createElement("img"),t=Tr(e,"load");return e.src=n.url,await t,e}async function $y(n){const e=document.createElement("video");e.muted=!0;const t=Tr(e,"loadedmetadata");e.src=n.url,e.load(),await t;const s=Tr(e,"seeked");return await new Promise(i=>setTimeout(i,200)),e.currentTime=.1,await s,e}async function jy(n,e,t,s,i){let r=n.querySelector("iframe.downloadSandbox");if(!r){r=document.createElement("iframe"),r.setAttribute("sandbox","allow-scripts allow-downloads allow-downloads-without-user-activation"),r.setAttribute("src",e),r.className="hidden downloadSandbox",n.appendChild(r);let o;await new Promise((c,l)=>{o=()=>{r.removeEventListener("load",c),r.removeEventListener("error",l)},r.addEventListener("load",c),r.addEventListener("error",l)}),o()}if(i){const o=await t.readAsBuffer();r.contentWindow.postMessage({type:"downloadBuffer",buffer:o,mimeType:t.mimeType,filename:s},"*")}else r.contentWindow.postMessage({type:"downloadBlob",blob:t.nativeBlob,filename:s},"*")}/*! @license DOMPurify 2.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.0/LICENSE */function qy(n){if(Array.isArray(n)){for(var e=0,t=Array(n.length);e1?t-1:0),i=1;i/gm),rw=Bt(/^data-[\-\w.\u00B7-\uFFFF]/),nw=Bt(/^aria-[\-\w]+$/),ow=Bt(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),aw=Bt(/^(?:\w+script|data):/i),cw=Bt(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),xi=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(n){return typeof n}:function(n){return n&&typeof Symbol=="function"&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n};function ut(n){if(Array.isArray(n)){for(var e=0,t=Array(n.length);e0&&arguments[0]!==void 0?arguments[0]:lw(),e=function(y){return qc(y)};if(e.version="2.3.0",e.removed=[],!n||!n.document||n.document.nodeType!==9)return e.isSupported=!1,e;var t=n.document,s=n.document,i=n.DocumentFragment,r=n.HTMLTemplateElement,o=n.Node,c=n.Element,l=n.NodeFilter,h=n.NamedNodeMap,a=h===void 0?n.NamedNodeMap||n.MozNamedAttrMap:h,u=n.Text,p=n.Comment,g=n.DOMParser,f=n.trustedTypes,v=c.prototype,M=mr(v,"cloneNode"),R=mr(v,"nextSibling"),N=mr(v,"childNodes"),F=mr(v,"parentNode");if(typeof r=="function"){var T=s.createElement("template");T.content&&T.content.ownerDocument&&(s=T.content.ownerDocument)}var D=hw(f,t),B=D&&us?D.createHTML(""):"",G=s,$e=G.implementation,Ns=G.createNodeIterator,di=G.createDocumentFragment,as=G.getElementsByTagName,cs=t.importNode,Ds={};try{Ds=zs(s).documentMode?s.documentMode:{}}catch{}var Ue={};e.isSupported=typeof F=="function"&&$e&&typeof $e.createHTMLDocument!="undefined"&&Ds!==9;var Us=sw,U=iw,zi=rw,Ht=nw,Wt=aw,ui=cw,Je=ow,re=null,Os=j({},[].concat(ut(Xo),ut(Wr),ut(zr),ut(Gr),ut(Zo))),ie=null,Ps=j({},[].concat(ut(ea),ut(Yr),ut(ta),ut(_r))),ls=null,hs=null,mi=!0,Fs=!0,_i=!1,vt=!1,zt=!1,Qe=!1,bt=!1,je=!1,ds=!1,we=!0,us=!1,pi=!0,gi=!0,St=!1,at={},Ls=j({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Xe=null,Gt=j({},["audio","video","img","source","image","track"]),Ks=null,Gi=j({},["alt","class","for","id","label","name","pattern","placeholder","summary","title","value","style","xmlns"]),Bs="http://www.w3.org/1998/Math/MathML",$s="http://www.w3.org/2000/svg",Ze="http://www.w3.org/1999/xhtml",kt=Ze,js=!1,ge=null,ve=s.createElement("form"),Te=function(y){ge&&ge===y||((!y||(typeof y=="undefined"?"undefined":xi(y))!=="object")&&(y={}),y=zs(y),re="ALLOWED_TAGS"in y?j({},y.ALLOWED_TAGS):Os,ie="ALLOWED_ATTR"in y?j({},y.ALLOWED_ATTR):Ps,Ks="ADD_URI_SAFE_ATTR"in y?j(zs(Gi),y.ADD_URI_SAFE_ATTR):Gi,Xe="ADD_DATA_URI_TAGS"in y?j(zs(Gt),y.ADD_DATA_URI_TAGS):Gt,ls="FORBID_TAGS"in y?j({},y.FORBID_TAGS):{},hs="FORBID_ATTR"in y?j({},y.FORBID_ATTR):{},at="USE_PROFILES"in y?y.USE_PROFILES:!1,mi=y.ALLOW_ARIA_ATTR!==!1,Fs=y.ALLOW_DATA_ATTR!==!1,_i=y.ALLOW_UNKNOWN_PROTOCOLS||!1,vt=y.SAFE_FOR_TEMPLATES||!1,zt=y.WHOLE_DOCUMENT||!1,je=y.RETURN_DOM||!1,ds=y.RETURN_DOM_FRAGMENT||!1,we=y.RETURN_DOM_IMPORT!==!1,us=y.RETURN_TRUSTED_TYPE||!1,bt=y.FORCE_BODY||!1,pi=y.SANITIZE_DOM!==!1,gi=y.KEEP_CONTENT!==!1,St=y.IN_PLACE||!1,Je=y.ALLOWED_URI_REGEXP||Je,kt=y.NAMESPACE||Ze,vt&&(Fs=!1),ds&&(je=!0),at&&(re=j({},[].concat(ut(Zo))),ie=[],at.html===!0&&(j(re,Xo),j(ie,ea)),at.svg===!0&&(j(re,Wr),j(ie,Yr),j(ie,_r)),at.svgFilters===!0&&(j(re,zr),j(ie,Yr),j(ie,_r)),at.mathMl===!0&&(j(re,Gr),j(ie,ta),j(ie,_r))),y.ADD_TAGS&&(re===Os&&(re=zs(re)),j(re,y.ADD_TAGS)),y.ADD_ATTR&&(ie===Ps&&(ie=zs(ie)),j(ie,y.ADD_ATTR)),y.ADD_URI_SAFE_ATTR&&j(Ks,y.ADD_URI_SAFE_ATTR),gi&&(re["#text"]=!0),zt&&j(re,["html","head","body"]),re.table&&(j(re,["tbody"]),delete ls.tbody),Ce&&Ce(y),ge=y)},Ae=j({},["mi","mo","mn","ms","mtext"]),ms=j({},["foreignobject","desc","title","annotation-xml"]),qe=j({},Wr);j(qe,zr),j(qe,ew);var He=j({},Gr);j(He,tw);var xe=function(y){var b=F(y);(!b||!b.tagName)&&(b={namespaceURI:Ze,tagName:"template"});var C=vs(y.tagName),O=vs(b.tagName);if(y.namespaceURI===$s)return b.namespaceURI===Ze?C==="svg":b.namespaceURI===Bs?C==="svg"&&(O==="annotation-xml"||Ae[O]):Boolean(qe[C]);if(y.namespaceURI===Bs)return b.namespaceURI===Ze?C==="math":b.namespaceURI===$s?C==="math"&&ms[O]:Boolean(He[C]);if(y.namespaceURI===Ze){if(b.namespaceURI===$s&&!ms[O]||b.namespaceURI===Bs&&!Ae[O])return!1;var oe=j({},["title","style","font","a","script"]);return!He[C]&&(oe[C]||!qe[C])}return!1},Ve=function(y){Mi(e.removed,{element:y});try{y.parentNode.removeChild(y)}catch{try{y.outerHTML=B}catch{y.remove()}}},Yt=function(y,b){try{Mi(e.removed,{attribute:b.getAttributeNode(y),from:b})}catch{Mi(e.removed,{attribute:null,from:b})}if(b.removeAttribute(y),y==="is"&&!ie[y])if(je||ds)try{Ve(b)}catch{}else try{b.setAttribute(y,"")}catch{}},We=function(y){var b=void 0,C=void 0;if(bt)y=""+y;else{var O=Jo(y,/^[\r\n\t ]+/);C=O&&O[0]}var oe=D?D.createHTML(y):y;if(kt===Ze)try{b=new g().parseFromString(oe,"text/html")}catch{}if(!b||!b.documentElement){b=$e.createDocument(kt,"template",null);try{b.documentElement.innerHTML=js?"":oe}catch{}}var he=b.body||b.documentElement;return y&&C&&he.insertBefore(s.createTextNode(C),he.childNodes[0]||null),kt===Ze?as.call(b,zt?"html":"body")[0]:zt?b.documentElement:he},Ne=function(y){return Ns.call(y.ownerDocument||y,y,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT,null,!1)},Z=function(y){return y instanceof u||y instanceof p?!1:typeof y.nodeName!="string"||typeof y.textContent!="string"||typeof y.removeChild!="function"||!(y.attributes instanceof a)||typeof y.removeAttribute!="function"||typeof y.setAttribute!="function"||typeof y.namespaceURI!="string"||typeof y.insertBefore!="function"},Y=function(y){return(typeof o=="undefined"?"undefined":xi(o))==="object"?y instanceof o:y&&(typeof y=="undefined"?"undefined":xi(y))==="object"&&typeof y.nodeType=="number"&&typeof y.nodeName=="string"},le=function(y,b,C){!Ue[y]||Jy(Ue[y],function(O){O.call(e,b,C,ge)})},be=function(y){var b=void 0;if(le("beforeSanitizeElements",y,null),Z(y)||Jo(y.nodeName,/[\u0080-\uFFFF]/))return Ve(y),!0;var C=vs(y.nodeName);if(le("uponSanitizeElement",y,{tagName:C,allowedTags:re}),!Y(y.firstElementChild)&&(!Y(y.content)||!Y(y.content.firstElementChild))&&Qt(/<[/\w]/g,y.innerHTML)&&Qt(/<[/\w]/g,y.textContent))return Ve(y),!0;if(!re[C]||ls[C]){if(gi&&!Ls[C]){var O=F(y)||y.parentNode,oe=N(y)||y.childNodes;if(oe&&O)for(var he=oe.length,d=he-1;d>=0;--d)O.insertBefore(M(oe[d],!0),R(y))}return Ve(y),!0}return y instanceof c&&!xe(y)||(C==="noscript"||C==="noembed")&&Qt(/<\/no(script|embed)/i,y.innerHTML)?(Ve(y),!0):(vt&&y.nodeType===3&&(b=y.textContent,b=Jt(b,Us," "),b=Jt(b,U," "),y.textContent!==b&&(Mi(e.removed,{element:y.cloneNode()}),y.textContent=b)),le("afterSanitizeElements",y,null),!1)},I=function(y,b,C){if(pi&&(b==="id"||b==="name")&&(C in s||C in ve))return!1;if(!(Fs&&!hs[b]&&Qt(zi,b))){if(!(mi&&Qt(Ht,b))){if(!ie[b]||hs[b])return!1;if(!Ks[b]){if(!Qt(Je,Jt(C,ui,""))){if(!((b==="src"||b==="xlink:href"||b==="href")&&y!=="script"&&Qy(C,"data:")===0&&Xe[y])){if(!(_i&&!Qt(Wt,Jt(C,ui,"")))){if(C)return!1}}}}}}return!0},K=function(y){var b=void 0,C=void 0,O=void 0,oe=void 0;le("beforeSanitizeAttributes",y,null);var he=y.attributes;if(!!he){var d={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:ie};for(oe=he.length;oe--;){b=he[oe];var m=b,_=m.name,w=m.namespaceURI;if(C=Xy(b.value),O=vs(_),d.attrName=O,d.attrValue=C,d.keepAttr=!0,d.forceKeepAttr=void 0,le("uponSanitizeAttribute",y,d),C=d.attrValue,!d.forceKeepAttr&&(Yt(_,y),!!d.keepAttr)){if(Qt(/\/>/i,C)){Yt(_,y);continue}vt&&(C=Jt(C,Us," "),C=Jt(C,U," "));var k=y.nodeName.toLowerCase();if(!!I(k,O,C))try{w?y.setAttributeNS(w,_,C):y.setAttribute(_,C),Yo(e.removed)}catch{}}}le("afterSanitizeAttributes",y,null)}},x=function S(y){var b=void 0,C=Ne(y);for(le("beforeSanitizeShadowDOM",y,null);b=C.nextNode();)le("uponSanitizeShadowNode",b,null),!be(b)&&(b.content instanceof i&&S(b.content),K(b));le("afterSanitizeShadowDOM",y,null)};return e.sanitize=function(S,y){var b=void 0,C=void 0,O=void 0,oe=void 0,he=void 0;if(js=!S,js&&(S=""),typeof S!="string"&&!Y(S)){if(typeof S.toString!="function")throw Qo("toString is not a function");if(S=S.toString(),typeof S!="string")throw Qo("dirty is not a string, aborting")}if(!e.isSupported){if(xi(n.toStaticHTML)==="object"||typeof n.toStaticHTML=="function"){if(typeof S=="string")return n.toStaticHTML(S);if(Y(S))return n.toStaticHTML(S.outerHTML)}return S}if(Qe||Te(y),e.removed=[],typeof S=="string"&&(St=!1),!St)if(S instanceof o)b=We(""),C=b.ownerDocument.importNode(S,!0),C.nodeType===1&&C.nodeName==="BODY"||C.nodeName==="HTML"?b=C:b.appendChild(C);else{if(!je&&!vt&&!zt&&S.indexOf("<")===-1)return D&&us?D.createHTML(S):S;if(b=We(S),!b)return je?null:B}b&&bt&&Ve(b.firstChild);for(var d=Ne(St?S:b);O=d.nextNode();)O.nodeType===3&&O===oe||be(O)||(O.content instanceof i&&x(O.content),K(O),oe=O);if(oe=null,St)return S;if(je){if(ds)for(he=di.call(b.ownerDocument);b.firstChild;)he.appendChild(b.firstChild);else he=b;return we&&(he=cs.call(t,he,!0)),he}var m=zt?b.outerHTML:b.innerHTML;return vt&&(m=Jt(m,Us," "),m=Jt(m,U," ")),D&&us?D.createHTML(m):m},e.setConfig=function(S){Te(S),Qe=!0},e.clearConfig=function(){ge=null,Qe=!1},e.isValidAttribute=function(S,y,b){ge||Te({});var C=vs(S),O=vs(y);return I(C,O,b)},e.addHook=function(S,y){typeof y=="function"&&(Ue[S]=Ue[S]||[],Mi(Ue[S],y))},e.removeHook=function(S){Ue[S]&&Yo(Ue[S])},e.removeHooks=function(S){Ue[S]&&(Ue[S]=[])},e.removeAllHooks=function(){Ue={}},e}var dw=qc();class uw{constructor(e){this._bodyNode=e}get rootNodes(){return Array.from(this._bodyNode.childNodes)}getChildNodes(e){return Array.from(e.childNodes)}getAttributeNames(e){return Array.from(e.getAttributeNames())}getAttributeValue(e,t){return e.getAttribute(t)}isTextNode(e){return e.nodeType===Node.TEXT_NODE}getNodeText(e){return e.textContent}isElementNode(e){return e.nodeType===Node.ELEMENT_NODE}getNodeElementName(e){return e.tagName}}const mw={ALLOWED_URI_REGEXP:/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx|mxc):|[^a-z]|[a-z+.-]+(?:[^a-z+.-:]|$))/i,FORBID_TAGS:["mx-reply"],KEEP_CONTENT:!1};function _w(n){const e=dw.sanitize(n,mw),t=new DOMParser().parseFromString(`${e}`,"text/html").body;return new uw(t)}const pw=200,gw=-60,fw=8;class yw{constructor(e){this.mediaDevices=e}enumerate(){return this.mediaDevices.enumerateDevices()}async getMediaTracks(e,t){const s=await this.mediaDevices.getUserMedia(this.getUserMediaContraints(e,t));return s.addEventListener("removetrack",i=>{console.log(`removing track ${i.track.id} (${i.track.kind}) from stream ${s.id}`)}),s}async getScreenShareTrack(){return await this.mediaDevices.getDisplayMedia(this.getScreenshareContraints())}getUserMediaContraints(e,t){const s=!!navigator.webkitGetUserMedia;return{audio:e?{deviceId:typeof e!="boolean"?{ideal:e.deviceId}:void 0}:!1,video:t?{deviceId:typeof t!="boolean"?{ideal:t.deviceId}:void 0,width:s?{exact:640}:{ideal:640},height:s?{exact:360}:{ideal:360}}:!1}}getScreenshareContraints(){return{audio:!1,video:!0}}createVolumeMeasurer(e,t){return new ww(e,t)}}class ww{constructor(e,t){this.measuringVolumeActivity=!1,this.speakingThreshold=gw,this.speaking=!1,this.volumeLooper=()=>{if(!this.analyser||!this.measuringVolumeActivity)return;this.analyser.getFloatFrequencyData(this.frequencyBinCount);let s=-1/0;for(let r=0;rs&&(s=this.frequencyBinCount[r]);this.speakingVolumeSamples.shift(),this.speakingVolumeSamples.push(s),this.callback();let i=!1;for(let r=0;rthis.speakingThreshold){i=!0;break}this.speaking!==i&&(this.speaking=i,this.callback()),this.volumeLooperTimeout=setTimeout(this.volumeLooper,pw)},this.stream=e,this.callback=t,this.speakingVolumeSamples=new Array(fw).fill(-1/0),this.initVolumeMeasuring(),this.measureVolumeActivity(!0)}get isSpeaking(){return this.speaking}measureVolumeActivity(e){if(e){if(!this.audioContext||!this.analyser||!this.frequencyBinCount)return;this.measuringVolumeActivity=!0,this.volumeLooper()}else this.measuringVolumeActivity=!1,this.speakingVolumeSamples.fill(-1/0),this.callback()}initVolumeMeasuring(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return;this.audioContext=new e,this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=512,this.analyser.smoothingTimeConstant=.1,this.audioContext.createMediaStreamSource(this.stream).connect(this.analyser),this.frequencyBinCount=new Float32Array(this.analyser.frequencyBinCount)}setSpeakingThreshold(e){this.speakingThreshold=e}stop(){var e;clearTimeout(this.volumeLooperTimeout),this.analyser.disconnect(),(e=this.audioContext)==null||e.close()}}class vw{createPeerConnection(e,t,s){const i=new RTCPeerConnection({iceTransportPolicy:e?"relay":void 0,iceServers:t,iceCandidatePoolSize:s});return new Proxy(i,{get(r,o,c){o==="close"&&console.trace("calling peerConnection.close");const l=r[o];return typeof l=="function"?l.bind(r):l}})}prepareSenderForPurpose(e,t,s){s===Zt.Screenshare&&this.getRidOfRTXCodecs(e,t)}getRidOfRTXCodecs(e,t){var c,l,h,a,u,p;if(!RTCRtpReceiver.getCapabilities||!RTCRtpSender.getCapabilities)return;const s=(l=(c=RTCRtpReceiver.getCapabilities("video"))==null?void 0:c.codecs)!=null?l:[],r=[...(a=(h=RTCRtpSender.getCapabilities("video"))==null?void 0:h.codecs)!=null?a:[],...s];for(const g of r)if(g.mimeType==="video/rtx"){const f=r.indexOf(g);r.splice(f,1)}const o=e.getTransceivers().find(g=>g.sender===t);o&&(((u=o.sender.track)==null?void 0:u.kind)==="video"||((p=o.receiver.track)==null?void 0:p.kind)==="video")&&o.setCodecPreferences(r)}}var es=(n=>(n[n.Dark=0]="Dark",n[n.Light=1]="Light",n))(es||{});function bw(n,e,t){let s=n.replaceAll("#ff00ff",e);if(s=s.replaceAll("#00ffff",t),n===s)throw new Error("svg-colorizer made no color replacements! The input svg should only contain colors #ff00ff (primary, case-sensitive) and #00ffff (secondary, case-sensitive).");return s}class Sw{constructor(e,t,s,i){this._platform=e,this._iconVariables=t,this._resolvedVariables=s,this._manifestLocation=i}async toVariables(){const{parsedStructure:e,promises:t}=await this._fetchAndParseIcons();return await Promise.all(t),this._produceColoredIconVariables(e)}async _fetchAndParseIcons(){const e=[],t={};for(const[s,i]of Object.entries(this._iconVariables)){const r=new URL(`https://${i}`),o=r.hostname,c=new URL(o,new URL(this._manifestLocation,window.location.origin)),l=this._platform.request(c,{method:"GET",format:"text",cache:!0}).response();e.push(l);const h=r.searchParams;t[s]={svg:l,primary:h.get("primary"),secondary:h.get("secondary")}}return{parsedStructure:t,promises:e}}async _produceColoredIconVariables(e){let t={};for(const[s,{svg:i,primary:r,secondary:o}]of Object.entries(e)){const{body:c}=await i;if(!r)throw new Error(`Primary color variable ${r} not in list of variables!`);const l=this._resolvedVariables[r],h=this._resolvedVariables[o],a=bw(c,l,h),u=`url('data:image/svg+xml;utf8,${encodeURIComponent(a)}')`;t[s]=u}return t}}var Or={exports:{}},kw=function(n){var e={};function t(s){if(e[s])return e[s].exports;var i=e[s]={i:s,l:!1,exports:{}};return n[s].call(i.exports,i,i.exports,t),i.l=!0,i.exports}return t.m=n,t.c=e,t.d=function(s,i,r){t.o(s,i)||Object.defineProperty(s,i,{enumerable:!0,get:r})},t.r=function(s){typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(s,"__esModule",{value:!0})},t.t=function(s,i){if(1&i&&(s=t(s)),8&i||4&i&&typeof s=="object"&&s&&s.__esModule)return s;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:s}),2&i&&typeof s!="string")for(var o in s)t.d(r,o,function(c){return s[c]}.bind(null,o));return r},t.n=function(s){var i=s&&s.__esModule?function(){return s.default}:function(){return s};return t.d(i,"a",i),i},t.o=function(s,i){return Object.prototype.hasOwnProperty.call(s,i)},t.p="",t(t.s=0)}([function(n,e,t){function s(h){let a,u;const p={light:function(){return!f()},dark:f,lighten:R,darken:M,saturate:N,desaturate:function(T=0){return N(T*=-1)},increaseContrast:function(T=0){return F(T*=-1)},decreaseContrast:F,active:function(){return F(.123)},highlight:function(){return F(.1)},selected:function(){return F(.066)},text:function(){return u=v()?i("#333333"):i("#FFFFFF"),p},shadow:function(){return u=v()?i("#000000"):i("#FFFFFF"),p},hex:function(){const T=u;return u=a,"#"+T.map(D=>parseInt(D+"",10).toString(16).padStart(2,"0")).join("")},rgb:function(){const T=u;return u=a,`rgb(${T.join()})`},rgba:function(T=1){const D=u;return u=a,`rgba(${D.join()}, ${T})`},setHex:g,setRgb:function(T=[0,0,0]){let[D,B,G]=T;return D=l(D,0,255),B=l(B,0,255),G=l(G,0,255),a=[D,B,G],u=[D,B,G],p}};function g(T="#000000"){return a=i(T),u=a,p}function f(){const[T,D,B]=u;return u=a,(299*T+587*D+114*B)/1e3<128}function v(){const[T,D,B]=u;return(299*T+587*D+114*B)/1e3>=128}function M(T=0){return R(T*=-1)}function R(T=0){let[D,B,G]=c(u);return G=l(G+T,0,1),u=r([D,B,G]),p}function N(T=0){let[D,B,G]=c(u);return B=l(B+T,0,1),u=r([D,B,G]),p}function F(T=0){return v()?M(T):R(T)}return g(h),p}function i(h){if(typeof h!="string")throw new TypeError("Expected a string");(h=h.replace(/^#/,"")).length===3&&(h=h[0]+h[0]+h[1]+h[1]+h[2]+h[2]);var a=parseInt(h,16);return[a>>16,a>>8&255,255&a]}function r(h){const[a,u,p]=h;let g,f,v;if(u===0)g=f=v=p;else{const M=function(F,T,D){return D<0&&(D+=1),D>1&&(D-=1),D<.16666666666666666?F+6*(T-F)*D:D<.5?T:D<.6666666666666666?F+(T-F)*(.6666666666666666-D)*6:F},R=p<.5?p*(1+u):p+u-p*u,N=2*p-R;g=l(M(N,R,a+1/3),0,1),f=l(M(N,R,a),0,1),v=l(M(N,R,a-1/3),0,1)}return[Math.round(255*g),Math.round(255*f),Math.round(255*v)]}t.r(e),t.d(e,"offColor",function(){return s}),t.d(e,"hexRgb",function(){return i}),t.d(e,"hslToRgb",function(){return r}),t.d(e,"color",function(){return o}),t.d(e,"rgbToHsl",function(){return c});const o=s;function c(h){const a=h[0]/255,u=h[1]/255,p=h[2]/255,g=Math.max(a,u,p),f=Math.min(a,u,p);let v=(g+f)/2,M=(g+f)/2;const R=(g+f)/2;if(g===f)v=M=0;else{const N=g-f;switch(M=R>.5?N/(2-g-f):N/(g+f),g){case a:v=(u-p)/N+(u=a?h:a}}]);Or.exports=kw;var Hc=Or.exports,ra;const Jr=(ra=Or.exports.offColor)!=null?ra:Hc.offColor;function sa(n,e,t,s){const i=parseInt(t);switch(s&&(e==="darker"?e="lighter":e==="lighter"&&(e="darker")),e){case"darker":return Jr(n).darken(i/100).hex();case"lighter":return Jr(n).lighten(i/100).hex();case"alpha":return Jr(n).rgba(i/100)}}class Iw{constructor(e,t,s){this._aliases={},this._derivedAliases=[],this._baseVariables=e,this._variablesToDerive=t,this._isDark=s}toVariables(){var t;const e={};this._detectAliases();for(const s of this._variablesToDerive){const i=this._derive(s);i&&(e[s]=i)}for(const[s,i]of Object.entries(this._aliases))e[s]=(t=this._baseVariables[i])!=null?t:e[i];for(const s of this._derivedAliases){const i=this._deriveAlias(s,e);i&&(e[s]=i)}return e}_detectAliases(){const e=[];for(const t of this._variablesToDerive){const[s,i]=t.split("=");i?this._aliases[s]=i:e.push(t)}this._variablesToDerive=e}_derive(e){const t=/(.+)--(.+)-(.+)/,s=e.match(t);if(s){const[,i,r,o]=s,c=this._baseVariables[i];if(!c)if(this._aliases[i]){this._derivedAliases.push(e);return}else throw new Error(`Cannot find value for base variable "${i}"!`);return sa(c,r,o,this._isDark)}}_deriveAlias(e,t){const s=/(.+)--(.+)-(.+)/,i=e.match(s);if(i){const[,r,o,c]=i,l=t[r];if(!l)throw new Error(`Cannot find value for alias "${r}" when trying to derive ${e}!`);return sa(l,o,c,this._isDark)}}}var na;(na=Or.exports.offColor)!=null||Hc.offColor;class Mw{constructor(e,t){this._themeMapping={},this._preferredColorScheme=t,this._platform=e}async parse(e,t,s,i){await i.wrap("RuntimeThemeParser.parse",async()=>{var u;const{cssLocation:r,derivedVariables:o,icons:c}=this._getSourceData(t,s,i),l=e.name;if(!l)throw new Error("Theme name not found in manifest!");let h={},a={};for(const[p,g]of Object.entries((u=e.values)==null?void 0:u.variants))try{const f=`${e.id}-${p}`,{name:v,default:M,dark:R,variables:N}=g,F=new Iw(N,o,R).toVariables();Object.assign(N,F);const T=await new Sw(this._platform,c,N,s).toVariables();Object.assign(N,F,T);const D=`${l} ${v}`;if(M){Object.assign(R?h:a,{variantName:v,id:f,cssLocation:r,variables:N});continue}this._themeMapping[D]={cssLocation:r,id:f,variables:N}}catch(f){console.error(f);continue}if(h.id&&a.id){const p=this._preferredColorScheme===es.Dark?h:a;this._themeMapping[l]={dark:h,light:a,default:p}}else{const p=h.id?h:a;this._themeMapping[`${l} ${p.variantName}`]={id:p.id,cssLocation:p.cssLocation}}})}_getSourceData(e,t,s){return s.wrap("getSourceData",()=>{var l,h,a;const i=(l=e.source)==null?void 0:l["runtime-asset"];if(!i)throw new Error(`Run-time asset not found in source section for theme at ${t}`);const r=new URL(i,new URL(t,window.location.origin)).href,o=(h=e.source)==null?void 0:h["derived-variables"];if(!o)throw new Error(`Derived variables not found in source section for theme at ${t}`);const c=(a=e.source)==null?void 0:a.icon;if(!c)throw new Error(`Icon mapping not found in source section for theme at ${t}`);return{cssLocation:r,derivedVariables:o,icons:c}})}get themeMapping(){return this._themeMapping}}class Cw{constructor(e){this._themeMapping={},this._preferredColorScheme=e}parse(e,t,s){s.wrap("BuiltThemeParser.parse",()=>{var l,h,a;const i=(l=e.source)==null?void 0:l["built-assets"],r=e.name;if(!r)throw new Error(`Theme name not found in manifest at ${t}`);let o={},c={};for(let[u,p]of Object.entries(i)){try{p=new URL(p,new URL(t,window.location.origin)).href}catch{continue}const g=(h=u.match(/.+-(.+)/))==null?void 0:h[1],f=(a=e.values)==null?void 0:a.variants[g];if(!f)throw new Error(`Variant ${g} is missing in manifest at ${t}`);const{name:v,default:M,dark:R}=f,N=`${r} ${v}`;if(M){const F=R?o:c;F.variantName=v,F.id=u,F.cssLocation=p;continue}this._themeMapping[N]={cssLocation:p,id:u}}if(o.id&&c.id){const u=this._preferredColorScheme===es.Dark?o:c;this._themeMapping[r]={dark:o,light:c,default:u}}else{const u=o.id?o:c;this._themeMapping[`${r} ${u.variantName}`]={id:u.id,cssLocation:u.cssLocation}}})}get themeMapping(){return this._themeMapping}}class Ew{constructor(e){this._platform=e}async init(e,t){await this._platform.logger.wrapOrRun(t,"ThemeLoader.init",async s=>{let i=!0;const r=[],o=[],c=await Promise.all(e.map(u=>this._platform.request(u,{method:"GET",format:"json",cache:!0}).response())),l=new Mw(this._platform,this.preferredColorScheme),h=new Cw(this.preferredColorScheme),a=[];for(let u=0;u=200&&g<=299)){console.error(`Failed to load manifest at ${e[u]}, status: ${g}`),s.log({l:"Manifest fetch failed",location:e[u],status:g},Ge.Error),r.push(e[u]);continue}i=!1;try{if(f.extends){const v=c.findIndex(F=>"value"in F&&F.value.body.id===f.extends);if(v===-1)throw new Error(`Base manifest for derived theme at ${e[u]} not found!`);const{body:M}=c[v].value,R=e[v],N=l.parse(f,M,R,s);a.push(N)}else h.parse(f,e[u],s)}catch(v){console.error(v),o.push(v.message)}}if(await Promise.all(a),this._themeMapping=It(It({},h.themeMapping),l.themeMapping),i)throw new Error(`All configured theme manifests failed to load, the following were tried: ${r.join(", ")}`);if(Object.keys(this._themeMapping).length===0&&o.length)throw new Error(`Failed to parse theme manifests, the following errors were encountered: ${o.join(", ")}`);this._addDefaultThemeToMapping(s),s.log({l:"Preferred colorscheme",scheme:this.preferredColorScheme===es.Dark?"dark":"light"}),s.log({l:"Result",themeMapping:this._themeMapping})})}async setTheme(e,t,s){await this._platform.logger.wrapOrRun(s,{l:"change theme",name:e,variant:t},async i=>{let r,o,c=this._themeMapping[e];if("id"in c)r=c.cssLocation,o=c.variables;else{if(!t)throw new Error("themeVariant is undefined!");r=c[t].cssLocation,o=c[t].variables}await this._platform.replaceStylesheet(r,i),o?(s==null||s.log({l:"Derived Theme",variables:o}),this._injectCSSVariables(o)):this._removePreviousCSSVariables(),this._platform.settingsStorage.setString("theme-name",e),t?this._platform.settingsStorage.setString("theme-variant",t):this._platform.settingsStorage.remove("theme-variant")})}_injectCSSVariables(e){const t=document.documentElement;for(const[s,i]of Object.entries(e))t.style.setProperty(`--${s}`,i);this._injectedVariables=e}_removePreviousCSSVariables(){if(!this._injectedVariables)return;const e=document.documentElement;for(const t of Object.keys(this._injectedVariables))e.style.removeProperty(`--${t}`);this._injectedVariables=void 0}get themeMapping(){return this._themeMapping}async getActiveTheme(){let e=await this._platform.settingsStorage.getString("theme-name"),t=await this._platform.settingsStorage.getString("theme-variant");return(!e||!this._themeMapping[e])&&(e="Default"in this._themeMapping?"Default":Object.keys(this._themeMapping)[0],this._themeMapping[e][t]||(t="default"in this._themeMapping[e]?"default":void 0)),{themeName:e,themeVariant:t}}getDefaultTheme(){var e,t;switch(this.preferredColorScheme){case es.Dark:return(e=this._platform.config.defaultTheme)==null?void 0:e.dark;case es.Light:return(t=this._platform.config.defaultTheme)==null?void 0:t.light}}_findThemeDetailsFromId(e){var t,s;for(const[i,r]of Object.entries(this._themeMapping)){if("id"in r&&r.id===e)return{themeName:i,themeData:r};if("light"in r&&((t=r.light)==null?void 0:t.id)===e)return{themeName:i,themeData:r.light};if("dark"in r&&((s=r.dark)==null?void 0:s.id)===e)return{themeName:i,themeData:r.dark}}}_addDefaultThemeToMapping(e){e.wrap("addDefaultThemeToMapping",t=>{const s=this.getDefaultTheme();if(s){const i=this._findThemeDetailsFromId(s);if(i){this._themeMapping.Default={id:"default",cssLocation:i.themeData.cssLocation};const r=i.themeData.variables;r&&(this._themeMapping.Default.variables=r)}}t.log({l:"Default Theme",theme:s})})}get preferredColorScheme(){if(window.matchMedia("(prefers-color-scheme: dark)").matches)return es.Dark;if(window.matchMedia("(prefers-color-scheme: light)").matches)return es.Light}}var Wc=(n=>(n[n.Minute=6e4]="Minute",n[n.Hours=36e5]="Hours",n[n.Day=864e5]="Day",n))(Wc||{});function Rw(n){let e=0,t=0,s=0;n>=864e5&&(e=Math.floor(n/864e5),n-=e*864e5),n>=36e5&&(t=Math.floor(n/36e5),n-=t*36e5),n>=6e4&&(s=Math.floor(n/6e4),n-=s*6e4);const i=Math.floor(n/1e3);let r="";return e&&(r=`${e}d `),(t||e)&&(r+=`${t}h `),(s||t||e)&&(r+=`${s}m `),r+=`${i}s`,r}class Tw{constructor(e){this.clock=e,this.todayMidnight=new Date,this.todayMidnight.setHours(0,0,0,0),this.relativeDayFormatter=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"}),this.weekdayFormatter=new Intl.DateTimeFormat(void 0,{weekday:"long"}),this.currentYearFormatter=new Intl.DateTimeFormat(void 0,{weekday:"long",month:"long",day:"numeric"}),this.otherYearFormatter=new Intl.DateTimeFormat(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"}),this.timeFormatter=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"2-digit"})}formatTime(e){return this.timeFormatter.format(e)}formatMachineReadableDate(e){return`${e.getFullYear()}-${e.getMonth()+1}-${e.getDate()}`}formatRelativeDate(e){let t=Math.floor((e.getTime()-this.todayMidnight.getTime())/Wc.Day);return t>=-1&&t<=1?Aw(this.relativeDayFormatter.format(t,"day")):t>-7&&t<0?this.weekdayFormatter.format(e):this.todayMidnight.getFullYear()===e.getFullYear()?this.currentYearFormatter.format(e):this.otherYearFormatter.format(e)}formatDuration(e){return Rw(e)}}function Aw(n){return n.slice(0,1).toLocaleUpperCase()+n.slice(1)}function ia(n){return new Promise(function(e,t){var s=document.createElement("script");s.setAttribute("src",n),s.onload=e,s.onerror=t,document.body.appendChild(s)})}async function xw(n){return window.msCrypto&&!window.crypto&&(window.crypto=window.msCrypto),n?(window.WebAssembly?(await ia(n.wasmBundle),await window.Olm.init({locateFile:()=>n.wasm})):(await ia(n.legacyBundle),await window.Olm.init()),window.Olm):null}function Vw(n){return n.startsWith("/")?n:new URL(n,document.location.href).pathname}async function Nw(n){const e=new Ky(n.worker,4);return await e.init(),await e.sendAll({type:"load_olm",path:Vw(n.olm.legacyBundle)}),new kg(e)}function Dw(n){if(!window.visualViewport)return;const e=()=>{const t=n.querySelector(".SessionView");if(!t)return;const s=n.querySelector(".bottom-aligned-scroll");let i,r,o;s&&(i=s.scrollTop,r=s.offsetHeight);const c=t.offsetTop+t.offsetHeight-window.visualViewport.height;n.style.setProperty("--ios-viewport-height",window.visualViewport.height.toString()+"px"),n.style.setProperty("--ios-viewport-top",c.toString()+"px"),s&&(o=s.offsetHeight,s.scrollTop=i+r-o)};return window.visualViewport.addEventListener("resize",e),()=>{window.visualViewport.removeEventListener("resize",e)}}class Uw{constructor({container:e,assetPaths:t,config:s,configURL:i,logger:r,options:o=null,cryptoExtras:c=null}){this._container=e,this._assetPaths=t,this._config=s,this._configURL=i,this.settingsStorage=new ug("hydrogen_setting_v1_"),this.clock=new Iy,this.encoding=new Sg,this.random=Math.random,this.logger=r!=null?r:this._createLogger(o==null?void 0:o.development),this.history=new Ey,this.onlineStatus=new Ry,this.timeFormatter=new Tw,this._serviceWorkerHandler=null,this.sessionInfoStorage=new dg("hydrogen_sessions_v1"),t.serviceWorker&&"serviceWorker"in navigator&&(this._serviceWorkerHandler=new My(this.sessionInfoStorage),this._serviceWorkerHandler.registerAndStart(t.serviceWorker)),this.notificationService=void 0,this._assetPaths.olm&&(this.crypto=new Oy(c)),this.storageFactory=new zd(this._serviceWorkerHandler),this.estimateStorageUsage=Py,typeof fetch=="function"?this.request=hg(this.clock.createTimeout,this._serviceWorkerHandler):this.request=bc;const l=!!window.MSInputMethodContext&&!!document.documentMode;this.isIE11=l;const h=/iPad|iPhone|iPod/.test(navigator.platform)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1&&!window.MSStream;this.isIOS=h,this._disposables=new li,this._olmPromise=void 0,this._workerPromise=void 0,this.mediaDevices=new yw(navigator.mediaDevices),this.webRTC=new vw,this._themeLoader=new Ew(this)}async init(){try{await this.logger.run("Platform init",async e=>{var t;if(!this._config){if(!this._configURL)throw new Error("Neither config nor configURL was provided!");const{status:s,body:i}=await this.request(this._configURL,{method:"GET",format:"json",cache:!0}).response();if(s===404)throw new Error(`Could not find ${this._configURL}. Did you copy over config.sample.json?`);if(s>=400)throw new Error(`Got status ${s} while trying to fetch ${this._configURL}`);this._config=i}if(this.notificationService=new Cy(this._serviceWorkerHandler,this._config.push),this._themeLoader){const s=this.config.themeManifests;await((t=this._themeLoader)==null?void 0:t.init(s,e));const{themeName:i,themeVariant:r}=await this._themeLoader.getActiveTheme();e.log({l:"Active theme",name:i,variant:r}),await this._themeLoader.setTheme(i,r,e)}})}catch(e){throw this._container.innerText=e.message,e}}_createLogger(e){const t=new Ag({platform:this}),s=r=>{var o;return(o=r.e)!=null&&o.stack&&(r.e.stack=r.e.stack.replace(/\/\?loginToken=(.+)/,"?loginToken=")),r},i=new Ig({name:"hydrogen_logs",platform:this,serializedTransformer:s});return t.addReporter(i),e&&t.addReporter(new Cg),t}get updateService(){return this._serviceWorkerHandler}loadOlm(){return this._olmPromise||(this._olmPromise=xw(this._assetPaths.olm)),this._olmPromise}get config(){return this._config}async loadOlmWorker(){if(!window.WebAssembly)return this._workerPromise||(this._workerPromise=Nw(this._assetPaths)),this._workerPromise}createAndMountRootView(e){if(this.isIE11&&(this._container.className+=" legacy"),this.isIOS){this._container.className+=" ios";const s=Dw(this._container);s&&this._disposables.track(s)}this._container.addEventListener("error",$o,!0),this._disposables.track(()=>this._container.removeEventListener("error",$o,!0)),window.__hydrogenViewModel=e;const t=new vy(e);this._container.appendChild(t.mount())}setNavigation(e){var t;(t=this._serviceWorkerHandler)==null||t.setNavigation(e)}createBlob(e,t){return Ts.fromBuffer(e,t)}saveFileAs(e,t){navigator.msSaveBlob?navigator.msSaveBlob(e.nativeBlob,t):jy(this._container,this._assetPaths.downloadSandbox,e,t,this.isIOS)}async copyPlaintext(e){return await jf(e)}restart(){document.location.reload()}openFile(e=null){const t=document.createElement("input");t.setAttribute("type","file"),t.className="hidden",e&&t.setAttribute("accept",e);const s=new Promise(i=>{const r=()=>{t.removeEventListener("change",r,!0);const o=t.files[0];this._container.removeChild(t),o?i({name:o.name,blob:Ts.fromBlobUnsafe(o)}):i()};t.addEventListener("change",r,!0)});return this._container.appendChild(t),t.click(),s}openUrl(e){location.href=e}parseHTML(e){return _w(e)}async loadImage(e){return ji.fromBlob(e)}async loadVideo(e){return Bn.fromBlob(e)}hasReadPixelPermission(){return By()}get devicePixelRatio(){return window.devicePixelRatio||1}get version(){return"0.5.1"}get themeLoader(){return this._themeLoader}async replaceStylesheet(e,t){const s=await this.logger.wrapOrRun(t,{l:"replaceStylesheet",location:e},async i=>{let r;const o=document.querySelector("head");document.querySelectorAll(".theme").forEach(h=>h.remove());const c=document.createElement("link");c.href=e,c.rel="stylesheet",c.type="text/css",c.className="theme";const l=new Promise(h=>{c.onerror=()=>{r=new Error(`Failed to load stylesheet from ${e}`),i.catch(r),h()},c.onload=()=>{h()}});return o.appendChild(c),await l,r});if(s)throw s}get description(){var e;return"web-"+((e=navigator.userAgent)!=null?e:"")}dispose(){this._disposables.dispose()}}var Ow="./config.json",Pw="./assets/download-sandbox.48a866e9.html",Fw="./assets/main.bdb9a925.js",Lw="./assets/olm.3fc8dbfe.wasm",Kw="./assets/olm.cf9a793b.js",Bw="./assets/olm_legacy.bc22f405.js",zc={downloadSandbox:Pw,worker:Fw,olm:{wasm:Lw,legacyBundle:Bw,wasmBundle:Kw}};zc.serviceWorker="sw.js";const $w=new Uw({container:document.body,assetPaths:zc,configURL:Ow,options:{development:!1}});ng($w); +//# sourceMappingURL=index.e65aa065.js.map diff --git a/hydrogen/assets/index.e65aa065.js.map b/hydrogen/assets/index.e65aa065.js.map new file mode 100644 index 0000000..dc31a12 --- /dev/null +++ b/hydrogen/assets/index.e65aa065.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.e65aa065.js","sources":["../../src/utils/enum.ts","../../src/matrix/well-known.js","../../src/utils/EventEmitter.ts","../../src/utils/AbortableOperation.ts","../../src/utils/error.ts","../../src/observable/BaseObservable.ts","../../src/observable/value/BaseObservableValue.ts","../../src/observable/value/EventObservableValue.ts","../../src/observable/value/ObservableValue.ts","../../src/observable/value/FlatMapObservableValue.ts","../../src/observable/value/PickMapObservableValue.ts","../../src/observable/value/RetainedObservableValue.ts","../../src/observable/list/BaseObservableList.ts","../../src/utils/sortedIndex.ts","../../src/observable/list/ObservableArray.ts","../../src/observable/list/common.ts","../../src/observable/list/SortedArray.ts","../../src/observable/list/BaseMappedList.ts","../../src/observable/list/AsyncMappedList.ts","../../src/observable/list/ConcatList.ts","../../src/observable/list/SortedMapList.js","../../src/observable/map/BaseObservableMap.ts","../../src/observable/map/ApplyMap.ts","../../src/observable/map/FilteredMap.ts","../../src/observable/map/JoinedMap.ts","../../src/observable/map/MappedMap.ts","../../src/observable/map/ObservableMap.ts","../../src/observable/map/ObservableValueMap.ts","../../src/observable/value/MapSizeObservableValue.ts","../../src/platform/web/dom/BlobHandle.js","../../src/matrix/net/common.ts","../../src/matrix/error.js","../../src/matrix/net/HomeServerRequest.ts","../../src/matrix/net/HomeServerApi.ts","../../src/matrix/net/ExponentialRetryDelay.ts","../../src/matrix/net/Reconnector.ts","../../src/matrix/e2ee/attachment.js","../../src/matrix/net/MediaRepository.ts","../../src/matrix/net/RequestScheduler.ts","../../src/matrix/Sync.js","../../node_modules/another-json/another-json.js","../../src/matrix/e2ee/common.ts","../../src/matrix/room/common.ts","../../src/matrix/room/RoomSummary.js","../../src/matrix/storage/common.ts","../../src/matrix/room/timeline/EventKey.ts","../../src/matrix/room/timeline/entries/BaseEntry.ts","../../src/matrix/room/timeline/relations.js","../../src/matrix/room/timeline/PendingAnnotation.js","../../src/matrix/room/timeline/entries/reply.js","../../src/matrix/room/timeline/entries/BaseEventEntry.js","../../src/matrix/room/timeline/entries/PendingEventEntry.js","../../src/utils/Deferred.ts","../../src/matrix/room/sending/PendingEvent.js","../../src/matrix/room/timeline/entries/EventEntry.js","../../src/matrix/room/timeline/persistence/common.js","../../src/matrix/room/members/RoomMember.js","../../src/matrix/room/timeline/common.js","../../src/matrix/room/timeline/FragmentIdComparer.js","../../vite/preload-helper","../../src/matrix/storage/idb/error.ts","../../src/matrix/storage/idb/utils.ts","../../src/matrix/storage/idb/QueryTarget.ts","../../src/matrix/storage/idb/Store.ts","../../src/utils/typedJSON.ts","../../src/matrix/storage/idb/stores/SessionStore.ts","../../src/matrix/storage/idb/stores/RoomSummaryStore.ts","../../src/matrix/storage/idb/stores/InviteStore.ts","../../src/logging/LogFilter.ts","../../src/logging/NullLogger.ts","../../src/matrix/storage/idb/stores/TimelineEventStore.ts","../../src/matrix/storage/idb/stores/common.ts","../../src/matrix/storage/idb/stores/TimelineRelationStore.ts","../../src/matrix/storage/idb/stores/RoomStateStore.ts","../../src/matrix/storage/idb/stores/RoomMemberStore.ts","../../src/matrix/storage/idb/stores/TimelineFragmentStore.ts","../../src/matrix/storage/idb/stores/PendingEventStore.ts","../../src/matrix/storage/idb/stores/UserIdentityStore.ts","../../src/matrix/storage/idb/stores/DeviceKeyStore.ts","../../src/matrix/storage/idb/stores/CrossSigningKeyStore.ts","../../src/matrix/storage/idb/stores/OlmSessionStore.ts","../../src/matrix/storage/idb/stores/InboundGroupSessionStore.ts","../../src/matrix/storage/idb/stores/OutboundGroupSessionStore.ts","../../src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts","../../src/matrix/storage/idb/stores/OperationStore.ts","../../src/matrix/storage/idb/stores/AccountDataStore.ts","../../src/matrix/storage/idb/stores/CallStore.ts","../../src/matrix/storage/idb/stores/SharedSecretStore.ts","../../src/matrix/storage/idb/Transaction.ts","../../src/matrix/storage/idb/Storage.ts","../../src/matrix/storage/idb/export.ts","../../src/matrix/verification/common.ts","../../src/matrix/verification/SAS/stages/BaseSASVerificationStage.ts","../../src/matrix/verification/SAS/channel/types.ts","../../src/matrix/verification/SAS/stages/constants.ts","../../src/matrix/verification/SAS/generator.ts","../../src/matrix/verification/SAS/mac.ts","../../src/matrix/verification/SAS/stages/SendDoneStage.ts","../../src/matrix/verification/SAS/stages/VerifyMacStage.ts","../../src/matrix/verification/SAS/stages/SendMacStage.ts","../../src/matrix/verification/SAS/VerificationCancelledError.ts","../../src/matrix/verification/SAS/stages/CalculateSASStage.ts","../../src/matrix/verification/SAS/stages/SendKeyStage.ts","../../src/matrix/verification/SAS/stages/SendAcceptVerificationStage.ts","../../src/matrix/verification/SAS/stages/SelectVerificationMethodStage.ts","../../src/matrix/verification/SAS/stages/SendRequestVerificationStage.ts","../../src/matrix/verification/SAS/stages/SendReadyStage.ts","../../__vite-browser-external","../../node_modules/@matrix-org/olm/olm.js","../../src/matrix/verification/SAS/SASVerification.ts","../../src/matrix/verification/SAS/channel/IChannel.ts","../../src/utils/groupBy.ts","../../src/matrix/common.js","../../src/utils/Disposables.ts","../../src/matrix/verification/SAS/channel/ToDeviceChannel.ts","../../src/matrix/verification/SAS/channel/RoomChannel.ts","../../src/matrix/verification/SAS/SASRequest.ts","../../src/matrix/verification/CrossSigning.ts","../../src/matrix/e2ee/DeviceTracker.ts","../../src/matrix/storage/idb/schema.ts","../../src/matrix/storage/idb/quirks.ts","../../src/matrix/storage/idb/StorageFactory.ts","../../src/matrix/room/timeline/persistence/RelationWriter.js","../../src/matrix/room/timeline/Direction.ts","../../src/matrix/room/timeline/entries/FragmentBoundaryEntry.js","../../src/matrix/room/timeline/persistence/SyncWriter.js","../../src/utils/LRUCache.ts","../../src/matrix/room/timeline/persistence/MemberWriter.js","../../src/matrix/room/timeline/persistence/GapWriter.js","../../src/matrix/room/timeline/persistence/TimelineReader.js","../../src/matrix/room/timeline/entries/NonPersistedEventEntry.js","../../src/utils/RetainedValue.ts","../../src/matrix/User.js","../../src/matrix/room/timeline/Timeline.js","../../src/matrix/room/members/load.js","../../src/matrix/room/members/MemberList.js","../../src/matrix/room/members/Heroes.js","../../src/matrix/room/ObservedEventMap.js","../../src/logging/utils.ts","../../src/matrix/room/PowerLevels.js","../../src/matrix/room/state/ObservedStateTypeMap.ts","../../src/matrix/room/state/ObservedStateKeyValue.ts","../../src/matrix/room/BaseRoom.js","../../src/matrix/room/sending/SendQueue.js","../../src/matrix/room/AttachmentUpload.js","../../src/matrix/room/Room.js","../../src/matrix/room/ArchivedRoom.js","../../src/matrix/profile.ts","../../src/matrix/room/RoomBeingCreated.ts","../../src/matrix/room/Invite.js","../../src/matrix/push/Pusher.ts","../../src/matrix/DeviceMessageHandler.js","../../src/matrix/e2ee/Account.js","../../src/matrix/ssss/common.ts","../../src/matrix/ssss/passphrase.ts","../../src/matrix/ssss/recoveryKey.ts","../../src/matrix/ssss/SecretFetcher.ts","../../src/matrix/ssss/SecretSharing.ts","../../src/matrix/ssss/SecretStorage.ts","../../src/matrix/ssss/index.ts","../../src/matrix/e2ee/Dehydration.js","../../src/utils/Lock.ts","../../src/matrix/e2ee/olm/Session.ts","../../src/matrix/e2ee/DecryptionResult.ts","../../src/matrix/e2ee/olm/types.ts","../../src/matrix/e2ee/olm/Decryption.ts","../../src/matrix/e2ee/olm/Encryption.ts","../../src/matrix/e2ee/megolm/decryption/DecryptionChanges.js","../../src/utils/mergeMap.ts","../../src/matrix/e2ee/megolm/decryption/DecryptionPreparation.js","../../src/matrix/e2ee/megolm/decryption/ReplayDetectionEntry.ts","../../src/matrix/e2ee/megolm/decryption/SessionDecryption.ts","../../src/matrix/e2ee/megolm/decryption/utils.ts","../../src/matrix/e2ee/megolm/decryption/RoomKey.ts","../../src/matrix/e2ee/megolm/Decryption.ts","../../src/matrix/e2ee/megolm/decryption/KeyLoader.ts","../../src/matrix/e2ee/megolm/keybackup/Curve25519.ts","../../src/matrix/e2ee/megolm/keybackup/KeyBackup.ts","../../src/matrix/e2ee/megolm/Encryption.js","../../src/matrix/e2ee/RoomEncryption.js","../../src/utils/LockMap.ts","../../src/utils/recursivelyAssign.ts","../../src/platform/types/MediaDevices.ts","../../src/matrix/calls/common.ts","../../src/matrix/calls/callEventTypes.ts","../../src/matrix/calls/PeerCall.ts","../../src/utils/ErrorBoundary.ts","../../src/matrix/calls/group/Member.ts","../../src/matrix/calls/group/GroupCall.ts","../../src/matrix/calls/TurnServerSource.ts","../../src/matrix/calls/CallHandler.ts","../../src/matrix/room/state/RoomStateHandlerSet.ts","../../src/features.ts","../../src/matrix/Session.js","../../src/matrix/login/PasswordLoginMethod.ts","../../src/matrix/login/TokenLoginMethod.ts","../../src/matrix/login/SSOLoginHelper.ts","../../src/matrix/registration/stages/BaseRegistrationStage.ts","../../src/matrix/registration/stages/DummyAuth.ts","../../src/matrix/registration/stages/TermsAuth.ts","../../src/matrix/registration/stages/TokenAuth.ts","../../src/matrix/registration/Registration.ts","../../src/matrix/Client.js","../../src/domain/ViewModel.ts","../../src/domain/avatar.ts","../../src/domain/session/leftpanel/BaseTileViewModel.js","../../src/domain/session/leftpanel/RoomTileViewModel.js","../../src/domain/session/leftpanel/common.js","../../src/domain/session/leftpanel/InviteTileViewModel.js","../../src/domain/session/leftpanel/RoomBeingCreatedTileViewModel.js","../../src/domain/session/leftpanel/RoomFilter.js","../../src/domain/navigation/Navigation.ts","../../src/domain/navigation/URLRouter.ts","../../src/domain/navigation/index.ts","../../src/domain/session/leftpanel/LeftPanelViewModel.js","../../src/domain/session/room/timeline/tiles/ITile.ts","../../src/domain/session/room/timeline/UpdateAction.js","../../src/domain/session/room/timeline/TilesCollection.js","../../src/domain/session/room/timeline/TimelineViewModel.js","../../src/domain/session/room/ComposerViewModel.js","../../src/domain/rageshake.ts","../../src/domain/ErrorViewModel.ts","../../src/domain/ErrorReportViewModel.ts","../../src/domain/session/room/CallViewModel.ts","../../src/domain/session/common.js","../../src/matrix/calls/LocalMedia.ts","../../src/domain/session/room/timeline/tiles/DateTile.ts","../../src/domain/session/room/timeline/tiles/SimpleTile.ts","../../src/domain/session/room/timeline/tiles/GapTile.js","../../src/domain/session/room/timeline/ReactionsViewModel.js","../../src/domain/session/room/timeline/tiles/BaseMessageTile.js","../../src/domain/session/room/timeline/linkify/regex.ts","../../src/domain/session/room/timeline/linkify/linkify.ts","../../src/domain/session/room/timeline/MessageBody.js","../../src/domain/session/room/timeline/tiles/BaseTextTile.js","../../src/domain/session/room/timeline/deserialize.js","../../src/domain/session/room/timeline/tiles/TextTile.js","../../src/domain/session/room/timeline/tiles/RedactedTile.js","../../src/domain/session/room/timeline/tiles/BaseMediaTile.js","../../src/domain/session/room/timeline/tiles/ImageTile.js","../../src/domain/session/room/timeline/tiles/VideoTile.js","../../src/utils/formatSize.ts","../../src/domain/session/room/timeline/tiles/FileTile.js","../../src/domain/session/room/timeline/tiles/LocationTile.js","../../src/domain/session/room/timeline/tiles/RoomNameTile.js","../../src/domain/session/room/timeline/tiles/RoomMemberTile.js","../../src/domain/session/room/timeline/tiles/EncryptedEventTile.js","../../src/domain/session/room/timeline/tiles/EncryptionEnabledTile.js","../../src/domain/session/room/timeline/tiles/MissingAttachmentTile.js","../../src/domain/session/room/timeline/tiles/CallTile.js","../../src/domain/session/room/timeline/tiles/VerificationTile.ts","../../src/domain/session/room/timeline/tiles/index.ts","../../src/matrix/room/joinRoom.ts","../../src/domain/session/room/RoomViewModel.js","../../src/domain/session/room/UnknownRoomViewModel.js","../../src/domain/session/room/InviteViewModel.js","../../src/domain/session/room/RoomBeingCreatedViewModel.js","../../src/domain/session/room/LightboxViewModel.js","../../src/domain/session/SessionStatusViewModel.js","../../src/domain/session/RoomGridViewModel.js","../../src/domain/session/settings/KeyBackupViewModel.ts","../../src/domain/session/settings/FeaturesViewModel.ts","../../src/domain/session/settings/SettingsViewModel.js","../../src/domain/session/CreateRoomViewModel.js","../../src/domain/session/JoinRoomViewModel.ts","../../src/domain/session/verification/stages/WaitingForOtherUserViewModel.ts","../../src/domain/session/verification/stages/DismissibleVerificationViewModel.ts","../../src/domain/session/verification/stages/VerificationCancelledViewModel.ts","../../src/domain/session/verification/stages/SelectMethodViewModel.ts","../../src/domain/session/verification/stages/VerifyEmojisViewModel.ts","../../src/domain/session/verification/stages/VerificationCompleteViewModel.ts","../../src/domain/session/verification/stages/MissingKeysViewModel.ts","../../src/domain/session/verification/DeviceVerificationViewModel.ts","../../src/domain/session/RoomViewModelObservable.js","../../src/domain/session/rightpanel/RoomDetailsViewModel.js","../../src/domain/session/rightpanel/MemberTileViewModel.js","../../src/domain/session/rightpanel/members/comparator.js","../../src/domain/session/rightpanel/members/disambiguator.js","../../src/domain/session/rightpanel/MemberListViewModel.js","../../src/domain/session/rightpanel/MemberDetailsViewModel.js","../../src/domain/session/rightpanel/InvitePanelViewModel.ts","../../src/domain/session/rightpanel/RightPanelViewModel.js","../../src/domain/session/toast/BaseToastNotificationViewModel.ts","../../src/domain/session/toast/calls/CallToastNotificationViewModel.ts","../../src/domain/session/toast/calls/CallsToastCollectionViewModel.ts","../../src/domain/session/toast/verification/VerificationToastNotificationViewModel.ts","../../src/domain/session/toast/verification/VerificationToastCollectionViewModel.ts","../../src/domain/session/toast/ToastCollectionViewModel.ts","../../src/domain/session/SessionViewModel.js","../../src/domain/AccountSetupViewModel.js","../../src/domain/SessionLoadViewModel.js","../../src/domain/login/PasswordLoginViewModel.ts","../../src/domain/login/StartSSOLoginViewModel.ts","../../src/domain/login/CompleteSSOLoginViewModel.ts","../../src/domain/login/LoginViewModel.ts","../../src/domain/LogoutViewModel.ts","../../src/domain/ForcedLogoutViewModel.ts","../../src/domain/SessionPickerViewModel.js","../../src/domain/RootViewModel.js","../../src/platform/web/main.js","../../src/utils/timeout.ts","../../src/platform/web/dom/request/common.js","../../src/platform/web/dom/request/xhr.js","../../src/platform/web/dom/request/fetch.js","../../src/matrix/sessioninfo/localstorage/SessionInfoStorage.ts","../../src/platform/web/dom/SettingsStorage.js","../../src/platform/web/dom/UTF8.js","../../node_modules/base64-arraybuffer/lib/base64-arraybuffer.js","../../src/platform/web/utils/Base64.js","../../scripts/package-overrides/buffer/index.js","../../node_modules/base-x/src/index.js","../../node_modules/bs58/index.js","../../src/platform/web/utils/Base58.js","../../src/platform/web/utils/Encoding.js","../../src/matrix/e2ee/OlmWorker.js","../../src/logging/IDBLogPersister.ts","../../src/logging/ConsoleReporter.ts","../../src/logging/LogItem.ts","../../src/logging/Logger.ts","../../src/platform/web/ui/general/html.ts","../../src/platform/web/ui/general/utils.ts","../../src/platform/web/ui/general/ListView.ts","../../src/platform/web/ui/general/BaseUpdateView.ts","../../src/platform/web/ui/general/TemplateView.ts","../../src/platform/web/ui/avatar.js","../../src/platform/web/ui/AvatarView.js","../../src/platform/web/ui/common.js","../../src/platform/web/ui/session/leftpanel/RoomTileView.js","../../src/platform/web/ui/general/Menu.js","../../src/platform/web/ui/general/Popup.js","../../src/platform/web/ui/session/leftpanel/LeftPanelView.js","../../src/platform/web/ui/session/room/TimelineView.ts","../../src/platform/web/ui/session/room/TimelineLoadingView.js","../../src/platform/web/ui/session/room/MessageComposer.js","../../src/platform/web/ui/session/room/DisabledComposerView.js","../../src/platform/web/ui/general/ErrorView.ts","../../src/platform/web/ui/session/room/CallView.ts","../../src/platform/web/ui/session/room/RoomView.js","../../src/platform/web/ui/session/room/UnknownRoomView.js","../../src/platform/web/ui/general/StaticView.js","../../src/platform/web/ui/general/LoadingView.js","../../src/platform/web/ui/session/room/RoomBeingCreatedView.js","../../src/platform/web/ui/session/room/InviteView.js","../../src/platform/web/ui/session/room/LightboxView.js","../../src/platform/web/ui/session/SessionStatusView.js","../../src/platform/web/ui/session/RoomGridView.js","../../src/platform/web/ui/session/settings/KeyBackupSettingsView.ts","../../src/platform/web/ui/session/settings/FeaturesView.ts","../../src/platform/web/ui/session/settings/SettingsView.js","../../src/platform/web/ui/session/CreateRoomView.js","../../src/platform/web/ui/session/rightpanel/RoomDetailsView.js","../../src/platform/web/ui/general/Range.ts","../../src/platform/web/ui/general/ListRange.ts","../../src/platform/web/ui/general/LazyListView.ts","../../src/platform/web/ui/session/rightpanel/MemberTileView.js","../../src/platform/web/ui/session/rightpanel/MemberListView.js","../../src/platform/web/ui/session/rightpanel/MemberDetailsView.js","../../src/platform/web/ui/session/verification/stages/WaitingForOtherUserView.ts","../../src/platform/web/ui/session/verification/stages/VerificationCancelledView.ts","../../src/platform/web/ui/session/verification/stages/SelectMethodView.ts","../../src/platform/web/ui/session/verification/stages/VerifyEmojisView.ts","../../src/platform/web/ui/session/verification/stages/VerificationCompleteView.ts","../../src/platform/web/ui/session/verification/stages/MissingKeysView.ts","../../src/platform/web/ui/session/verification/DeviceVerificationView.ts","../../src/platform/web/ui/session/rightpanel/InvitePanelView.ts","../../src/platform/web/ui/session/rightpanel/RightPanelView.js","../../src/platform/web/ui/session/room/timeline/ReactionsView.js","../../src/platform/web/ui/session/room/timeline/BaseMessageView.js","../../src/platform/web/ui/session/room/timeline/ReplyPreviewView.js","../../src/platform/web/ui/session/room/timeline/TextMessageView.js","../../src/platform/web/ui/session/room/timeline/BaseMediaView.js","../../src/platform/web/ui/session/room/timeline/ImageView.js","../../src/platform/web/dom/utils.ts","../../src/platform/web/ui/session/room/timeline/VideoView.js","../../src/platform/web/ui/session/room/timeline/FileView.js","../../src/platform/web/ui/session/room/timeline/LocationView.js","../../src/platform/web/ui/session/room/timeline/MissingAttachmentView.js","../../src/platform/web/ui/session/room/timeline/AnnouncementView.js","../../src/platform/web/ui/session/room/timeline/RedactedView.js","../../src/platform/web/ui/session/room/timeline/GapView.js","../../src/platform/web/ui/session/room/timeline/CallTileView.ts","../../src/platform/web/ui/session/room/timeline/DateHeaderView.ts","../../src/platform/web/ui/session/room/timeline/VerificationTileView.ts","../../src/platform/web/ui/session/room/common.ts","../../src/platform/web/ui/session/JoinRoomView.ts","../../src/platform/web/ui/session/toast/CallToastNotificationView.ts","../../src/platform/web/ui/session/toast/VerificationToastNotificationView.ts","../../src/platform/web/ui/session/toast/ToastCollectionView.ts","../../src/platform/web/ui/session/SessionView.js","../../src/platform/web/ui/login/common.js","../../src/platform/web/ui/login/PasswordLoginView.js","../../src/platform/web/ui/login/AccountSetupView.js","../../src/platform/web/ui/login/SessionLoadStatusView.js","../../src/platform/web/ui/login/CompleteSSOView.js","../../src/platform/web/ui/login/LoginView.js","../../src/platform/web/ui/LogoutView.js","../../src/platform/web/ui/ForcedLogoutView.js","../../src/platform/web/ui/login/SessionLoadView.js","../../src/platform/web/ui/login/SessionPickerView.js","../../src/platform/web/ui/RootView.js","../../src/platform/web/dom/Clock.js","../../src/platform/web/dom/ServiceWorkerHandler.js","../../src/platform/web/dom/NotificationService.js","../../src/platform/web/dom/History.js","../../src/platform/web/dom/OnlineStatus.js","../../src/platform/web/dom/Crypto.js","../../src/platform/web/dom/StorageEstimate.js","../../src/platform/web/dom/WorkerPool.js","../../src/platform/web/dom/ImageHandle.js","../../src/platform/web/dom/download.js","../../node_modules/dompurify/dist/purify.es.js","../../src/platform/web/parsehtml.js","../../src/platform/web/dom/MediaDevices.ts","../../src/platform/web/dom/WebRTC.ts","../../src/platform/web/theming/parsers/types.ts","../../src/platform/web/theming/shared/svg-colorizer.mjs","../../src/platform/web/theming/IconColorizer.ts","../../node_modules/off-color/cjs/index.min.js","../../node_modules/off-color/index.js","../../src/platform/web/theming/shared/color.mjs","../../src/platform/web/theming/DerivedVariables.ts","../../src/platform/web/theming/parsers/RuntimeThemeParser.ts","../../src/platform/web/theming/parsers/BuiltThemeParser.ts","../../src/platform/web/theming/ThemeLoader.ts","../../src/utils/timeFormatting.ts","../../src/platform/web/dom/TimeFormatter.ts","../../src/platform/web/Platform.js","../../src/platform/web/assets/config.json?url","../../src/platform/web/assets/download-sandbox.html?url","../../src/platform/web/worker/main.js?url","../../node_modules/@matrix-org/olm/olm.wasm?url","../../node_modules/@matrix-org/olm/olm.js?url","../../node_modules/@matrix-org/olm/olm_legacy.js?url","../../src/platform/web/sdk/paths/vite.js","../../src/platform/web/index.html?html-proxy&index=0.js"],"sourcesContent":["/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function createEnum(...values: string[]): Readonly<{}> {\n const obj = {};\n for (const value of values) {\n obj[value] = value;\n }\n return Object.freeze(obj);\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nfunction normalizeHomeserver(homeserver) {\n try {\n return new URL(homeserver).origin;\n } catch (err) {\n return new URL(`https://${homeserver}`).origin;\n }\n}\n\nasync function getWellKnownResponse(homeserver, request) {\n const requestOptions = {format: \"json\", timeout: 30000, method: \"GET\"};\n try {\n const wellKnownUrl = `${homeserver}/.well-known/matrix/client`;\n return await request(wellKnownUrl, requestOptions).response();\n } catch (err) {\n if (err.name === \"ConnectionError\") {\n // don't fail lookup on a ConnectionError,\n // there might be a missing CORS header on a 404 response or something,\n // which won't be a problem necessarily with homeserver requests later on ...\n return null;\n } else {\n throw err;\n }\n }\n}\n\nexport async function lookupHomeserver(homeserver, request) {\n homeserver = normalizeHomeserver(homeserver);\n const wellKnownResponse = await getWellKnownResponse(homeserver, request);\n if (wellKnownResponse && wellKnownResponse.status === 200) {\n const {body} = wellKnownResponse;\n const wellKnownHomeserver = body[\"m.homeserver\"]?.[\"base_url\"];\n if (typeof wellKnownHomeserver === \"string\") {\n homeserver = normalizeHomeserver(wellKnownHomeserver);\n }\n }\n return homeserver;\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 Daniel Fedorin \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\ntype Handler = (value?: T) => void;\n\nexport class EventEmitter {\n private _handlersByName: { [event in keyof T]?: Set> }\n\n constructor() {\n this._handlersByName = {};\n }\n\n emit(name: K, value?: T[K]): void {\n const handlers = this._handlersByName[name];\n if (handlers) {\n handlers.forEach(h => h(value));\n }\n }\n\n disposableOn(name: K, callback: Handler): () => void {\n this.on(name, callback);\n return () => {\n this.off(name, callback);\n }\n }\n\n on(name: K, callback: Handler): void {\n let handlers = this._handlersByName[name];\n if (!handlers) {\n this.onFirstSubscriptionAdded(name);\n this._handlersByName[name] = handlers = new Set();\n }\n handlers.add(callback);\n }\n\n off(name: K, callback: Handler): void {\n const handlers = this._handlersByName[name];\n if (handlers) {\n handlers.delete(callback);\n if (handlers.size === 0) {\n delete this._handlersByName[name];\n this.onLastSubscriptionRemoved(name);\n }\n }\n }\n\n onFirstSubscriptionAdded(name: K): void {}\n\n onLastSubscriptionRemoved(name: K): void {}\n}\n\nexport function tests() {\n return {\n test_on_off(assert) {\n let counter = 0;\n const e = new EventEmitter<{ change: never }>();\n const callback = () => counter += 1;\n e.on(\"change\", callback);\n e.emit(\"change\");\n e.off(\"change\", callback);\n e.emit(\"change\");\n assert.equal(counter, 1);\n },\n\n test_emit_value(assert) {\n let value = 0;\n const e = new EventEmitter<{ change: number }>();\n const callback = (v) => value = v;\n e.on(\"change\", callback);\n e.emit(\"change\", 5);\n e.off(\"change\", callback);\n assert.equal(value, 5);\n },\n\n test_double_on(assert) {\n let counter = 0;\n const e = new EventEmitter<{ change: never }>();\n const callback = () => counter += 1;\n e.on(\"change\", callback);\n e.on(\"change\", callback);\n e.emit(\"change\");\n e.off(\"change\", callback);\n assert.equal(counter, 1);\n }\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventEmitter} from \"../utils/EventEmitter\";\n\nexport interface IAbortable {\n abort();\n}\n\nexport type SetAbortableFn = (a: IAbortable) => typeof a;\nexport type SetProgressFn

= (progress: P) => void;\ntype RunFn = (setAbortable: SetAbortableFn, setProgress: SetProgressFn

) => T;\n\nexport class AbortableOperation extends EventEmitter<{change: keyof AbortableOperation}> implements IAbortable {\n public readonly result: T;\n private _abortable?: IAbortable;\n private _progress?: P;\n\n constructor(run: RunFn) {\n super();\n this._abortable = undefined;\n const setAbortable: SetAbortableFn = abortable => {\n this._abortable = abortable;\n return abortable;\n };\n this._progress = undefined;\n const setProgress: SetProgressFn

= (progress: P) => {\n this._progress = progress;\n this.emit(\"change\", \"progress\");\n };\n this.result = run(setAbortable, setProgress);\n }\n\n get progress(): P | undefined {\n return this._progress;\n }\n\n abort() {\n this._abortable?.abort();\n this._abortable = undefined;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class AbortError extends Error {\n get name(): string {\n return \"AbortError\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// we return undefined so you can reassign any member\n// that uses `member?: T` syntax in one statement.\nexport type SubscriptionHandle = () => undefined;\n\nexport abstract class BaseObservable {\n protected _handlers: Set = new Set();\n\n onSubscribeFirst(): void {\n\n }\n\n onUnsubscribeLast(): void {\n\n }\n\n subscribe(handler: T): SubscriptionHandle {\n this._handlers.add(handler);\n if (this._handlers.size === 1) {\n this.onSubscribeFirst();\n }\n return (): undefined => {\n return this.unsubscribe(handler);\n };\n }\n\n unsubscribe(handler?: T): undefined {\n if (handler) {\n this._handlers.delete(handler);\n if (this._handlers.size === 0) {\n this.onUnsubscribeLast();\n }\n }\n return undefined;\n }\n\n unsubscribeAll(): void {\n if (this._handlers.size !== 0) {\n this._handlers.clear();\n this.onUnsubscribeLast();\n }\n }\n\n get hasSubscriptions(): boolean {\n return this._handlers.size !== 0;\n }\n\n // Add iterator over handlers here\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n class Collection extends BaseObservable<{}> {\n firstSubscribeCalls: number = 0;\n firstUnsubscribeCalls: number = 0;\n\n onSubscribeFirst(): void { this.firstSubscribeCalls += 1; }\n onUnsubscribeLast(): void { this.firstUnsubscribeCalls += 1; }\n }\n\n return {\n test_unsubscribe(assert): void {\n const c = new Collection();\n const unsubscribe = c.subscribe({});\n unsubscribe();\n assert.equal(c.firstSubscribeCalls, 1);\n assert.equal(c.firstUnsubscribeCalls, 1);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../utils/error\";\nimport {BaseObservable} from \"../BaseObservable\";\nimport type {SubscriptionHandle} from \"../BaseObservable\";\nimport {FlatMapObservableValue} from \"./index\";\n\n// like an EventEmitter, but doesn't have an event type\nexport abstract class BaseObservableValue extends BaseObservable<(value: T) => void> {\n emit(argument: T): void {\n for (const h of this._handlers) {\n h(argument);\n }\n }\n\n abstract get(): T;\n\n waitFor(predicate: (value: T) => boolean): IWaitHandle {\n if (predicate(this.get())) {\n return new ResolvedWaitForHandle(Promise.resolve(this.get()));\n } else {\n return new WaitForHandle(this, predicate);\n }\n }\n\n flatMap(mapper: (value: T) => (BaseObservableValue | undefined)): BaseObservableValue {\n return new FlatMapObservableValue(this, mapper);\n }\n}\n\ninterface IWaitHandle {\n promise: Promise;\n dispose(): void;\n}\n\nclass WaitForHandle implements IWaitHandle {\n private _promise: Promise\n private _reject: ((reason?: any) => void) | null;\n private _subscription: (() => void) | null;\n\n constructor(observable: BaseObservableValue, predicate: (value: T) => boolean) {\n this._promise = new Promise((resolve, reject) => {\n this._reject = reject;\n this._subscription = observable.subscribe(v => {\n if (predicate(v)) {\n this._reject = null;\n resolve(v);\n this.dispose();\n }\n });\n });\n }\n\n get promise(): Promise {\n return this._promise;\n }\n\n dispose(): void {\n if (this._subscription) {\n this._subscription();\n this._subscription = null;\n }\n if (this._reject) {\n this._reject(new AbortError());\n this._reject = null;\n }\n }\n}\n\nclass ResolvedWaitForHandle implements IWaitHandle {\n constructor(public promise: Promise) {}\n dispose(): void {}\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport {EventEmitter} from \"../../utils/EventEmitter\";\n\nexport class EventObservableValue> extends BaseObservableValue {\n private eventSubscription: () => void;\n\n constructor(\n private readonly value: V,\n private readonly eventName: keyof T\n ) {\n super();\n }\n\n onSubscribeFirst(): void {\n this.eventSubscription = this.value.disposableOn(this.eventName, () => {\n this.emit(this.value);\n });\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast(): void {\n this.eventSubscription!();\n super.onUnsubscribeLast();\n }\n\n get(): V {\n return this.value;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../utils/error\";\nimport {BaseObservableValue} from \"./index\";\n\nexport class ObservableValue extends BaseObservableValue {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n get(): T {\n return this._value;\n }\n\n set(value: T): void {\n if (value !== this._value) {\n this._value = value;\n this.emit(this._value);\n }\n }\n}\n\nexport function tests() {\n return {\n \"set emits an update\": (assert): void => {\n const a = new ObservableValue(0);\n let fired = false;\n const subscription = a.subscribe(v => {\n fired = true;\n assert.strictEqual(v, 5);\n });\n a.set(5);\n assert(fired);\n subscription();\n },\n \"set doesn't emit if value hasn't changed\": (assert): void => {\n const a = new ObservableValue(5);\n let fired = false;\n const subscription = a.subscribe(() => {\n fired = true;\n });\n a.set(5);\n a.set(5);\n assert(!fired);\n subscription();\n },\n \"waitFor promise resolves on matching update\": async (assert): Promise => {\n const a = new ObservableValue(5);\n const handle = a.waitFor(v => v === 6);\n await Promise.resolve().then(() => {\n a.set(6);\n });\n await handle.promise;\n assert.strictEqual(a.get(), 6);\n },\n \"waitFor promise rejects when disposed\": async (assert): Promise => {\n const a = new ObservableValue(0);\n const handle = a.waitFor(() => false);\n await Promise.resolve().then(() => {\n handle.dispose();\n });\n await assert.rejects(handle.promise, AbortError);\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport type {SubscriptionHandle} from \"../BaseObservable\";\n\nexport class FlatMapObservableValue extends BaseObservableValue {\n private sourceSubscription?: SubscriptionHandle;\n private targetSubscription?: SubscriptionHandle;\n\n constructor(\n private readonly source: BaseObservableValue

,\n private readonly mapper: (value: P) => (BaseObservableValue | undefined)\n ) {\n super();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n this.sourceSubscription = this.sourceSubscription!();\n if (this.targetSubscription) {\n this.targetSubscription = this.targetSubscription();\n }\n }\n\n onSubscribeFirst(): void {\n super.onSubscribeFirst();\n this.sourceSubscription = this.source.subscribe(() => {\n this.updateTargetSubscription();\n this.emit(this.get());\n });\n this.updateTargetSubscription();\n }\n\n private updateTargetSubscription(): void {\n const sourceValue = this.source.get();\n if (sourceValue) {\n const target = this.mapper(sourceValue);\n if (target) {\n if (!this.targetSubscription) {\n this.targetSubscription = target.subscribe(() => this.emit(this.get()));\n }\n return;\n }\n }\n // if no sourceValue or target\n if (this.targetSubscription) {\n this.targetSubscription = this.targetSubscription();\n }\n }\n\n get(): C | undefined {\n const sourceValue = this.source.get();\n if (!sourceValue) {\n return undefined;\n }\n const mapped = this.mapper(sourceValue);\n return mapped?.get();\n }\n}\n\nimport {ObservableValue} from \"./ObservableValue\";\n\nexport function tests() {\n return {\n \"flatMap.get\": (assert): void => {\n const a = new ObservableValue}>(undefined);\n const countProxy = a.flatMap(a => a!.count);\n assert.strictEqual(countProxy.get(), undefined);\n const count = new ObservableValue(0);\n a.set({count});\n assert.strictEqual(countProxy.get(), 0);\n },\n \"flatMap update from source\": (assert): void => {\n const a = new ObservableValue}>(undefined);\n const updates: (number | undefined)[] = [];\n a.flatMap(a => a!.count).subscribe(count => {\n updates.push(count);\n });\n const count = new ObservableValue(0);\n a.set({count});\n assert.deepEqual(updates, [0]);\n },\n \"flatMap update from target\": (assert): void => {\n const a = new ObservableValue}>(undefined);\n const updates: (number | undefined)[] = [];\n a.flatMap(a => a!.count).subscribe(count => {\n updates.push(count);\n });\n const count = new ObservableValue(0);\n a.set({count});\n count.set(5);\n assert.deepEqual(updates, [0, 5]);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport {BaseObservableMap, IMapObserver} from \"../map/BaseObservableMap\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\nfunction pickLowestKey(currentKey: K, newKey: K): boolean {\n return newKey < currentKey;\n}\n\nexport class PickMapObservableValue extends BaseObservableValue implements IMapObserver{\n\n private key?: K;\n private mapSubscription?: SubscriptionHandle;\n\n constructor(\n private readonly map: BaseObservableMap,\n private readonly pickKey: (currentKey: K, newKey: K) => boolean = pickLowestKey\n ) {\n super();\n }\n\n private updateKey(newKey: K): boolean {\n if (this.key === undefined || this.pickKey(this.key, newKey)) {\n this.key = newKey;\n return true;\n }\n return false;\n }\n\n onReset(): void {\n this.key = undefined;\n this.emit(this.get());\n }\n\n onAdd(key: K, value:V): void {\n if (this.updateKey(key)) {\n this.emit(this.get());\n }\n }\n\n onUpdate(key: K, value: V, params: any): void {\n this.emit(this.get());\n }\n\n onRemove(key: K, value: V): void {\n if (key === this.key) {\n this.key = undefined;\n // try to see if there is another key that fullfills pickKey\n for (const [key] of this.map) {\n this.updateKey(key);\n }\n this.emit(this.get());\n }\n }\n\n onSubscribeFirst(): void {\n this.mapSubscription = this.map.subscribe(this);\n for (const [key] of this.map) {\n this.updateKey(key);\n }\n }\n\n onUnsubscribeLast(): void {\n this.mapSubscription!();\n this.key = undefined;\n }\n\n get(): V | undefined {\n if (this.key !== undefined) {\n return this.map.get(this.key);\n }\n return undefined;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableValue} from \"./index\";\n\nexport class RetainedObservableValue extends ObservableValue {\n\n constructor(initialValue: T, private freeCallback: () => void, private startCallback: () => void = () => {}) {\n super(initialValue);\n }\n\n onSubscribeFirst(): void {\n this.startCallback();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n this.freeCallback();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservable} from \"../BaseObservable\";\n\nexport interface IListObserver {\n onReset(list: BaseObservableList): void;\n onAdd(index: number, value:T, list: BaseObservableList): void;\n onUpdate(index: number, value: T, params: any, list: BaseObservableList): void;\n onRemove(index: number, value: T, list: BaseObservableList): void\n onMove(from: number, to: number, value: T, list: BaseObservableList): void\n}\n\nexport function defaultObserverWith(overrides: { [key in keyof IListObserver]?: IListObserver[key] }): IListObserver {\n const defaults = {\n onReset(): void {},\n onAdd(): void {},\n onUpdate(): void {},\n onRemove(): void {},\n onMove(): void {},\n };\n return Object.assign(defaults, overrides);\n}\n\nexport abstract class BaseObservableList extends BaseObservable> implements Iterable {\n emitReset(): void {\n for(let h of this._handlers) {\n h.onReset(this);\n }\n }\n // we need batch events, mostly on index based collection though?\n // maybe we should get started without?\n emitAdd(index: number, value: T): void {\n for(let h of this._handlers) {\n h.onAdd(index, value, this);\n }\n }\n\n emitUpdate(index: number, value: T, params?: any): void {\n for(let h of this._handlers) {\n h.onUpdate(index, value, params, this);\n }\n }\n\n emitRemove(index: number, value: T): void {\n for(let h of this._handlers) {\n h.onRemove(index, value, this);\n }\n }\n\n // toIdx assumes the item has already\n // been removed from its fromIdx\n emitMove(fromIdx: number, toIdx: number, value: T): void {\n for(let h of this._handlers) {\n h.onMove(fromIdx, toIdx, value, this);\n }\n }\n\n abstract [Symbol.iterator](): Iterator;\n abstract get length(): number;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * @license\n * Based off baseSortedIndex function in Lodash \n * Copyright JS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\nexport function sortedIndex(array: T[], value: T, comparator: (x:T, y:T) => number): number {\n let low = 0;\n let high = array.length;\n\n while (low < high) {\n let mid = (low + high) >>> 1;\n let cmpResult = comparator(value, array[mid]);\n\n if (cmpResult > 0) {\n low = mid + 1;\n } else if (cmpResult < 0) {\n high = mid;\n } else {\n low = high = mid;\n }\n }\n return high;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\n\nexport class ObservableArray extends BaseObservableList {\n private _items: T[];\n\n constructor(initialValues: T[] = []) {\n super();\n this._items = initialValues;\n }\n\n append(item: T): void {\n this._items.push(item);\n this.emitAdd(this._items.length - 1, item);\n }\n\n remove(idx: number): void {\n const [item] = this._items.splice(idx, 1);\n this.emitRemove(idx, item);\n }\n\n insertMany(idx: number, items: T[]): void {\n for(let item of items) {\n this.insert(idx, item);\n idx += 1;\n }\n }\n\n insert(idx: number, item: T): void {\n this._items.splice(idx, 0, item);\n this.emitAdd(idx, item);\n }\n\n move(fromIdx: number, toIdx: number): void {\n if (fromIdx < this._items.length && toIdx < this._items.length) {\n const [item] = this._items.splice(fromIdx, 1);\n this._items.splice(toIdx, 0, item);\n this.emitMove(fromIdx, toIdx, item);\n }\n }\n\n update(idx: number, item: T, params: any = null): void {\n if (idx < this._items.length) {\n this._items[idx] = item;\n this.emitUpdate(idx, item, params);\n }\n }\n\n get array(): Readonly {\n return this._items;\n }\n\n at(idx: number): T | undefined {\n if (this._items && idx >= 0 && idx < this._items.length) {\n return this._items[idx];\n }\n }\n\n get length(): number {\n return this._items.length;\n }\n\n [Symbol.iterator](): IterableIterator {\n return this._items.values();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseObservableList} from \"./BaseObservableList\";\n\n/* inline update of item in collection backed by array, without replacing the preexising item */\nexport function findAndUpdateInArray(\n predicate: (value: T) => boolean,\n array: T[],\n observable: BaseObservableList,\n updater: (value: T) => any | false\n): boolean {\n const index = array.findIndex(predicate);\n if (index !== -1) {\n const value = array[index];\n // allow bailing out of sending an emit if updater determined its not needed\n const params = updater(value);\n if (params !== false) {\n observable.emitUpdate(index, value, params);\n }\n // found\n return true;\n }\n return false;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\nimport {sortedIndex} from \"../../utils/sortedIndex\";\nimport {findAndUpdateInArray} from \"./common\";\n\nexport class SortedArray extends BaseObservableList {\n private _comparator: (left: T, right: T) => number;\n private _items: T[] = [];\n\n constructor(comparator: (left: T, right: T) => number) {\n super();\n this._comparator = comparator;\n }\n\n setManyUnsorted(items: T[]): void {\n this.setManySorted(items);\n }\n\n setManySorted(items: T[]): void {\n // TODO: we can make this way faster by only looking up the first and last key,\n // and merging whatever is inbetween with items\n // if items is not sorted, 💩🌀 will follow!\n // should we check?\n // Also, once bulk events are supported in collections,\n // we can do a bulk add event here probably if there are no updates\n // BAD CODE!\n for(let item of items) {\n this.set(item);\n }\n }\n\n findAndUpdate(predicate: (value: T) => boolean, updater: (value: T) => any | false): boolean {\n return findAndUpdateInArray(predicate, this._items, this, updater);\n }\n\n getAndUpdate(item: T, updater: (existing: T, item: T) => any, updateParams: any = null): void {\n const idx = this.indexOf(item);\n if (idx !== -1) {\n const existingItem = this._items[idx];\n const newItem = updater(existingItem, item);\n this._items[idx] = newItem;\n this.emitUpdate(idx, newItem, updateParams);\n }\n }\n\n update(item: T, updateParams: any = null): void {\n const idx = this.indexOf(item);\n if (idx !== -1) {\n this._items[idx] = item;\n this.emitUpdate(idx, item, updateParams);\n }\n }\n\n indexOf(item: T): number {\n const idx = sortedIndex(this._items, item, this._comparator);\n if (idx < this._items.length && this._comparator(this._items[idx], item) === 0) {\n return idx;\n } else {\n return -1;\n }\n }\n\n _getNext(item: T): T | undefined {\n let idx = sortedIndex(this._items, item, this._comparator);\n while(idx < this._items.length && this._comparator(this._items[idx], item) <= 0) {\n idx += 1;\n }\n return this.get(idx);\n }\n\n set(item: T, updateParams: any = null): void {\n const idx = sortedIndex(this._items, item, this._comparator);\n if (idx >= this._items.length || this._comparator(this._items[idx], item) !== 0) {\n this._items.splice(idx, 0, item);\n this.emitAdd(idx, item);\n } else {\n this._items[idx] = item;\n this.emitUpdate(idx, item, updateParams);\n }\n }\n\n get(idx: number): T | undefined {\n return this._items[idx];\n }\n\n remove(idx: number): void {\n const item = this._items[idx];\n this._items.splice(idx, 1);\n this.emitRemove(idx, item);\n }\n\n get array(): T[] {\n return this._items;\n }\n\n get length(): number {\n return this._items.length;\n }\n\n [Symbol.iterator](): Iterator {\n return new Iterator(this);\n }\n}\n\n// iterator that works even if the current value is removed while iterating\nclass Iterator {\n private _sortedArray: SortedArray;\n private _current: T | null | undefined;\n private _consumed: boolean = false;\n\n constructor(sortedArray: SortedArray) {\n this._sortedArray = sortedArray;\n this._current = null;\n }\n\n next(): IteratorResult {\n if (this._consumed) {\n return {value: undefined, done: true};\n }\n this._current = this._current? this._sortedArray._getNext(this._current): this._sortedArray.get(0);\n if (!this._current) {\n this._consumed = true;\n }\n return { value: this._current, done: this._consumed } as IteratorResult;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n return {\n \"setManyUnsorted\": (assert): void => {\n const sa = new SortedArray((a, b) => a.localeCompare(b));\n sa.setManyUnsorted([\"b\", \"a\", \"c\"]);\n assert.equal(sa.length, 3);\n assert.equal(sa.get(0), \"a\");\n assert.equal(sa.get(1), \"b\");\n assert.equal(sa.get(2), \"c\");\n },\n \"_getNext\": (assert): void => {\n const sa = new SortedArray((a, b) => a.localeCompare(b));\n sa.setManyUnsorted([\"b\", \"a\", \"f\"]);\n assert.equal(sa._getNext(\"a\"), \"b\");\n assert.equal(sa._getNext(\"b\"), \"f\");\n // also finds the next if the value is not in the collection\n assert.equal(sa._getNext(\"c\"), \"f\");\n assert.equal(sa._getNext(\"f\"), undefined);\n },\n \"iterator with removals\": (assert): void => {\n const queue = new SortedArray<{idx: number}>((a, b) => a.idx - b.idx);\n queue.setManyUnsorted([{idx: 5}, {idx: 3}, {idx: 1}, {idx: 4}, {idx: 2}]);\n const it = queue[Symbol.iterator]();\n assert.equal(it.next().value.idx, 1);\n assert.equal(it.next().value.idx, 2);\n queue.remove(1);\n assert.equal(it.next().value.idx, 3);\n queue.remove(1);\n assert.equal(it.next().value.idx, 4);\n queue.remove(1);\n assert.equal(it.next().value.idx, 5);\n queue.remove(1);\n assert.equal(it.next().done, true);\n // check done persists\n assert.equal(it.next().done, true);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\nimport {findAndUpdateInArray} from \"./common\";\n\nexport type Mapper = (value: F) => T\nexport type Updater = (mappedValue: T, params: any, value: F) => void;\n\nexport class BaseMappedList extends BaseObservableList {\n protected _sourceList: BaseObservableList;\n protected _sourceUnsubscribe: (() => void) | null = null;\n _mapper: Mapper;\n _updater?: Updater;\n _removeCallback?: (value: T) => void;\n _mappedValues: T[] | null = null;\n\n constructor(sourceList: BaseObservableList, mapper: Mapper, updater?: Updater, removeCallback?: (value: T) => void) {\n super();\n this._sourceList = sourceList;\n this._mapper = mapper;\n this._updater = updater;\n this._removeCallback = removeCallback;\n }\n\n findAndUpdate(predicate: (value: T) => boolean, updater: (value: T) => any | false): boolean {\n return findAndUpdateInArray(predicate, this._mappedValues!, this, updater);\n }\n\n get length(): number {\n return this._mappedValues!.length;\n }\n\n [Symbol.iterator](): IterableIterator {\n return this._mappedValues!.values();\n }\n}\n\nexport function runAdd(list: BaseMappedList, index: number, mappedValue: T): void {\n list._mappedValues!.splice(index, 0, mappedValue);\n list.emitAdd(index, mappedValue);\n}\n\nexport function runUpdate(list: BaseMappedList, index: number, value: F, params: any): void {\n const mappedValue = list._mappedValues![index];\n if (list._updater) {\n list._updater(mappedValue, params, value);\n }\n list.emitUpdate(index, mappedValue, params);\n}\n\nexport function runRemove(list: BaseMappedList, index: number): void {\n const mappedValue = list._mappedValues![index];\n list._mappedValues!.splice(index, 1);\n if (list._removeCallback) {\n list._removeCallback(mappedValue);\n }\n list.emitRemove(index, mappedValue);\n}\n\nexport function runMove(list: BaseMappedList, fromIdx: number, toIdx: number): void {\n const mappedValue = list._mappedValues![fromIdx];\n list._mappedValues!.splice(fromIdx, 1);\n list._mappedValues!.splice(toIdx, 0, mappedValue);\n list.emitMove(fromIdx, toIdx, mappedValue);\n}\n\nexport function runReset(list: BaseMappedList): void {\n list._mappedValues = [];\n list.emitReset();\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {IListObserver} from \"./BaseObservableList\";\nimport {BaseMappedList, runAdd, runUpdate, runRemove, runMove, runReset} from \"./BaseMappedList\";\n\nexport class AsyncMappedList extends BaseMappedList> implements IListObserver {\n private _eventQueue: AsyncEvent[] | null = null;\n private _flushing: boolean = false;\n\n onSubscribeFirst(): void {\n this._sourceUnsubscribe = this._sourceList.subscribe(this);\n this._eventQueue = [];\n this._mappedValues = [];\n let idx = 0;\n for (const item of this._sourceList) {\n this._eventQueue.push(new AddEvent(idx, item));\n idx += 1;\n }\n void this._flush();\n }\n\n async _flush(): Promise {\n if (this._flushing) {\n return;\n }\n this._flushing = true;\n try {\n while (this._eventQueue!.length) {\n const event = this._eventQueue!.shift();\n await event!.run(this);\n }\n } finally {\n this._flushing = false;\n }\n }\n\n onReset(): void {\n if (this._eventQueue) {\n this._eventQueue.push(new ResetEvent());\n void this._flush();\n }\n }\n\n onAdd(index: number, value: F): void {\n if (this._eventQueue) {\n this._eventQueue.push(new AddEvent(index, value));\n void this._flush();\n }\n }\n\n onUpdate(index: number, value: F, params: any): void {\n if (this._eventQueue) {\n this._eventQueue.push(new UpdateEvent(index, value, params));\n void this._flush();\n }\n }\n\n onRemove(index: number): void {\n if (this._eventQueue) {\n this._eventQueue.push(new RemoveEvent(index));\n void this._flush();\n }\n }\n\n onMove(fromIdx: number, toIdx: number): void {\n if (this._eventQueue) {\n this._eventQueue.push(new MoveEvent(fromIdx, toIdx));\n void this._flush();\n }\n }\n\n onUnsubscribeLast(): void {\n this._sourceUnsubscribe!();\n this._eventQueue = null;\n this._mappedValues = null;\n }\n}\n\ntype AsyncEvent = AddEvent | UpdateEvent | RemoveEvent | MoveEvent | ResetEvent\n\nclass AddEvent {\n constructor(public index: number, public value: F) {}\n\n async run(list: AsyncMappedList): Promise {\n const mappedValue = await list._mapper(this.value);\n runAdd(list, this.index, mappedValue);\n }\n}\n\nclass UpdateEvent {\n constructor(public index: number, public value: F, public params: any) {}\n\n async run(list: AsyncMappedList): Promise {\n runUpdate(list, this.index, this.value, this.params);\n }\n}\n\nclass RemoveEvent {\n constructor(public index: number) {}\n\n async run(list: AsyncMappedList): Promise {\n runRemove(list, this.index);\n }\n}\n\nclass MoveEvent {\n constructor(public fromIdx: number, public toIdx: number) {}\n\n async run(list: AsyncMappedList): Promise {\n runMove(list, this.fromIdx, this.toIdx);\n }\n}\n\nclass ResetEvent {\n async run(list: AsyncMappedList): Promise {\n runReset(list);\n }\n}\n\nimport {ObservableArray} from \"./ObservableArray\";\nimport {ListObserver} from \"../../mocks/ListObserver.js\";\n\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n return {\n \"events are emitted in order\": async (assert): Promise => {\n const double = (n: number): number => n * n;\n const source = new ObservableArray();\n const mapper = new AsyncMappedList(source, async n => {\n await new Promise(r => setTimeout(r, n));\n return {n: double(n)};\n }, (o, params, n) => {\n o.n = double(n);\n });\n const observer = new ListObserver();\n mapper.subscribe(observer);\n source.append(2); // will sleep this amount, so second append would take less time\n source.append(1);\n source.update(0, 7, \"lucky seven\");\n source.remove(0);\n {\n const {type, index, value} = await observer.next();\n assert.equal(mapper.length, 1);\n assert.equal(type, \"add\");\n assert.equal(index, 0);\n assert.equal(value.n, 4);\n }\n {\n const {type, index, value} = await observer.next();\n assert.equal(mapper.length, 2);\n assert.equal(type, \"add\");\n assert.equal(index, 1);\n assert.equal(value.n, 1);\n }\n {\n const {type, index, value, params} = await observer.next();\n assert.equal(mapper.length, 2);\n assert.equal(type, \"update\");\n assert.equal(index, 0);\n assert.equal(value.n, 49);\n assert.equal(params, \"lucky seven\");\n }\n {\n const {type, index, value} = await observer.next();\n assert.equal(mapper.length, 1);\n assert.equal(type, \"remove\");\n assert.equal(index, 0);\n assert.equal(value.n, 49);\n }\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList, IListObserver} from \"./BaseObservableList\";\n\nexport class ConcatList extends BaseObservableList implements IListObserver {\n protected _sourceLists: BaseObservableList[];\n protected _sourceUnsubscribes: (() => void)[] | null = null;\n\n constructor(...sourceLists: BaseObservableList[]) {\n super();\n this._sourceLists = sourceLists;\n }\n\n _offsetForSource(sourceList: BaseObservableList): number {\n const listIdx = this._sourceLists.indexOf(sourceList);\n let offset = 0;\n for (let i = 0; i < listIdx; ++i) {\n offset += this._sourceLists[i].length;\n }\n return offset;\n }\n\n onSubscribeFirst(): void {\n this._sourceUnsubscribes = this._sourceLists.map(sourceList => sourceList.subscribe(this));\n }\n\n onUnsubscribeLast(): void {\n for (const sourceUnsubscribe of this._sourceUnsubscribes!) {\n sourceUnsubscribe();\n }\n }\n\n onReset(): void {\n // TODO: not ideal if other source lists are large\n // but working impl for now\n // reset, and\n this.emitReset();\n let idx = 0;\n for(const item of this) {\n this.emitAdd(idx, item);\n idx += 1;\n }\n }\n\n onAdd(index: number, value: T, sourceList: BaseObservableList): void {\n this.emitAdd(this._offsetForSource(sourceList) + index, value);\n }\n\n onUpdate(index: number, value: T, params: any, sourceList: BaseObservableList): void {\n // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it\n // as we are not supposed to call `length` on any uninitialized list\n if (!this._sourceUnsubscribes) {\n return;\n }\n this.emitUpdate(this._offsetForSource(sourceList) + index, value, params);\n }\n\n onRemove(index: number, value: T, sourceList: BaseObservableList): void {\n this.emitRemove(this._offsetForSource(sourceList) + index, value);\n }\n\n onMove(fromIdx: number, toIdx: number, value: T, sourceList: BaseObservableList): void {\n const offset = this._offsetForSource(sourceList);\n this.emitMove(offset + fromIdx, offset + toIdx, value);\n }\n\n get length(): number {\n let len = 0;\n for (let i = 0; i < this._sourceLists.length; ++i) {\n len += this._sourceLists[i].length;\n }\n return len;\n }\n\n [Symbol.iterator](): Iterator {\n let sourceListIdx = 0;\n let it = this._sourceLists[0][Symbol.iterator]();\n return {\n next: (): IteratorResult => {\n let result = it.next();\n while (result.done) {\n sourceListIdx += 1;\n if (sourceListIdx >= this._sourceLists.length) {\n return result; //done\n }\n it = this._sourceLists[sourceListIdx][Symbol.iterator]();\n result = it.next();\n }\n return result;\n }\n };\n }\n}\n\nimport {ObservableArray} from \"./ObservableArray\";\nimport {defaultObserverWith} from \"./BaseObservableList\";\n\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport async function tests() {\n return {\n test_length(assert): void {\n const all = new ConcatList(\n new ObservableArray([1, 2, 3]),\n new ObservableArray([11, 12, 13])\n );\n assert.equal(all.length, 6);\n },\n test_iterator(assert): void {\n const all = new ConcatList(\n new ObservableArray([1, 2, 3]),\n new ObservableArray([11, 12, 13])\n );\n const it = all[Symbol.iterator]();\n assert.equal(it.next().value, 1);\n assert.equal(it.next().value, 2);\n assert.equal(it.next().value, 3);\n assert.equal(it.next().value, 11);\n assert.equal(it.next().value, 12);\n assert.equal(it.next().value, 13);\n assert(it.next().done);\n },\n test_add(assert): void {\n const list1 = new ObservableArray([1, 2, 3]);\n const list2 = new ObservableArray([11, 12, 13]);\n const all = new ConcatList(list1, list2);\n let fired = false;\n all.subscribe(defaultObserverWith({\n onAdd(index, value) {\n fired = true;\n assert.equal(index, 4);\n assert.equal(value, 11.5);\n }\n }));\n list2.insert(1, 11.5);\n assert(fired);\n },\n test_update(assert): void {\n const list1 = new ObservableArray([1, 2, 3]);\n const list2 = new ObservableArray([11, 12, 13]);\n const all = new ConcatList(list1, list2);\n let fired = false;\n all.subscribe(defaultObserverWith({\n onUpdate(index, value) {\n fired = true;\n assert.equal(index, 4);\n assert.equal(value, 10);\n }\n }));\n list2.emitUpdate(1, 10);\n assert(fired);\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\nimport {sortedIndex} from \"../../utils/sortedIndex\";\n\n/*\n\nwhen a value changes, it sorting order can change. It would still be at the old index prior to firing an onUpdate event.\nSo how do you know where it was before it changed, if not by going over all values?\n\nhow to make this fast?\n\nseems hard to solve with an array, because you need to map the key to it's previous location somehow, to efficiently find it,\nand move it.\n\nI wonder if we could do better with a binary search tree (BST).\nThe tree has a value with {key, value}. There is a plain Map mapping keys to this tuple,\nfor easy lookup. Now how do we find the index of this tuple in the BST?\n\neither we store in every node the amount of nodes on the left and right, or we decend into the part\nof the tree preceding the node we want to know about. Updating the counts upwards would probably be fine as this is log2 of\nthe size of the container.\n\nto be able to go from a key to an index, the value would have the have a link with the tree node though\n\nso key -> Map -> value -> node -> *parentNode -> rootNode\nwith a node containing {value, leftCount, rightCount, leftNode, rightNode, parentNode}\n*/\n\n// does not assume whether or not the values are reference\n// types modified outside of the collection (and affecting sort order) or not\n\n// no duplicates allowed for now\nexport class SortedMapList extends BaseObservableList {\n constructor(sourceMap, comparator) {\n super();\n this._sourceMap = sourceMap;\n this._comparator = (a, b) => comparator(a.value, b.value);\n this._sortedPairs = null;\n this._mapSubscription = null;\n }\n\n onAdd(key, value) {\n const pair = {key, value};\n const idx = sortedIndex(this._sortedPairs, pair, this._comparator);\n this._sortedPairs.splice(idx, 0, pair);\n this.emitAdd(idx, value);\n }\n\n onRemove(key, value) {\n const pair = {key, value};\n const idx = sortedIndex(this._sortedPairs, pair, this._comparator);\n // assert key === this._sortedPairs[idx].key;\n this._sortedPairs.splice(idx, 1);\n this.emitRemove(idx, value);\n }\n\n onUpdate(key, value, params) {\n // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it\n if (!this._sortedPairs) {\n return;\n }\n // TODO: suboptimal for performance, see above for idea with BST to speed this up if we need to\n const oldIdx = this._sortedPairs.findIndex(p => p.key === key);\n // neccesary to remove pair from array before\n // doing sortedIndex as it relies on being sorted\n this._sortedPairs.splice(oldIdx, 1);\n const pair = {key, value};\n const newIdx = sortedIndex(this._sortedPairs, pair, this._comparator);\n this._sortedPairs.splice(newIdx, 0, pair);\n if (oldIdx !== newIdx) {\n this.emitMove(oldIdx, newIdx, value);\n }\n this.emitUpdate(newIdx, value, params);\n }\n\n onReset() {\n this._sortedPairs = [];\n this.emitReset();\n }\n\n onSubscribeFirst() {\n this._mapSubscription = this._sourceMap.subscribe(this);\n this._sortedPairs = new Array(this._sourceMap.size);\n let i = 0;\n for (let [key, value] of this._sourceMap) {\n this._sortedPairs[i] = {key, value};\n ++i;\n }\n this._sortedPairs.sort(this._comparator);\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast() {\n super.onUnsubscribeLast();\n this._sortedPairs = null;\n this._mapSubscription = this._mapSubscription();\n }\n\n get(index) {\n return this._sortedPairs[index].value;\n }\n\n get length() {\n return this._sourceMap.size;\n }\n\n [Symbol.iterator]() {\n const it = this._sortedPairs.values();\n return {\n next() {\n const v = it.next();\n if (v.value) {\n v.value = v.value.value;\n }\n return v;\n }\n };\n }\n}\n\nimport {ObservableMap} from \"../\";\n\nexport function tests() {\n return {\n test_sortIndex(assert) {\n const a = [1, 5, 6, 8];\n const cmp = (a, b) => a - b;\n let idx = sortedIndex(a, 0, cmp);\n assert.equal(idx, 0);\n idx = sortedIndex(a, 3, cmp);\n assert.equal(idx, 1);\n idx = sortedIndex(a, 5, cmp);\n assert.equal(idx, 1);\n idx = sortedIndex(a, 8, cmp);\n assert.equal(idx, 3);\n },\n\n test_sortIndex_reverse(assert) {\n let idx = sortedIndex([8, 6, 5, 1], 6, (a, b) => b - a);\n assert.equal(idx, 1);\n },\n\n test_sortIndex_comparator_Array_compatible(assert) {\n const a = [5, 1, 8, 2];\n const cmp = (a, b) => a - b;\n a.sort(cmp);\n assert.deepEqual(a, [1, 2, 5, 8]);\n let idx = sortedIndex(a, 2, cmp);\n assert.equal(idx, 1);\n },\n\n test_initial_values(assert) {\n const map = new ObservableMap([\n [\"a\", 50],\n [\"b\", 6],\n [\"c\", -5],\n ]);\n const list = new SortedMapList(map, (a, b) => a - b);\n list.subscribe({}); //needed to populate iterator\n assert.deepEqual(Array.from(list), [-5, 6, 50]);\n assert.equal(list.length, 3);\n },\n\n test_add(assert) {\n const map = new ObservableMap([[\"a\", 50], [\"b\", 6], [\"c\", -5]]);\n const list = new SortedMapList(map, (a, b) => a - b);\n let fired = 0;\n list.subscribe({\n onAdd(idx, value) {\n fired++;\n assert.equal(idx, 2);\n assert.equal(value, 20);\n }\n });\n map.add(\"d\", 20);\n assert.equal(fired, 1);\n assert.equal(list.length, 4);\n },\n\n test_remove(assert) {\n const map = new ObservableMap([[\"a\", 50], [\"b\", 6], [\"c\", -5]]);\n const list = new SortedMapList(map, (a, b) => a - b);\n let fired = 0;\n list.subscribe({\n onRemove(idx, value) {\n fired++;\n assert.equal(idx, 2);\n assert.equal(value, 50);\n }\n });\n map.remove(\"a\");\n assert.equal(fired, 1);\n assert.equal(list.length, 2);\n },\n\n test_move_reference(assert) {\n const a = {number: 3};\n const map = new ObservableMap([\n [\"a\", a],\n [\"b\", {number: 11}],\n [\"c\", {number: 1}],\n ]);\n const list = new SortedMapList(map, (a, b) => a.number - b.number);\n let updateFired = 0, moveFired = 0;\n list.subscribe({\n onUpdate(idx, value, param) {\n updateFired++;\n assert.equal(idx, 2);\n assert.equal(value, a);\n assert.equal(param, \"number\");\n },\n\n onMove(oldIdx, newIdx, value) {\n moveFired++;\n assert.equal(oldIdx, 1);\n assert.equal(newIdx, 2);\n assert.equal(value, a);\n }\n });\n a.number = 111;\n map.update(\"a\", \"number\");\n assert.equal(moveFired, 1);\n assert.equal(updateFired, 1);\n },\n\n test_update_without_move(assert) {\n const a = {number: 3};\n const map = new ObservableMap([\n [\"a\", a],\n [\"b\", {number: 11}],\n [\"c\", {number: 1}],\n ]);\n const list = new SortedMapList(map, (a, b) => a.number - b.number);\n let updateFired = 0, moveFired = 0;\n list.subscribe({\n onUpdate(idx, value, param) {\n updateFired++;\n assert.equal(idx, 1);\n assert.equal(value, a);\n assert.equal(param, \"number\");\n },\n\n onMove() {\n moveFired++;\n }\n });\n assert.deepEqual(Array.from(list).map(v => v.number), [1, 3, 11]);\n // asume some part of a that doesn't affect\n // sorting order has changed here\n map.update(\"a\", \"number\");\n assert.equal(moveFired, 0);\n assert.equal(updateFired, 1);\n assert.deepEqual(Array.from(list).map(v => v.number), [1, 3, 11]);\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservable} from \"../BaseObservable\";\nimport {JoinedMap} from \"./index\";\nimport {MappedMap} from \"./index\";\nimport {FilteredMap} from \"./index\";\nimport {BaseObservableValue, MapSizeObservableValue} from \"../value/index\";\nimport {SortedMapList} from \"../list/SortedMapList.js\";\n\n\nexport interface IMapObserver {\n onReset(): void;\n onAdd(key: K, value:V): void;\n onUpdate(key: K, value: V, params: any): void;\n onRemove(key: K, value: V): void\n}\n\n/*\nThis class MUST never be imported directly from here.\nInstead, it MUST be imported from index.ts. See the\ntop level comment in index.ts for details.\n*/\nexport abstract class BaseObservableMap extends BaseObservable> {\n\n constructor() {\n super();\n }\n\n emitReset(): void {\n for(let h of this._handlers) {\n h.onReset();\n }\n }\n // we need batch events, mostly on index based collection though?\n // maybe we should get started without?\n emitAdd(key: K, value: V): void {\n for(let h of this._handlers) {\n h.onAdd(key, value);\n }\n }\n\n emitUpdate(key: K, value: V, params: any): void {\n for(let h of this._handlers) {\n h.onUpdate(key, value, params);\n }\n }\n\n emitRemove(key: K, value: V): void {\n for(let h of this._handlers) {\n h.onRemove(key, value);\n }\n }\n\n join>(...otherMaps: Array): JoinedMap {\n return new JoinedMap([this as BaseObservableMap].concat(otherMaps));\n }\n\n mapValues(mapper: Mapper, updater?: Updater): MappedMap {\n return new MappedMap(this, mapper, updater);\n }\n\n sortValues(comparator: Comparator): SortedMapList {\n return new SortedMapList(this, comparator);\n }\n\n filterValues(filter: Filter): FilteredMap {\n return new FilteredMap(this, filter);\n }\n\n observeSize(): BaseObservableValue {\n return new MapSizeObservableValue(this);\n }\n\n abstract [Symbol.iterator](): Iterator<[K, V]>;\n abstract get size(): number;\n abstract get(key: K): V | undefined;\n}\n\nexport type Mapper = (\n value: V,\n emitSpontaneousUpdate: any,\n) => MappedV;\n\nexport type Updater = (params: any, mappedValue?: MappedV, value?: V) => void;\n\nexport type Comparator = (a: V, b: V) => number;\n\nexport type Filter = (v: V, k: K) => boolean;\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableMap} from \"./index\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\n\n/*\nThis class MUST never be imported directly from here.\nInstead, it MUST be imported from index.ts. See the\ntop level comment in index.ts for details.\n*/\nexport class ApplyMap extends BaseObservableMap {\n private _source: BaseObservableMap;\n private _subscription?: SubscriptionHandle;\n private _apply?: Apply;\n\n constructor(source: BaseObservableMap, apply?: Apply) {\n super();\n this._source = source;\n this._apply = apply;\n }\n\n hasApply(): boolean {\n return !!this._apply;\n }\n\n setApply(apply?: Apply): void {\n this._apply = apply;\n if (this._apply) {\n this.applyOnce(this._apply);\n }\n }\n\n applyOnce(apply: Apply): void {\n for (const [key, value] of this._source) {\n apply(key, value);\n }\n }\n\n onAdd(key: K, value: V): void {\n if (this._apply) {\n this._apply(key, value);\n }\n this.emitAdd(key, value);\n }\n\n onRemove(key: K, value: V): void {\n this.emitRemove(key, value);\n }\n\n onUpdate(key: K, value: V, params: any): void {\n if (this._apply) {\n this._apply(key, value, params);\n }\n this.emitUpdate(key, value, params);\n }\n\n onSubscribeFirst(): void {\n this._subscription = this._source.subscribe(this);\n if (this._apply) {\n this.applyOnce(this._apply);\n }\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n if (this._subscription) {\n this._subscription = this._subscription();\n }\n }\n\n onReset(): void {\n if (this._apply) {\n this.applyOnce(this._apply);\n }\n this.emitReset();\n }\n\n [Symbol.iterator](): Iterator<[K, V]> {\n return this._source[Symbol.iterator]();\n }\n\n get size(): number {\n return this._source.size;\n }\n\n get(key: K): V | undefined {\n return this._source.get(key);\n }\n}\n\ntype Apply = (key: K, value: V, params?: any) => void;","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableMap, Filter} from \"./index\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\n\n/*\nThis class MUST never be imported directly from here.\nInstead, it MUST be imported from index.ts. See the\ntop level comment in index.ts for details.\n*/\nexport class FilteredMap extends BaseObservableMap {\n private _source: BaseObservableMap;\n private _filter: Filter;\n private _included?: Map;\n private _subscription?: SubscriptionHandle;\n\n constructor(source: BaseObservableMap, filter: Filter) {\n super();\n this._source = source;\n this._filter = filter;\n }\n\n setFilter(filter: Filter): void {\n this._filter = filter;\n if (this._subscription) {\n this._reapplyFilter();\n }\n }\n\n /**\n * reapply the filter\n */\n _reapplyFilter(silent = false): void {\n if (this._filter) {\n this._included = this._included || new Map();\n for (const [key, value] of this._source) {\n const isIncluded = this._filter(value, key);\n const oldIncluded = this._included.get(key);\n this._included.set(key, isIncluded);\n if (!silent) {\n const wasIncluded = oldIncluded ? oldIncluded : true;\n this._emitForUpdate(wasIncluded, isIncluded, key, value);\n }\n }\n } else { // no filter\n // did we have a filter before?\n if (this._included && !silent) {\n // add any non-included items again\n for (const [key, value] of this._source) {\n if (!this._included.get(key)) {\n this.emitAdd(key, value);\n }\n }\n }\n this._included = undefined;\n }\n }\n\n onAdd(key: K, value: V): void {\n if (this._filter) {\n if (this._included) {\n const included = this._filter(value, key);\n this._included.set(key, included);\n if (!included) {\n return;\n }\n } else {\n throw new Error(\"Internal logic error: FilteredMap._included used before initialized\");\n }\n }\n this.emitAdd(key, value);\n }\n\n onRemove(key: K, value: V): void {\n const wasIncluded = !this._filter || this._included?.get(key);\n if (this._included) {\n this._included.delete(key);\n if (wasIncluded) {\n this.emitRemove(key, value);\n }\n } else {\n throw new Error(\"Internal logic error: FilteredMap._included used before initialized\");\n }\n }\n\n onUpdate(key: K, value: V, params: any): void {\n // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it\n if (!this._included) {\n return;\n }\n if (this._filter) {\n const wasIncluded = this._included.get(key);\n const isIncluded = this._filter(value, key);\n this._included.set(key, isIncluded);\n this._emitForUpdate(wasIncluded, isIncluded, key, value, params);\n } else {\n this.emitUpdate(key, value, params);\n }\n }\n\n _emitForUpdate(wasIncluded: boolean | undefined, isIncluded: boolean, key: K, value: V, params: any = null): void {\n if (wasIncluded && !isIncluded) {\n this.emitRemove(key, value);\n } else if (!wasIncluded && isIncluded) {\n this.emitAdd(key, value);\n } else if (wasIncluded && isIncluded) {\n this.emitUpdate(key, value, params);\n }\n }\n\n onSubscribeFirst(): void {\n this._subscription = this._source.subscribe(this);\n this._reapplyFilter(true);\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n this._included = undefined;\n if (this._subscription) {\n this._subscription = this._subscription();\n }\n }\n\n onReset(): void {\n this._reapplyFilter();\n this.emitReset();\n }\n\n [Symbol.iterator](): FilterIterator {\n return new FilterIterator(this._source, this._included);\n }\n\n get size(): number {\n let count = 0;\n this._included?.forEach(included => {\n if (included) {\n count += 1;\n }\n });\n return count;\n }\n\n get(key: K): V | undefined {\n const value = this._source.get(key);\n if (value && this._filter(value, key)) {\n return value;\n }\n }\n}\n\nclass FilterIterator {\n private _included?: Map\n private _sourceIterator: Iterator<[K, V], any, undefined>\n constructor(map: BaseObservableMap, included?: Map) {\n this._included = included;\n this._sourceIterator = map[Symbol.iterator]();\n }\n\n next(): IteratorResult<[K, V]> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const sourceResult = this._sourceIterator.next();\n if (sourceResult.done) {\n return sourceResult;\n }\n const key = sourceResult.value[0];\n if (this._included?.get(key)) {\n return sourceResult;\n }\n }\n }\n}\n\nimport {ObservableMap} from \"..\";\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n return {\n \"filter preloaded list\": (assert): void => {\n const source = new ObservableMap();\n source.add(\"one\", 1);\n source.add(\"two\", 2);\n source.add(\"three\", 3);\n const oddNumbers = new FilteredMap(source, (x: number) => x % 2 !== 0);\n // can only iterate after subscribing\n oddNumbers.subscribe({\n onAdd() {\n return;\n },\n onRemove() {\n return;\n },\n onUpdate() {\n return;\n },\n onReset() {\n return;\n },\n });\n assert.equal(oddNumbers.size, 2);\n const it = oddNumbers[Symbol.iterator]();\n assert.deepEqual(it.next().value, [\"one\", 1]);\n assert.deepEqual(it.next().value, [\"three\", 3]);\n assert.equal(it.next().done, true);\n },\n // \"filter added values\": (assert): void => {\n\n // },\n // \"filter removed values\": (assert): void => {\n\n // },\n // \"filter changed values\": (assert): void => {\n\n // },\n\n \"emits must trigger once\": (assert): void => {\n const source = new ObservableMap();\n let count_add = 0, count_update = 0, count_remove = 0;\n source.add(\"num1\", 1);\n source.add(\"num2\", 2);\n source.add(\"num3\", 3);\n const oddMap = new FilteredMap(source, (x: number) => x % 2 !== 0);\n oddMap.subscribe({\n onAdd() {\n count_add += 1;\n },\n onRemove() {\n count_remove += 1;\n },\n onUpdate() {\n count_update += 1;\n },\n onReset() {\n return;\n }\n });\n source.set(\"num3\", 4);\n source.set(\"num3\", 5);\n source.set(\"num3\", 7);\n assert.strictEqual(count_add, 1);\n assert.strictEqual(count_update, 1);\n assert.strictEqual(count_remove, 1);\n }\n };\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableMap} from \".\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\n\n/*\nThis class MUST never be imported directly from here.\nInstead, it MUST be imported from index.ts. See the\ntop level comment in index.ts for details.\n*/\nexport class JoinedMap extends BaseObservableMap {\n protected _sources: BaseObservableMap[];\n private _subscriptions?: SourceSubscriptionHandler[];\n\n constructor(sources: BaseObservableMap[]) {\n super();\n this._sources = sources;\n }\n\n onAdd(source: BaseObservableMap, key: K, value: V): void {\n if (!this._isKeyAtSourceOccluded(source, key)) {\n const occludingValue = this._getValueFromOccludedSources(source, key);\n if (occludingValue !== undefined) {\n // adding a value that will occlude another one should\n // first emit a remove\n this.emitRemove(key, occludingValue);\n }\n this.emitAdd(key, value);\n }\n }\n\n onRemove(source: BaseObservableMap, key: K, value: V): void {\n if (!this._isKeyAtSourceOccluded(source, key)) {\n this.emitRemove(key, value);\n const occludedValue = this._getValueFromOccludedSources(source, key);\n if (occludedValue !== undefined) {\n // removing a value that so far occluded another one should\n // emit an add for the occluded value after the removal\n this.emitAdd(key, occludedValue);\n }\n }\n }\n\n onUpdate(source: BaseObservableMap, key: K, value: V, params: any): void {\n // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it\n if (!this._subscriptions) {\n return;\n }\n if (!this._isKeyAtSourceOccluded(source, key)) {\n this.emitUpdate(key, value, params);\n }\n }\n\n onReset(): void {\n this.emitReset();\n }\n\n onSubscribeFirst(): void {\n this._subscriptions = this._sources.map(source => new SourceSubscriptionHandler(source, this).subscribe());\n super.onSubscribeFirst();\n }\n\n _isKeyAtSourceOccluded(source: BaseObservableMap, key: K): boolean {\n // sources that come first in the sources array can\n // hide the keys in later sources, to prevent events\n // being emitted for the same key and different values,\n // so check the key is not present in earlier sources\n const index = this._sources.indexOf(source);\n for (let i = 0; i < index; i += 1) {\n if (this._sources[i].get(key) !== undefined) {\n return true;\n }\n }\n return false;\n }\n\n // get the value that the given source and key occlude, if any\n _getValueFromOccludedSources(source: BaseObservableMap, key: K): V | undefined{\n // sources that come first in the sources array can\n // hide the keys in later sources, to prevent events\n // being emitted for the same key and different values,\n // so check the key is not present in earlier sources\n const index = this._sources.indexOf(source);\n for (let i = index + 1; i < this._sources.length; i += 1) {\n const source = this._sources[i];\n const occludedValue = source.get(key);\n if (occludedValue !== undefined) {\n return occludedValue;\n }\n }\n return undefined;\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n if (this._subscriptions) {\n for (const s of this._subscriptions) {\n s.dispose();\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n [Symbol.iterator]() {\n return new JoinedIterator(this._sources);\n }\n\n get size(): number {\n return this._sources.reduce((sum, s) => sum + s.size, 0);\n }\n\n get(key: K): V | undefined {\n for (const s of this._sources) {\n const value = s.get(key);\n if (value) {\n return value;\n }\n }\n return undefined;\n }\n}\n\nclass JoinedIterator implements Iterator<[K, V]> {\n private _sources: {[Symbol.iterator](): Iterator<[K, V]>}[];\n private _sourceIndex = -1;\n private _encounteredKeys = new Set();\n private _currentIterator?: Iterator<[K, V]>\n\n constructor(sources: {[Symbol.iterator](): Iterator<[K, V]>}[]) {\n this._sources = sources;\n }\n\n next(): IteratorYieldResult<[K, V]> | IteratorReturnResult {\n let result: IteratorYieldResult<[K, V]> | undefined = undefined;\n while (!result) {\n if (!this._currentIterator) {\n this._sourceIndex += 1;\n if (this._sources.length <= this._sourceIndex) {\n return {done: true, value: null};\n }\n this._currentIterator = this._sources[this._sourceIndex][Symbol.iterator]();\n }\n const sourceResult = this._currentIterator?.next();\n if (!sourceResult || sourceResult.done) {\n this._currentIterator = undefined;\n continue;\n } else {\n const key = sourceResult.value[0];\n if (!this._encounteredKeys.has(key)) {\n this._encounteredKeys.add(key);\n result = sourceResult;\n }\n }\n }\n return result;\n }\n}\n\nclass SourceSubscriptionHandler {\n private _source: BaseObservableMap;\n private _joinedMap: JoinedMap;\n private _subscription?: SubscriptionHandle;\n\n constructor(source: BaseObservableMap, joinedMap: JoinedMap) {\n this._source = source;\n this._joinedMap = joinedMap;\n this._subscription = undefined;\n }\n\n subscribe(): this {\n this._subscription = this._source.subscribe(this);\n return this;\n }\n\n dispose(): void {\n if (this._subscription) this._subscription = this._subscription();\n }\n\n onAdd(key: K, value: V): void {\n this._joinedMap.onAdd(this._source, key, value);\n }\n\n onRemove(key: K, value: V): void {\n this._joinedMap.onRemove(this._source, key, value);\n }\n\n onUpdate(key: K, value: V, params: any): void {\n this._joinedMap.onUpdate(this._source, key, value, params);\n }\n\n onReset(): void {\n this._joinedMap.onReset();\n }\n}\n\n\nimport {ObservableMap} from \"..\";\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n function observeMap(map: JoinedMap): { type: string; key: any; value: any; params?: any; }[] {\n const events: { type: string, key: any, value: any, params?: any }[] = [];\n map.subscribe({\n onAdd(key, value) { events.push({ type: \"add\", key, value }); },\n onRemove(key, value) { events.push({ type: \"remove\", key, value }); },\n onUpdate(key, value, params) { events.push({ type: \"update\", key, value, params }); },\n onReset: function (): void {\n return;\n }\n });\n return events;\n }\n\n return {\n \"joined iterator\": (assert): void => {\n const firstKV: [string, number] = [\"a\", 1];\n const secondKV: [string, number] = [\"b\", 2];\n const thirdKV: [string, number] = [\"c\", 3];\n const it = new JoinedIterator([[firstKV, secondKV], [thirdKV]]);\n assert.equal(it.next().value, firstKV);\n assert.equal(it.next().value, secondKV);\n assert.equal(it.next().value, thirdKV);\n assert.equal(it.next().done, true);\n },\n \"prevent key collision during iteration\": (assert): void => {\n const first = new ObservableMap();\n const second = new ObservableMap();\n const join = new JoinedMap([first, second]);\n second.add(\"a\", 2);\n second.add(\"b\", 3);\n first.add(\"a\", 1);\n const it = join[Symbol.iterator]();\n assert.deepEqual(it.next().value, [\"a\", 1]);\n assert.deepEqual(it.next().value, [\"b\", 3]);\n assert.equal(it.next().done, true);\n },\n \"adding occluded key doesn't emit add\": (assert): void => {\n const first = new ObservableMap();\n const second = new ObservableMap();\n const join = new JoinedMap([first, second]);\n const events = observeMap(join);\n first.add(\"a\", 1);\n second.add(\"a\", 2);\n assert.equal(events.length, 1);\n assert.equal(events[0].type, \"add\");\n assert.equal(events[0].key, \"a\");\n assert.equal(events[0].value, 1);\n },\n \"updating occluded key doesn't emit update\": (assert): void => {\n const first = new ObservableMap();\n const second = new ObservableMap();\n const join = new JoinedMap([first, second]);\n first.add(\"a\", 1);\n second.add(\"a\", 2);\n const events = observeMap(join);\n second.update(\"a\", 3);\n assert.equal(events.length, 0);\n },\n \"removal of occluding key emits add after remove\": (assert): void => {\n const first = new ObservableMap();\n const second = new ObservableMap();\n const join = new JoinedMap([first, second]);\n first.add(\"a\", 1);\n second.add(\"a\", 2);\n const events = observeMap(join);\n first.remove(\"a\");\n assert.equal(events.length, 2);\n assert.equal(events[0].type, \"remove\");\n assert.equal(events[0].key, \"a\");\n assert.equal(events[0].value, 1);\n assert.equal(events[1].type, \"add\");\n assert.equal(events[1].key, \"a\");\n assert.equal(events[1].value, 2);\n },\n \"adding occluding key emits remove first\": (assert): void => {\n const first = new ObservableMap();\n const second = new ObservableMap();\n const join = new JoinedMap([first, second]);\n second.add(\"a\", 2);\n const events = observeMap(join);\n first.add(\"a\", 1);\n assert.equal(events.length, 2);\n assert.equal(events[0].type, \"remove\");\n assert.equal(events[0].key, \"a\");\n assert.equal(events[0].value, 2);\n assert.equal(events[1].type, \"add\");\n assert.equal(events[1].key, \"a\");\n assert.equal(events[1].value, 1);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableMap, Mapper, Updater} from \"./index\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\n\n/*\nso a mapped value can emit updates on it's own with this._emitSpontaneousUpdate that is passed in the mapping function\nhow should the mapped value be notified of an update though? and can it then decide to not propagate the update?\n*/\n/*\nThis class MUST never be imported directly from here.\nInstead, it MUST be imported from index.ts. See the\ntop level comment in index.ts for details.\n*/\nexport class MappedMap extends BaseObservableMap {\n private _source: BaseObservableMap;\n private _mapper: Mapper;\n private _updater?: Updater;\n private _mappedValues: Map;\n private _subscription?: SubscriptionHandle;\n\n\n constructor(\n source: BaseObservableMap,\n mapper: Mapper,\n updater?: Updater\n ) {\n super();\n this._source = source;\n this._mapper = mapper;\n this._updater = updater;\n this._mappedValues = new Map();\n }\n\n _emitSpontaneousUpdate(key: K, params: any): void {\n const value = this._mappedValues.get(key);\n if (value) {\n this.emitUpdate(key, value, params);\n }\n }\n\n onAdd(key: K, value: V): void {\n const emitSpontaneousUpdate = this._emitSpontaneousUpdate.bind(this, key);\n const mappedValue = this._mapper(value, emitSpontaneousUpdate);\n this._mappedValues.set(key, mappedValue);\n this.emitAdd(key, mappedValue);\n }\n\n onRemove(key: K/*, _value*/): void {\n const mappedValue = this._mappedValues.get(key);\n if (this._mappedValues.delete(key)) {\n if (mappedValue) {\n this.emitRemove(key, mappedValue);\n }\n }\n }\n\n onUpdate(key: K, value: V, params: any): void {\n // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it\n if (!this._mappedValues) {\n return;\n }\n const mappedValue = this._mappedValues.get(key);\n if (mappedValue !== undefined) {\n this._updater?.(params, mappedValue, value);\n // TODO: map params somehow if needed?\n this.emitUpdate(key, mappedValue, params);\n }\n }\n\n onSubscribeFirst(): void {\n this._subscription = this._source.subscribe(this);\n for (let [key, value] of this._source) {\n const emitSpontaneousUpdate = this._emitSpontaneousUpdate.bind(this, key);\n const mappedValue = this._mapper(value, emitSpontaneousUpdate);\n this._mappedValues.set(key, mappedValue);\n }\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n if (this._subscription) {\n this._subscription = this._subscription();\n }\n this._mappedValues.clear();\n }\n\n onReset(): void {\n this._mappedValues.clear();\n this.emitReset();\n }\n\n [Symbol.iterator](): IterableIterator<[K, MappedV]> {\n return this._mappedValues.entries();\n }\n\n get size(): number {\n return this._mappedValues.size;\n }\n\n get(key: K): MappedV | undefined {\n return this._mappedValues.get(key);\n }\n}","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableMap} from \"./index\";\n\n\n/*\nThis class MUST never be imported directly from here.\nInstead, it MUST be imported from index.ts. See the\ntop level comment in index.ts for details.\n*/\nexport class ObservableMap extends BaseObservableMap {\n private readonly _values: Map;\n\n constructor(initialValues?: (readonly [K, V])[]) {\n super();\n this._values = new Map(initialValues);\n }\n\n update(key: K, params?: any): boolean {\n const value = this._values.get(key);\n if (value !== undefined) {\n // could be the same value, so it's already updated\n // but we don't assume this here\n this._values.set(key, value);\n this.emitUpdate(key, value, params);\n return true;\n }\n return false; // or return existing value?\n }\n\n add(key: K, value: V): boolean {\n if (!this._values.has(key)) {\n this._values.set(key, value);\n this.emitAdd(key, value);\n return true;\n }\n return false; // or return existing value?\n }\n\n remove(key: K): boolean {\n const value = this._values.get(key);\n if (value !== undefined) {\n this._values.delete(key);\n this.emitRemove(key, value);\n return true;\n } else {\n return false;\n }\n }\n\n set(key: K, value: V): boolean {\n if (this._values.has(key)) {\n // We set the value here because update only supports inline updates\n this._values.set(key, value);\n return this.update(key, undefined);\n }\n else {\n return this.add(key, value);\n }\n }\n\n reset(): void {\n this._values.clear();\n this.emitReset();\n }\n\n get(key: K): V | undefined {\n return this._values.get(key);\n }\n\n get size(): number {\n return this._values.size;\n }\n\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this._values.entries();\n }\n\n values(): IterableIterator {\n return this._values.values();\n }\n\n keys(): IterableIterator {\n return this._values.keys();\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n return {\n test_initial_values(assert): void {\n const map = new ObservableMap([\n [\"a\", 5],\n [\"b\", 10]\n ]);\n assert.equal(map.size, 2);\n assert.equal(map.get(\"a\"), 5);\n assert.equal(map.get(\"b\"), 10);\n },\n\n test_add(assert): void {\n let fired = 0;\n const map = new ObservableMap();\n map.subscribe({\n onAdd(key, value) {\n fired += 1;\n assert.equal(key, 1);\n assert.deepEqual(value, {value: 5});\n },\n onUpdate() {},\n onRemove() {},\n onReset() {}\n });\n map.add(1, {value: 5});\n assert.equal(map.size, 1);\n assert.equal(fired, 1);\n },\n\n test_update(assert): void {\n let fired = 0;\n const map = new ObservableMap();\n const value = {number: 5};\n map.add(1, value);\n map.subscribe({\n onUpdate(key, value, params) {\n fired += 1;\n assert.equal(key, 1);\n assert.deepEqual(value, {number: 6});\n assert.equal(params, \"test\");\n },\n onAdd() {},\n onRemove() {},\n onReset() {}\n });\n value.number = 6;\n map.update(1, \"test\");\n assert.equal(fired, 1);\n },\n\n test_update_unknown(assert): void {\n let fired = 0;\n const map = new ObservableMap();\n map.subscribe({\n onUpdate() { fired += 1; },\n onAdd() {},\n onRemove() {},\n onReset() {}\n });\n const result = map.update(1);\n assert.equal(fired, 0);\n assert.equal(result, false);\n },\n\n test_set(assert): void {\n let add_fired = 0, update_fired = 0;\n const map = new ObservableMap();\n map.subscribe({\n onAdd(key, value) {\n add_fired += 1;\n assert.equal(key, 1);\n assert.deepEqual(value, {value: 5});\n },\n onUpdate(key, value/*, params*/) {\n update_fired += 1;\n assert.equal(key, 1);\n assert.deepEqual(value, {value: 7});\n },\n onRemove() {},\n onReset() {}\n });\n // Add\n map.set(1, {value: 5});\n assert.equal(map.size, 1);\n assert.equal(add_fired, 1);\n // Update\n map.set(1, {value: 7});\n assert.equal(map.size, 1);\n assert.equal(update_fired, 1);\n },\n\n test_remove(assert): void {\n let fired = 0;\n const map = new ObservableMap();\n const value = {value: 5};\n map.add(1, value);\n map.subscribe({\n onRemove(key, value) {\n fired += 1;\n assert.equal(key, 1);\n assert.deepEqual(value, {value: 5});\n },\n onAdd() {},\n onUpdate() {},\n onReset() {}\n });\n map.remove(1);\n assert.equal(map.size, 0);\n assert.equal(fired, 1);\n },\n\n test_iterate(assert): void {\n const results: any[] = [];\n const map = new ObservableMap();\n map.add(1, {number: 5});\n map.add(2, {number: 6});\n map.add(3, {number: 7});\n for (let e of map) {\n results.push(e);\n }\n assert.equal(results.length, 3);\n assert.equal(results.find(([key]) => key === 1)[1].number, 5);\n assert.equal(results.find(([key]) => key === 2)[1].number, 6);\n assert.equal(results.find(([key]) => key === 3)[1].number, 7);\n },\n test_size(assert): void {\n const map = new ObservableMap();\n map.add(1, {number: 5});\n map.add(2, {number: 6});\n assert.equal(map.size, 2);\n },\n };\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableMap} from \"./BaseObservableMap\";\nimport {BaseObservableValue} from \"../value/BaseObservableValue\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\nexport class ObservableValueMap extends BaseObservableMap {\n private subscription?: SubscriptionHandle;\n\n constructor(private readonly key: K, private readonly observableValue: BaseObservableValue) {\n super();\n }\n\n onSubscribeFirst() {\n this.subscription = this.observableValue.subscribe(value => {\n this.emitUpdate(this.key, value, undefined);\n });\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast() {\n this.subscription!();\n super.onUnsubscribeLast();\n }\n\n *[Symbol.iterator](): Iterator<[K, V]> {\n yield [this.key, this.observableValue.get()];\n }\n \n get size(): number {\n return 1;\n }\n\n get(key: K): V | undefined {\n if (key == this.key) {\n return this.observableValue.get();\n }\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport {BaseObservableMap} from \"../map/index\";\nimport type {SubscriptionHandle} from \"../BaseObservable\";\n\nexport class MapSizeObservableValue extends BaseObservableValue {\n private subscription?: SubscriptionHandle;\n\n constructor(private readonly map: BaseObservableMap)\n {\n super();\n }\n\n onSubscribeFirst(): void {\n this.subscription = this.map.subscribe({\n onAdd: (key: K, value: V) => {\n this.emit(this.get());\n },\n onRemove: (key: K, value: V) => {\n this.emit(this.get());\n },\n onUpdate: (key: K, value: V) => {},\n onReset: () => {\n this.emit(this.get());\n },\n });\n }\n\n onUnsubscribeLast(): void {\n this.subscription = this.subscription?.();\n }\n\n get(): number {\n return this.map.size;\n }\n}\n\nimport {ObservableMap} from \"../map/index\";\n\nexport function tests() {\n return {\n \"emits update on add and remove\": assert => {\n const map = new ObservableMap();\n const size = new MapSizeObservableValue(map);\n const updates: number[] = [];\n size.subscribe(size => {\n updates.push(size);\n });\n map.add(\"hello\", 1);\n map.add(\"world\", 2);\n map.remove(\"world\");\n map.remove(\"hello\");\n assert.deepEqual(updates, [1, 2, 1, 0]);\n }\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n\n// WARNING: We have to be very careful about what mime-types we allow into blobs.\n//\n// This means that the content is rendered using the origin of the script which\n// called createObjectURL(), and so if the content contains any scripting then it\n// will pose a XSS vulnerability when the browser renders it. This is particularly\n// bad if the user right-clicks the URI and pastes it into a new window or tab,\n// as the blob will then execute with access to Element's full JS environment(!)\n//\n// See https://github.com/matrix-org/matrix-react-sdk/pull/1820#issuecomment-385210647\n// for details.\n//\n// We mitigate this by only allowing mime-types into blobs which we know don't\n// contain any scripting, and instantiate all others as application/octet-stream\n// regardless of what mime-type the event claimed. Even if the payload itself\n// is some malicious HTML, the fact we instantiate it with a media mimetype or\n// application/octet-stream means the browser doesn't try to render it as such.\n//\n// One interesting edge case is image/svg+xml, which empirically *is* rendered\n// correctly if the blob is set to the src attribute of an img tag (for thumbnails)\n// *even if the mimetype is application/octet-stream*. However, empirically JS\n// in the SVG isn't executed in this scenario, so we seem to be okay.\n//\n// Tested on Chrome 65 and Firefox 60\n//\n// The list below is taken mainly from\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats\n// N.B. Matrix doesn't currently specify which mimetypes are valid in given\n// events, so we pick the ones which HTML5 browsers should be able to display\n//\n// For the record, mime-types which must NEVER enter this list below include:\n// text/html, text/xhtml, image/svg, image/svg+xml, image/pdf, and similar.\n\nconst ALLOWED_BLOB_MIMETYPES = {\n 'image/jpeg': true,\n 'image/gif': true,\n 'image/png': true,\n\n 'video/mp4': true,\n 'video/webm': true,\n 'video/ogg': true,\n 'video/quicktime': true,\n 'video/VP8': true,\n\n 'audio/mp4': true,\n 'audio/webm': true,\n 'audio/aac': true,\n 'audio/mpeg': true,\n 'audio/ogg': true,\n 'audio/wave': true,\n 'audio/wav': true,\n 'audio/x-wav': true,\n 'audio/x-pn-wav': true,\n 'audio/flac': true,\n 'audio/x-flac': true,\n};\n\nconst DEFAULT_MIMETYPE = 'application/octet-stream';\n\nexport class BlobHandle {\n /** \n * @internal\n * Don't use the constructor directly, instead use fromBuffer or fromBlobUnsafe\n * */\n constructor(blob, buffer = null) {\n this._blob = blob;\n this._buffer = buffer;\n this._url = null;\n }\n\n static fromBuffer(buffer, mimetype) {\n mimetype = mimetype ? mimetype.split(\";\")[0].trim() : '';\n if (!ALLOWED_BLOB_MIMETYPES[mimetype]) {\n mimetype = DEFAULT_MIMETYPE;\n }\n return new BlobHandle(new Blob([buffer], {type: mimetype}), buffer);\n }\n\n /** Does not filter out mimetypes that could execute embedded javascript.\n * It's up to the callee of this method to ensure that the blob won't be\n * rendered by the browser in a way that could allow cross-signing scripting. */\n static fromBlobUnsafe(blob) {\n return new BlobHandle(blob);\n }\n\n get nativeBlob() {\n return this._blob;\n }\n\n async readAsBuffer() {\n if (this._buffer) {\n return this._buffer;\n } else {\n const reader = new FileReader();\n const promise = new Promise((resolve, reject) => {\n reader.addEventListener(\"load\", evt => resolve(evt.target.result)); \n reader.addEventListener(\"error\", evt => reject(evt.target.error)); \n });\n reader.readAsArrayBuffer(this._blob);\n return promise;\n }\n }\n\n get url() {\n if (!this._url) {\n this._url = URL.createObjectURL(this._blob);\n }\n return this._url;\n }\n\n get size() {\n return this._blob.size;\n }\n\n get mimeType() {\n return this._blob.type || DEFAULT_MIMETYPE;\n }\n\n dispose() {\n if (this._url) {\n URL.revokeObjectURL(this._url);\n this._url = null;\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BlobHandle} from \"../../platform/web/dom/BlobHandle.js\";\n\nexport type RequestBody = BlobHandle | string | Map;\n\nexport type EncodedBody = {\n mimeType: string;\n // the map gets transformed to a FormData object on the web\n body: RequestBody\n}\n\nexport function encodeQueryParams(queryParams?: object): string {\n return Object.entries(queryParams || {})\n .filter(([, value]) => value !== undefined)\n .map(([name, value]) => {\n if (typeof value === \"object\") {\n value = JSON.stringify(value);\n }\n return `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\n })\n .join(\"&\");\n}\n\nexport function encodeBody(body: BlobHandle | object): EncodedBody {\n if (body instanceof BlobHandle) {\n const blob = body as BlobHandle;\n return {\n mimeType: blob.mimeType,\n body: blob // will be unwrapped in request fn\n };\n } else if (body instanceof Map) {\n return {\n mimeType: \"multipart/form-data\",\n body: body\n }\n } else if (typeof body === \"object\") {\n const json = JSON.stringify(body);\n return {\n mimeType: \"application/json\",\n body: json\n }\n } else {\n throw new Error(\"Unknown body type: \" + body);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class WrappedError extends Error {\n constructor(message, cause) {\n super(`${message}: ${cause.message}`);\n this.cause = cause;\n }\n\n get name() {\n return \"WrappedError\";\n }\n}\n\nexport class HomeServerError extends Error {\n constructor(method, url, body, status) {\n super(`${body ? body.error : status} on ${method} ${url}`);\n this.errcode = body ? body.errcode : null;\n this.retry_after_ms = body ? body.retry_after_ms : 0;\n this.statusCode = status;\n }\n\n get name() {\n return \"HomeServerError\";\n }\n}\n\nexport {AbortError} from \"../utils/error\";\n\nexport class ConnectionError extends Error {\n constructor(message, isTimeout) {\n super(message || \"ConnectionError\");\n this.isTimeout = isTimeout;\n }\n\n get name() {\n return \"ConnectionError\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {HomeServerError, ConnectionError} from \"../error.js\";\nimport type {RequestResult} from \"../../platform/web/dom/request/fetch.js\";\nimport type {ILogItem} from \"../../logging/types\";\n\nexport interface IHomeServerRequest {\n abort(): void;\n response(): Promise;\n responseCode(): Promise;\n}\n\ntype HomeServerRequestOptions = {\n log?: ILogItem;\n allowedStatusCodes?: number[];\n};\n\nexport class HomeServerRequest implements IHomeServerRequest {\n private readonly _log?: ILogItem;\n private _sourceRequest?: RequestResult;\n // as we add types for expected responses from hs, this could be a generic class instead\n private readonly _promise: Promise;\n\n constructor(method: string, url: string, sourceRequest: RequestResult, options?: HomeServerRequestOptions) {\n let log: ILogItem | undefined;\n if (options?.log) {\n const parent = options?.log;\n log = parent.child({ t: \"network\", url, method, }, parent.level.Info);\n }\n this._log = log;\n this._sourceRequest = sourceRequest;\n this._promise = sourceRequest.response().then(response => {\n log?.set(\"status\", response.status);\n // ok?\n if (response.status >= 200 && response.status < 300 || options?.allowedStatusCodes?.includes(response.status)) {\n log?.finish();\n return response.body;\n } else {\n if (response.status >= 500) {\n const err = new ConnectionError(`Internal Server Error`);\n log?.catch(err);\n throw err;\n } else if (response.status >= 400 && !response.body?.errcode) {\n const err = new ConnectionError(`HTTP error status ${response.status} without errcode in body, assume this is a load balancer complaining the server is offline.`);\n log?.catch(err);\n throw err;\n } else {\n const err = new HomeServerError(method, url, response.body, response.status);\n log?.set(\"errcode\", err.errcode);\n log?.catch(err);\n throw err;\n }\n }\n }, err => {\n // if this._sourceRequest is still set,\n // the abort error came not from calling abort here\n if (err.name === \"AbortError\" && this._sourceRequest) {\n // The service worker sometimes (only on Firefox, on long, large request,\n // perhaps it has its own timeout?) aborts the request, see #187.\n // When it happens, the best thing to do seems to be to retry.\n // \n // In the service worker, we will also actively abort all\n // ongoing requests when trying to get a new service worker to activate\n // (this may surface in the app as a TypeError, which already gets mapped\n // to a ConnectionError in the request function, or an AbortError,\n // depending on the browser), as the service worker will only be\n // replaced when there are no more (fetch) events for the\n // current one to handle.\n // \n // In that case, the request function (in fetch.js) will check \n // the haltRequests flag on the service worker handler, and\n // block any new requests, as that would break the update process.\n // \n // So it is OK to return a ConnectionError here.\n // If we're updating the service worker, the /versions polling will\n // be blocked at the fetch level because haltRequests is set.\n // And for #187, retrying is the right thing to do.\n const err = new ConnectionError(`Service worker aborted, either updating or hit #187.`);\n log?.catch(err);\n throw err;\n } else {\n if (err.name === \"ConnectionError\") {\n log?.set(\"timeout\", err.isTimeout);\n }\n log?.catch(err);\n throw err;\n }\n });\n }\n\n abort(): void {\n if (this._sourceRequest) {\n this._log?.set(\"aborted\", true);\n this._sourceRequest.abort();\n // to mark that it was on purpose in above rejection handler\n this._sourceRequest = undefined;\n }\n }\n\n response(): Promise {\n return this._promise;\n }\n\n async responseCode(): Promise {\n const response = await this._sourceRequest.response();\n return response.status;\n }\n}\n\nimport {Request as MockRequest} from \"../../mocks/Request.js\";\nimport {AbortError} from \"../error.js\";\n\nexport function tests() {\n return {\n \"Response is passed through\": async assert => {\n const request = new MockRequest();\n const hsRequest = new HomeServerRequest(\"GET\", \"https://hs.tld/foo\", request);\n request.respond(200, \"foo\");\n assert.equal(await hsRequest.response(), \"foo\");\n },\n \"Unexpected AbortError is mapped to ConnectionError\": async assert => {\n const request = new MockRequest();\n const hsRequest = new HomeServerRequest(\"GET\", \"https://hs.tld/foo\", request);\n request.reject(new AbortError());\n await assert.rejects(hsRequest.response(), ConnectionError);\n },\n \"500 response is mapped to ConnectionError\": async assert => {\n const request = new MockRequest();\n const hsRequest = new HomeServerRequest(\"GET\", \"https://hs.tld/foo\", request);\n request.respond(500);\n await assert.rejects(hsRequest.response(), ConnectionError);\n },\n \"4xx response is mapped to HomeServerError\": async assert => {\n const request = new MockRequest();\n const hsRequest = new HomeServerRequest(\"GET\", \"https://hs.tld/foo\", request);\n request.respond(400, {errcode: \"FOO\"});\n await assert.rejects(hsRequest.response(), HomeServerError);\n },\n \"4xx response without errcode is mapped to ConnectionError\": async assert => {\n const request = new MockRequest();\n const hsRequest = new HomeServerRequest(\"GET\", \"https://hs.tld/foo\", request);\n request.respond(400);\n await assert.rejects(hsRequest.response(), ConnectionError);\n },\n \"Other errors are passed through\": async assert => {\n class MyError extends Error {}\n const request = new MockRequest();\n const hsRequest = new HomeServerRequest(\"GET\", \"https://hs.tld/foo\", request);\n request.reject(new MyError());\n await assert.rejects(hsRequest.response(), MyError);\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {encodeQueryParams, encodeBody} from \"./common\";\nimport {HomeServerRequest} from \"./HomeServerRequest\";\nimport type {IHomeServerRequest} from \"./HomeServerRequest\";\nimport type {Reconnector} from \"./Reconnector\";\nimport type {EncodedBody} from \"./common\";\nimport type {RequestFunction} from \"../../platform/types/types\";\nimport type {ILogItem} from \"../../logging/types\";\n\ntype RequestMethod = \"POST\" | \"GET\" | \"PUT\";\n\nconst CS_R0_PREFIX = \"/_matrix/client/r0\";\nconst CS_V3_PREFIX = \"/_matrix/client/v3\";\nconst DEHYDRATION_PREFIX = \"/_matrix/client/unstable/org.matrix.msc2697.v2\";\n\ntype Options = {\n homeserver: string;\n accessToken: string;\n request: RequestFunction;\n reconnector: Reconnector;\n};\n\ntype BaseRequestOptions = {\n log?: ILogItem;\n allowedStatusCodes?: number[];\n uploadProgress?: (loadedBytes: number) => void;\n timeout?: number;\n prefix?: string;\n};\n\nexport class HomeServerApi {\n private readonly _homeserver: string;\n private _accessToken: string;\n private readonly _requestFn: RequestFunction;\n private readonly _reconnector: Reconnector;\n\n constructor({homeserver, accessToken, request, reconnector}: Options) {\n // store these both in a closure somehow so it's harder to get at in case of XSS?\n // one could change the homeserver as well so the token gets sent there, so both must be protected from read/write\n this._homeserver = homeserver;\n this._accessToken = accessToken;\n this._requestFn = request;\n this._reconnector = reconnector;\n }\n\n private _url(csPath: string, prefix: string = CS_R0_PREFIX): string {\n return this._homeserver + prefix + csPath;\n }\n\n private _baseRequest(method: RequestMethod, url: string, queryParams?: Record, body?: Record, options?: BaseRequestOptions, accessToken?: string): IHomeServerRequest {\n const queryString = encodeQueryParams(queryParams);\n url = `${url}?${queryString}`;\n let encodedBody: EncodedBody[\"body\"];\n const headers: Map = new Map();\n if (accessToken) {\n headers.set(\"Authorization\", `Bearer ${accessToken}`);\n }\n headers.set(\"Accept\", \"application/json\");\n if (body) {\n const encoded = encodeBody(body);\n headers.set(\"Content-Type\", encoded.mimeType);\n encodedBody = encoded.body;\n }\n\n const requestResult = this._requestFn(url, {\n method,\n headers,\n body: encodedBody,\n timeout: options?.timeout,\n uploadProgress: options?.uploadProgress,\n format: \"json\", // response format\n cache: method !== \"GET\",\n });\n\n const hsRequest = new HomeServerRequest(method, url, requestResult, options);\n \n if (this._reconnector) {\n hsRequest.response().catch(err => {\n // Some endpoints such as /sync legitimately time-out\n // (which is also reported as a ConnectionError) and will re-attempt,\n // but spinning up the reconnector in this case is ok,\n // as all code ran on session and sync start should be reentrant\n if (err.name === \"ConnectionError\") {\n this._reconnector.onRequestFailed(this);\n }\n });\n }\n\n return hsRequest;\n }\n\n private _unauthedRequest(method: RequestMethod, url: string, queryParams?: Record, body?: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._baseRequest(method, url, queryParams, body, options);\n }\n\n private _authedRequest(method: RequestMethod, url: string, queryParams?: Record, body?: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._baseRequest(method, url, queryParams, body, options, this._accessToken);\n }\n\n private _post(csPath: string, queryParams: Record, body: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._authedRequest(\"POST\", this._url(csPath, options?.prefix || CS_R0_PREFIX), queryParams, body, options);\n }\n\n private _put(csPath: string, queryParams: Record, body?: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._authedRequest(\"PUT\", this._url(csPath, options?.prefix || CS_R0_PREFIX), queryParams, body, options);\n }\n\n private _get(csPath: string, queryParams?: Record, body?: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._authedRequest(\"GET\", this._url(csPath, options?.prefix || CS_R0_PREFIX), queryParams, body, options);\n }\n\n /**\n * Update the access token used by the API.\n * @param token \n */\n public updateAccessToken(token: string) {\n this._accessToken = token;\n }\n\n sync(since: string, filter: string, timeout: number, options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(\"/sync\", {since, timeout, filter}, undefined, options);\n }\n\n context(roomId: string, eventId: string, limit: number, filter: string): IHomeServerRequest {\n return this._get(`/rooms/${encodeURIComponent(roomId)}/context/${encodeURIComponent(eventId)}`, {filter, limit});\n }\n\n // params is from, dir and optionally to, limit, filter.\n messages(roomId: string, params: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(`/rooms/${encodeURIComponent(roomId)}/messages`, params, undefined, options);\n }\n\n // params is at, membership and not_membership\n members(roomId: string, params: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(`/rooms/${encodeURIComponent(roomId)}/members`, params, undefined, options);\n }\n\n send(roomId: string, eventType: string, txnId: string, content: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._put(`/rooms/${encodeURIComponent(roomId)}/send/${encodeURIComponent(eventType)}/${encodeURIComponent(txnId)}`, {}, content, options);\n }\n\n redact(roomId: string, eventId: string, txnId: string, content: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._put(`/rooms/${encodeURIComponent(roomId)}/redact/${encodeURIComponent(eventId)}/${encodeURIComponent(txnId)}`, {}, content, options);\n }\n\n receipt(roomId: string, receiptType: string, eventId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/rooms/${encodeURIComponent(roomId)}/receipt/${encodeURIComponent(receiptType)}/${encodeURIComponent(eventId)}`,\n {}, {}, options);\n }\n\n state(roomId: string, eventType: string, stateKey: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(`/rooms/${encodeURIComponent(roomId)}/state/${encodeURIComponent(eventType)}/${encodeURIComponent(stateKey)}`, {}, undefined, options);\n }\n \n sendState(roomId: string, eventType: string, stateKey: string, content: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._put(`/rooms/${encodeURIComponent(roomId)}/state/${encodeURIComponent(eventType)}/${encodeURIComponent(stateKey)}`, {}, content, options);\n }\n\n getLoginFlows(): IHomeServerRequest {\n return this._unauthedRequest(\"GET\", this._url(\"/login\"));\n }\n\n register(username: string | null, password: string, initialDeviceDisplayName: string, auth?: Record, inhibitLogin: boolean = false , options: BaseRequestOptions = {}): IHomeServerRequest {\n options.allowedStatusCodes = [401];\n const body: any = {\n auth,\n password,\n initial_device_displayname: initialDeviceDisplayName,\n inhibit_login: inhibitLogin,\n };\n if (username) {\n // username is optional for registration\n body.username = username;\n }\n return this._unauthedRequest( \"POST\", this._url(\"/register\", CS_V3_PREFIX), undefined, body, options);\n }\n\n passwordLogin(username: string, password: string, initialDeviceDisplayName: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._unauthedRequest(\"POST\", this._url(\"/login\"), undefined, {\n \"type\": \"m.login.password\",\n \"identifier\": {\n \"type\": \"m.id.user\",\n \"user\": username\n },\n \"password\": password,\n \"initial_device_display_name\": initialDeviceDisplayName\n }, options);\n }\n\n tokenLogin(loginToken: string, txnId: string, initialDeviceDisplayName: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._unauthedRequest(\"POST\", this._url(\"/login\"), undefined, {\n \"type\": \"m.login.token\",\n \"identifier\": {\n \"type\": \"m.id.user\",\n },\n \"token\": loginToken,\n \"txn_id\": txnId,\n \"initial_device_display_name\": initialDeviceDisplayName\n }, options);\n }\n\n createFilter(userId: string, filter: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/user/${encodeURIComponent(userId)}/filter`, {}, filter, options);\n }\n\n versions(options?: BaseRequestOptions): IHomeServerRequest {\n return this._unauthedRequest(\"GET\", `${this._homeserver}/_matrix/client/versions`, undefined, undefined, options);\n }\n\n uploadKeys(dehydratedDeviceId: string, payload: Record, options?: BaseRequestOptions): IHomeServerRequest {\n let path = \"/keys/upload\";\n if (dehydratedDeviceId) {\n path = path + `/${encodeURIComponent(dehydratedDeviceId)}`;\n }\n return this._post(path, {}, payload, options);\n }\n\n uploadSignatures(payload: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(\"/keys/signatures/upload\", {}, payload, options);\n }\n\n queryKeys(queryRequest: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(\"/keys/query\", {}, queryRequest, options);\n }\n\n claimKeys(payload: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(\"/keys/claim\", {}, payload, options);\n }\n\n sendToDevice(type: string, payload: Record, txnId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._put(`/sendToDevice/${encodeURIComponent(type)}/${encodeURIComponent(txnId)}`, {}, payload, options);\n }\n \n roomKeysVersion(version?: string, options?: BaseRequestOptions): IHomeServerRequest {\n let versionPart = \"\";\n if (version) {\n versionPart = `/${encodeURIComponent(version)}`;\n }\n return this._get(`/room_keys/version${versionPart}`, undefined, undefined, options);\n }\n\n roomKeyForRoomAndSession(version: string, roomId: string, sessionId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(`/room_keys/keys/${encodeURIComponent(roomId)}/${encodeURIComponent(sessionId)}`, {version}, undefined, options);\n }\n\n uploadRoomKeysToBackup(version: string, payload: Record, options: BaseRequestOptions = {}): IHomeServerRequest {\n options.prefix = CS_V3_PREFIX;\n return this._put(`/room_keys/keys`, {version}, payload, options);\n }\n\n uploadAttachment(blob: Blob, filename: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._authedRequest(\"POST\", `${this._homeserver}/_matrix/media/r0/upload`, {filename}, blob, options);\n }\n\n setPusher(pusher: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(\"/pushers/set\", {}, pusher, options);\n }\n\n getPushers(options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(\"/pushers\", undefined, undefined, options);\n }\n\n invite(roomId: string, userId: string, reason?: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(\n `/rooms/${encodeURIComponent(roomId)}/invite`,\n {},\n { user_id: userId, reason },\n options\n );\n }\n\n join(roomId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/rooms/${encodeURIComponent(roomId)}/join`, {}, {}, options);\n }\n\n joinIdOrAlias(roomIdOrAlias: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/join/${encodeURIComponent(roomIdOrAlias)}`, {}, {}, options);\n }\n\n leave(roomId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/rooms/${encodeURIComponent(roomId)}/leave`, {}, {}, options);\n }\n\n forget(roomId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/rooms/${encodeURIComponent(roomId)}/forget`, {}, {}, options);\n }\n\n logout(options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/logout`, {}, {}, options);\n }\n\n getDehydratedDevice(options: BaseRequestOptions = {}): IHomeServerRequest {\n options.prefix = DEHYDRATION_PREFIX;\n return this._get(`/dehydrated_device`, undefined, undefined, options);\n }\n\n createDehydratedDevice(payload: Record, options: BaseRequestOptions = {}): IHomeServerRequest {\n options.prefix = DEHYDRATION_PREFIX;\n return this._put(`/dehydrated_device`, {}, payload, options);\n }\n\n claimDehydratedDevice(deviceId: string, options: BaseRequestOptions = {}): IHomeServerRequest {\n options.prefix = DEHYDRATION_PREFIX;\n return this._post(`/dehydrated_device/claim`, {}, {device_id: deviceId}, options);\n }\n\n profile(userId: string, options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(`/profile/${encodeURIComponent(userId)}`);\n }\n\n createRoom(payload: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._post(`/createRoom`, {}, payload, options);\n }\n\n setAccountData(ownUserId: string, type: string, content: Record, options?: BaseRequestOptions): IHomeServerRequest {\n return this._put(`/user/${encodeURIComponent(ownUserId)}/account_data/${encodeURIComponent(type)}`, {}, content, options);\n }\n\n getTurnServer(options?: BaseRequestOptions): IHomeServerRequest {\n return this._get(`/voip/turnServer`, undefined, undefined, options);\n }\n}\n\nimport {Request as MockRequest} from \"../../mocks/Request.js\";\n\nexport function tests() {\n return {\n \"superficial happy path for GET\": async assert => {\n // @ts-ignore\n const hsApi = new HomeServerApi({\n request: () => new MockRequest().respond(200, 42),\n homeserver: \"https://hs.tld\",\n });\n // @ts-ignore\n const result = await hsApi._get(\"foo\").response();\n assert.strictEqual(result, 42);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../utils/error\";\nimport type {Timeout} from \"../../platform/web/dom/Clock.js\";\n\ntype TimeoutCreator = (ms: number) => Timeout;\n\nconst enum Default { start = 2000 }\n\nexport class ExponentialRetryDelay {\n private readonly _start: number = Default.start;\n private _current: number = Default.start;\n private readonly _createTimeout: TimeoutCreator;\n private readonly _max: number;\n private _timeout?: Timeout;\n\n constructor(createTimeout: TimeoutCreator) {\n const start = 2000;\n this._start = start;\n this._current = start;\n this._createTimeout = createTimeout;\n this._max = 60 * 5 * 1000; //5 min\n }\n\n async waitForRetry(): Promise {\n this._timeout = this._createTimeout(this._current);\n try {\n await this._timeout.elapsed();\n // only increase delay if we didn't get interrupted\n const next = 2 * this._current;\n this._current = Math.min(this._max, next);\n } catch(err) {\n // swallow AbortError, means abort was called\n if (!(err instanceof AbortError)) {\n throw err;\n }\n } finally {\n this._timeout = undefined;\n }\n }\n\n abort(): void {\n if (this._timeout) {\n this._timeout.abort();\n }\n }\n\n reset(): void {\n this._current = this._start;\n this.abort();\n }\n\n get nextValue(): number {\n return this._current;\n }\n}\n\n\nimport {Clock as MockClock} from \"../../mocks/Clock.js\";\n\nexport function tests() {\n return {\n \"test sequence\": async assert => {\n const clock = new MockClock();\n const retryDelay = new ExponentialRetryDelay(clock.createTimeout);\n let promise;\n\n assert.strictEqual(retryDelay.nextValue, 2000);\n promise = retryDelay.waitForRetry();\n clock.elapse(2000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 4000);\n promise = retryDelay.waitForRetry();\n clock.elapse(4000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 8000);\n promise = retryDelay.waitForRetry();\n clock.elapse(8000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 16000);\n promise = retryDelay.waitForRetry();\n clock.elapse(16000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 32000);\n promise = retryDelay.waitForRetry();\n clock.elapse(32000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 64000);\n promise = retryDelay.waitForRetry();\n clock.elapse(64000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 128000);\n promise = retryDelay.waitForRetry();\n clock.elapse(128000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 256000);\n promise = retryDelay.waitForRetry();\n clock.elapse(256000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 300000);\n promise = retryDelay.waitForRetry();\n clock.elapse(300000);\n await promise;\n\n assert.strictEqual(retryDelay.nextValue, 300000);\n promise = retryDelay.waitForRetry();\n clock.elapse(300000);\n await promise;\n },\n }\n \n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableValue} from \"../../observable/value\";\nimport type {ExponentialRetryDelay} from \"./ExponentialRetryDelay\";\nimport type {TimeMeasure} from \"../../platform/web/dom/Clock.js\";\nimport type {OnlineStatus} from \"../../platform/web/dom/OnlineStatus.js\";\nimport type {VersionResponse} from \"./types/response\";\nimport type {HomeServerApi} from \"./HomeServerApi\";\n\nexport enum ConnectionStatus {\n \"Waiting\",\n \"Reconnecting\",\n \"Online\"\n};\n\ntype Ctor = {\n retryDelay: ExponentialRetryDelay;\n createMeasure: () => TimeMeasure;\n onlineStatus: OnlineStatus\n};\n\nexport class Reconnector {\n private readonly _retryDelay: ExponentialRetryDelay;\n private readonly _createTimeMeasure: () => TimeMeasure;\n private readonly _onlineStatus: OnlineStatus;\n private readonly _state: ObservableValue;\n private _isReconnecting: boolean;\n private _versionsResponse?: VersionResponse;\n private _stateSince: TimeMeasure;\n\n constructor({retryDelay, createMeasure, onlineStatus}: Ctor) {\n this._onlineStatus = onlineStatus;\n this._retryDelay = retryDelay;\n this._createTimeMeasure = createMeasure;\n // assume online, and do our thing when something fails\n this._state = new ObservableValue(ConnectionStatus.Online);\n this._isReconnecting = false;\n }\n\n get lastVersionsResponse(): VersionResponse | undefined {\n return this._versionsResponse;\n }\n\n get connectionStatus(): ObservableValue {\n return this._state;\n }\n\n get retryIn(): number {\n if (this._state.get() === ConnectionStatus.Waiting) {\n return this._retryDelay.nextValue - this._stateSince.measure();\n }\n return 0;\n }\n\n async onRequestFailed(hsApi: HomeServerApi): Promise {\n if (!this._isReconnecting) { \n this._isReconnecting = true;\n \n const onlineStatusSubscription = this._onlineStatus && this._onlineStatus.subscribe(online => {\n if (online) {\n this.tryNow();\n }\n });\n\n try {\n await this._reconnectLoop(hsApi);\n } catch (err) {\n // nothing is catching the error above us,\n // so just log here\n console.error(err);\n } finally {\n if (onlineStatusSubscription) {\n // unsubscribe from this._onlineStatus\n onlineStatusSubscription();\n }\n this._isReconnecting = false;\n }\n }\n }\n\n tryNow(): void {\n if (this._retryDelay) {\n // this will interrupt this._retryDelay.waitForRetry() in _reconnectLoop\n this._retryDelay.abort();\n }\n }\n\n private _setState(state: ConnectionStatus): void {\n if (state !== this._state.get()) {\n if (state === ConnectionStatus.Waiting) {\n this._stateSince = this._createTimeMeasure();\n } else {\n this._stateSince = null;\n }\n this._state.set(state);\n }\n }\n \n private async _reconnectLoop(hsApi: HomeServerApi): Promise {\n this._versionsResponse = undefined;\n this._retryDelay.reset();\n\n while (!this._versionsResponse) {\n try {\n this._setState(ConnectionStatus.Reconnecting);\n // use 30s timeout, as a tradeoff between not giving up\n // too quickly on a slow server, and not waiting for\n // a stale connection when we just came online again\n const versionsRequest = hsApi.versions({timeout: 30000});\n this._versionsResponse = await versionsRequest.response();\n this._setState(ConnectionStatus.Online);\n } catch (err) {\n if (err.name === \"ConnectionError\") {\n this._setState(ConnectionStatus.Waiting);\n await this._retryDelay.waitForRetry();\n } else {\n throw err;\n }\n }\n }\n }\n}\n\n\nimport {Clock as MockClock} from \"../../mocks/Clock.js\";\nimport {ExponentialRetryDelay as _ExponentialRetryDelay} from \"./ExponentialRetryDelay\";\nimport {ConnectionError} from \"../error.js\"\n\nexport function tests() {\n function createHsApiMock(remainingFailures) {\n return {\n versions() {\n return {\n response() {\n if (remainingFailures) {\n remainingFailures -= 1;\n return Promise.reject(new ConnectionError());\n } else {\n return Promise.resolve(42);\n }\n }\n };\n }\n }\n }\n\n return {\n \"test reconnecting with 1 failure\": async assert => {\n const clock = new MockClock();\n const {createMeasure} = clock;\n const onlineStatus = new ObservableValue(false);\n const retryDelay = new _ExponentialRetryDelay(clock.createTimeout);\n const reconnector = new Reconnector({retryDelay, onlineStatus, createMeasure});\n const {connectionStatus} = reconnector;\n const statuses: ConnectionStatus[] = [];\n const subscription = reconnector.connectionStatus.subscribe(s => {\n statuses.push(s);\n });\n // @ts-ignore\n reconnector.onRequestFailed(createHsApiMock(1));\n await connectionStatus.waitFor(s => s === ConnectionStatus.Waiting).promise;\n clock.elapse(2000);\n await connectionStatus.waitFor(s => s === ConnectionStatus.Online).promise;\n assert.deepEqual(statuses, [\n ConnectionStatus.Reconnecting,\n ConnectionStatus.Waiting,\n ConnectionStatus.Reconnecting,\n ConnectionStatus.Online\n ]);\n assert.strictEqual(reconnector.lastVersionsResponse, 42);\n subscription();\n },\n \"test reconnecting with onlineStatus\": async assert => {\n const clock = new MockClock();\n const {createMeasure} = clock;\n const onlineStatus = new ObservableValue(false);\n const retryDelay = new _ExponentialRetryDelay(clock.createTimeout);\n const reconnector = new Reconnector({retryDelay, onlineStatus, createMeasure});\n const {connectionStatus} = reconnector;\n // @ts-ignore\n reconnector.onRequestFailed(createHsApiMock(1));\n await connectionStatus.waitFor(s => s === ConnectionStatus.Waiting).promise;\n onlineStatus.set(true); //skip waiting\n await connectionStatus.waitFor(s => s === ConnectionStatus.Online).promise;\n assert.equal(connectionStatus.get(), ConnectionStatus.Online);\n assert.strictEqual(reconnector.lastVersionsResponse, 42);\n },\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Decrypt an attachment.\n * @param {ArrayBuffer} ciphertextBuffer The encrypted attachment data buffer.\n * @param {Object} info The information needed to decrypt the attachment.\n * @param {Object} info.key AES-CTR JWK key object.\n * @param {string} info.iv Base64 encoded 16 byte AES-CTR IV.\n * @param {string} info.hashes.sha256 Base64 encoded SHA-256 hash of the ciphertext.\n * @return {Promise} A promise that resolves with an ArrayBuffer when the attachment is decrypted.\n */\nexport async function decryptAttachment(platform, ciphertextBuffer, info) {\n if (info === undefined || info.key === undefined || info.iv === undefined\n || info.hashes === undefined || info.hashes.sha256 === undefined) {\n throw new Error(\"Invalid info. Missing info.key, info.iv or info.hashes.sha256 key\");\n }\n\n const {crypto} = platform;\n const {base64} = platform.encoding;\n var ivArray = base64.decode(info.iv);\n // re-encode to not deal with padded vs unpadded\n var expectedSha256base64 = base64.encode(base64.decode(info.hashes.sha256));\n // Check the sha256 hash\n const digestResult = await crypto.digest(\"SHA-256\", ciphertextBuffer);\n if (base64.encode(new Uint8Array(digestResult)) != expectedSha256base64) {\n throw new Error(\"Mismatched SHA-256 digest\");\n }\n var counterLength;\n if (info.v == \"v1\" || info.v == \"v2\") {\n // Version 1 and 2 use a 64 bit counter.\n counterLength = 64;\n } else {\n // Version 0 uses a 128 bit counter.\n counterLength = 128;\n }\n\n const decryptedBuffer = await crypto.aes.decryptCTR({\n jwkKey: info.key,\n iv: ivArray,\n data: ciphertextBuffer,\n counterLength\n });\n return decryptedBuffer;\n}\n\nexport async function encryptAttachment(platform, blob) {\n const {crypto} = platform;\n const {base64} = platform.encoding;\n const iv = await crypto.aes.generateIV();\n const key = await crypto.aes.generateKey(\"jwk\", 256);\n const buffer = await blob.readAsBuffer();\n const ciphertext = await crypto.aes.encryptCTR({jwkKey: key, iv, data: buffer});\n const digest = await crypto.digest(\"SHA-256\", ciphertext);\n return {\n blob: platform.createBlob(ciphertext, 'application/octet-stream'),\n info: {\n v: \"v2\",\n key,\n iv: base64.encodeUnpadded(iv),\n hashes: {\n sha256: base64.encodeUnpadded(digest)\n }\n }\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { encodeQueryParams } from \"./common\";\nimport { decryptAttachment } from \"../e2ee/attachment.js\";\nimport { Platform } from \"../../platform/web/Platform.js\";\nimport { BlobHandle } from \"../../platform/web/dom/BlobHandle.js\";\nimport type {\n Attachment,\n EncryptedFile,\n VersionResponse,\n} from \"./types/response\";\n\ntype ServerVersions = VersionResponse[\"versions\"];\n\ntype Params = {\n homeserver: string;\n platform: Platform;\n serverVersions: ServerVersions;\n};\n\nexport class MediaRepository {\n private readonly homeserver: string;\n private readonly platform: Platform;\n // Depends on whether the server supports authenticated media\n private mediaUrlPart: string;\n\n constructor(params: Params) {\n this.homeserver = params.homeserver;\n this.platform = params.platform;\n this.generateMediaUrl(params.serverVersions);\n }\n\n /**\n * Calculate and store the correct media endpoint depending\n * on whether the homeserver supports authenticated media (MSC3916)\n * @see https://github.com/matrix-org/matrix-spec-proposals/pull/3916\n * @param serverVersions List of supported spec versions\n */\n private generateMediaUrl(serverVersions: ServerVersions) {\n const VERSION_WITH_AUTHENTICATION = \"v1.11\";\n if (serverVersions.includes(VERSION_WITH_AUTHENTICATION)) {\n this.mediaUrlPart = \"_matrix/client/v1/media\";\n } else {\n this.mediaUrlPart = \"_matrix/media/v3\";\n }\n }\n\n mxcUrlThumbnail(\n url: string,\n width: number,\n height: number,\n method: \"crop\" | \"scale\"\n ): string | undefined {\n const parts = this.parseMxcUrl(url);\n if (parts) {\n const [serverName, mediaId] = parts;\n const httpUrl = `${this.homeserver}/${\n this.mediaUrlPart\n }/thumbnail/${encodeURIComponent(serverName)}/${encodeURIComponent(\n mediaId\n )}`;\n return (\n httpUrl +\n \"?\" +\n encodeQueryParams({\n width: Math.round(width),\n height: Math.round(height),\n method,\n })\n );\n }\n return undefined;\n }\n\n mxcUrl(url: string): string | undefined {\n const parts = this.parseMxcUrl(url);\n if (parts) {\n const [serverName, mediaId] = parts;\n return `${this.homeserver}/${\n this.mediaUrlPart\n }/download/${encodeURIComponent(serverName)}/${encodeURIComponent(\n mediaId\n )}`;\n }\n return undefined;\n }\n\n private parseMxcUrl(url: string): string[] | undefined {\n const prefix = \"mxc://\";\n if (url.startsWith(prefix)) {\n return url.slice(prefix.length).split(\"/\", 2);\n } else {\n return undefined;\n }\n }\n\n async downloadEncryptedFile(\n fileEntry: EncryptedFile,\n cache: boolean = false\n ): Promise {\n const url = this.mxcUrl(fileEntry.url);\n const { body: encryptedBuffer } = await this.platform\n .request(url, { method: \"GET\", format: \"buffer\", cache })\n .response();\n const decryptedBuffer = await decryptAttachment(\n this.platform,\n encryptedBuffer,\n fileEntry\n );\n return this.platform.createBlob(decryptedBuffer, fileEntry.mimetype);\n }\n\n async downloadPlaintextFile(\n mxcUrl: string,\n mimetype: string,\n cache: boolean = false\n ): Promise {\n const url = this.mxcUrl(mxcUrl);\n const { body: buffer } = await this.platform\n .request(url, { method: \"GET\", format: \"buffer\", cache })\n .response();\n return this.platform.createBlob(buffer, mimetype);\n }\n\n async downloadAttachment(\n content: Attachment,\n cache: boolean = false\n ): Promise {\n if (content.file) {\n return this.downloadEncryptedFile(content.file, cache);\n } else {\n return this.downloadPlaintextFile(\n content.url!,\n content.info?.mimetype,\n cache\n );\n }\n }\n}\n\nexport function tests() {\n return {\n \"Uses correct endpoint when server supports authenticated media\": (\n assert\n ) => {\n const homeserver = \"matrix.org\";\n const platform = {};\n // Is it enough to check if v1.11 is present?\n // or do we check if maxVersion > v1.11\n const serverVersions = [\"v1.1\", \"v1.11\", \"v1.10\"];\n const mediaRepository = new MediaRepository({\n homeserver,\n platform,\n serverVersions,\n });\n\n const mxcUrl = \"mxc://matrix.org/foobartest\";\n assert.match(\n mediaRepository.mxcUrl(mxcUrl),\n /_matrix\\/client\\/v1\\/media/\n );\n },\n\n \"Uses correct endpoint when server does not supports authenticated media\":\n (assert) => {\n const homeserver = \"matrix.org\";\n const platform = {};\n const serverVersions = [\"v1.1\", \"v1.11\", \"v1.10\"];\n const mediaRepository = new MediaRepository({\n homeserver,\n platform,\n serverVersions,\n });\n\n const mxcUrl = \"mxc://matrix.org/foobartest\";\n assert.match(\n mediaRepository.mxcUrl(mxcUrl),\n /_matrix\\/client\\/v1\\/media/\n );\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../utils/error\";\nimport {HomeServerError} from \"../error.js\";\nimport {HomeServerApi} from \"./HomeServerApi\";\nimport {ExponentialRetryDelay} from \"./ExponentialRetryDelay\";\nimport {Clock} from \"../../platform/web/dom/Clock.js\";\nimport type {IHomeServerRequest} from \"./HomeServerRequest.js\";\n\nclass Request implements IHomeServerRequest {\n public readonly methodName: string;\n public readonly args: any[];\n private responseResolve: (result: any) => void;\n public responseReject: (error: Error) => void;\n private responseCodeResolve?: (result: any) => void;\n private responseCodeReject?: (result: any) => void;\n private _requestResult?: IHomeServerRequest;\n private readonly _responsePromise: Promise;\n private _responseCodePromise: Promise;\n\n constructor(methodName: string, args: any[]) {\n this.methodName = methodName;\n this.args = args;\n this._responsePromise = new Promise((resolve, reject) => {\n this.responseResolve = resolve;\n this.responseReject = reject;\n });\n }\n\n abort(): void {\n if (this._requestResult) {\n this._requestResult.abort();\n } else {\n this.responseReject(new AbortError());\n this.responseCodeReject?.(new AbortError());\n }\n }\n\n response(): Promise {\n return this._responsePromise;\n }\n\n responseCode(): Promise {\n if (this.requestResult) {\n return this.requestResult.responseCode();\n }\n if (!this._responseCodePromise) {\n this._responseCodePromise = new Promise((resolve, reject) => {\n this.responseCodeResolve = resolve;\n this.responseCodeReject = reject;\n });\n }\n return this._responseCodePromise;\n }\n\n async setRequestResult(result) {\n this._requestResult = result;\n const response = await this._requestResult?.response();\n this.responseResolve(response);\n const responseCode = await this._requestResult?.responseCode();\n this.responseCodeResolve?.(responseCode);\n }\n\n get requestResult() {\n return this._requestResult;\n }\n}\n\nclass HomeServerApiWrapper {\n private readonly _scheduler: RequestScheduler;\n\n constructor(scheduler: RequestScheduler) {\n this._scheduler = scheduler;\n }\n}\n\n// add request-wrapping methods to prototype\nfor (const methodName of Object.getOwnPropertyNames(HomeServerApi.prototype)) {\n if (methodName !== \"constructor\" && !methodName.startsWith(\"_\")) {\n HomeServerApiWrapper.prototype[methodName] = function(...args) {\n return this._scheduler._hsApiRequest(methodName, args);\n };\n }\n}\n\nexport class RequestScheduler {\n private readonly _hsApi: HomeServerApi;\n private readonly _clock: Clock;\n private readonly _requests: Set = new Set();\n private _stopped = false;\n private _wrapper = new HomeServerApiWrapper(this);\n\n constructor({ hsApi, clock }: { hsApi: HomeServerApi; clock: Clock }) {\n this._hsApi = hsApi;\n this._clock = clock;\n }\n\n get hsApi(): HomeServerApi {\n return this._wrapper as unknown as HomeServerApi;\n }\n\n stop(): void {\n this._stopped = true;\n for (const request of this._requests) {\n request.abort();\n }\n this._requests.clear();\n }\n\n start(): void {\n this._stopped = false;\n }\n\n private _hsApiRequest(name: string, args: any[]): Request {\n const request = new Request(name, args);\n this._doSend(request);\n return request;\n }\n\n private async _doSend(request: Request): Promise {\n this._requests.add(request);\n try {\n let retryDelay: ExponentialRetryDelay | undefined;\n while (!this._stopped) {\n try {\n const requestResult = this._hsApi[\n request.methodName\n ].apply(this._hsApi, request.args);\n // so the request can be aborted\n await request.setRequestResult(requestResult);\n return;\n } catch (err) {\n if (\n err instanceof HomeServerError &&\n err.errcode === \"M_LIMIT_EXCEEDED\"\n ) {\n if (Number.isSafeInteger(err.retry_after_ms)) {\n await this._clock\n .createTimeout(err.retry_after_ms)\n .elapsed();\n } else {\n if (!retryDelay) {\n retryDelay = new ExponentialRetryDelay(\n this._clock.createTimeout\n );\n }\n await retryDelay.waitForRetry();\n }\n } else {\n request.responseReject(err);\n return;\n }\n }\n }\n if (this._stopped) {\n request.abort();\n }\n } finally {\n this._requests.delete(request);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableValue} from \"../observable/value\";\nimport {createEnum} from \"../utils/enum\";\n\nconst INCREMENTAL_TIMEOUT = 30000;\n\nexport const SyncStatus = createEnum(\n \"InitialSync\",\n \"CatchupSync\",\n \"Syncing\",\n \"Stopped\"\n);\n\nfunction timelineIsEmpty(roomResponse) {\n try {\n const events = roomResponse?.timeline?.events;\n return Array.isArray(events) && events.length === 0;\n } catch (err) {\n return true;\n }\n}\n\n/**\n * Sync steps in js-pseudocode:\n * ```js\n * // can only read some stores\n * const preparation = await room.prepareSync(roomResponse, membership, newRoomKeys, prepareTxn);\n * // can do async work that is not related to storage (such as decryption)\n * await room.afterPrepareSync(preparation);\n * // writes and calculates changes\n * const changes = await room.writeSync(roomResponse, isInitialSync, preparation, syncTxn);\n * // applies and emits changes once syncTxn is committed\n * room.afterSync(changes);\n * // can do network requests\n * await room.afterSyncCompleted(changes);\n * ```\n */\nexport class Sync {\n constructor({hsApi, session, storage, logger}) {\n this._hsApi = hsApi;\n this._logger = logger;\n this._session = session;\n this._storage = storage;\n this._currentRequest = null;\n this._status = new ObservableValue(SyncStatus.Stopped);\n this._error = null;\n }\n\n get status() {\n return this._status;\n }\n\n /** the error that made the sync stop */\n get error() {\n return this._error;\n }\n\n start() {\n // not already syncing?\n if (this._status.get() !== SyncStatus.Stopped) {\n return;\n }\n this._error = null;\n let syncToken = this._session.syncToken;\n if (syncToken) {\n this._status.set(SyncStatus.CatchupSync);\n } else {\n this._status.set(SyncStatus.InitialSync);\n }\n this._syncLoop(syncToken);\n }\n\n async _syncLoop(syncToken) {\n // if syncToken is falsy, it will first do an initial sync ... \n while(this._status.get() !== SyncStatus.Stopped) {\n let roomStates;\n let sessionChanges;\n let wasCatchupOrInitial = this._status.get() === SyncStatus.CatchupSync || this._status.get() === SyncStatus.InitialSync;\n await this._logger.run(\"sync\", async log => {\n log.set(\"token\", syncToken);\n log.set(\"status\", this._status.get());\n try {\n // unless we are happily syncing already, we want the server to return\n // as quickly as possible, even if there are no events queued. This\n // serves two purposes:\n //\n // * When the connection dies, we want to know asap when it comes back,\n // so that we can hide the error from the user. (We don't want to\n // have to wait for an event or a timeout).\n //\n // * We want to know if the server has any to_device messages queued up\n // for us. We do that by calling it with a zero timeout until it\n // doesn't give us any more to_device messages.\n const timeout = this._status.get() === SyncStatus.Syncing ? INCREMENTAL_TIMEOUT : 0; \n const syncResult = await this._syncRequest(syncToken, timeout, log);\n syncToken = syncResult.syncToken;\n roomStates = syncResult.roomStates;\n sessionChanges = syncResult.sessionChanges;\n // initial sync or catchup sync\n if (this._status.get() !== SyncStatus.Syncing && syncResult.hadToDeviceMessages) {\n this._status.set(SyncStatus.CatchupSync);\n } else {\n this._status.set(SyncStatus.Syncing);\n }\n } catch (err) {\n // retry same request on timeout\n if (err.name === \"ConnectionError\" && err.isTimeout) {\n // don't run afterSyncCompleted\n return;\n }\n this._error = err;\n if (err.name !== \"AbortError\") {\n // sync wasn't asked to stop, but is stopping\n // because of the error.\n log.error = err;\n log.logLevel = log.level.Fatal;\n }\n log.set(\"stopping\", true);\n this._status.set(SyncStatus.Stopped);\n }\n if (this._status.get() !== SyncStatus.Stopped) {\n // TODO: if we're not going to run this phase in parallel with the next\n // sync request (because this causes OTKs to be uploaded twice)\n // should we move this inside _syncRequest?\n // Alternatively, we can try to fix the OTK upload issue while still\n // running in parallel.\n await log.wrap(\"afterSyncCompleted\", log => this._runAfterSyncCompleted(sessionChanges, roomStates, log));\n }\n },\n this._logger.level.Info,\n (filter, log) => {\n if (log.durationWithoutType(\"network\") >= 2000 || log.error || wasCatchupOrInitial) {\n return filter.minLevel(log.level.Detail);\n } else {\n return filter.minLevel(log.level.Info);\n }\n });\n }\n }\n\n async _runAfterSyncCompleted(sessionChanges, roomStates, log) {\n const isCatchupSync = this._status.get() === SyncStatus.CatchupSync;\n const sessionPromise = (async () => {\n try {\n await log.wrap(\"session\", log => this._session.afterSyncCompleted(sessionChanges, isCatchupSync, log));\n } catch (err) {} // error is logged, but don't fail sessionPromise\n })();\n const roomsPromises = roomStates.map(async rs => {\n try {\n await rs.room.afterSyncCompleted(rs.changes, log);\n } catch (err) {} // error is logged, but don't fail roomsPromises\n });\n // run everything in parallel,\n // we don't want to delay the next sync too much\n // Also, since all promises won't reject (as they have a try/catch)\n // it's fine to use Promise.all\n await Promise.all(roomsPromises.concat(sessionPromise));\n }\n\n async _syncRequest(syncToken, timeout, log) {\n let {syncFilterId} = this._session;\n if (typeof syncFilterId !== \"string\") {\n this._currentRequest = this._hsApi.createFilter(this._session.user.id, {room: {state: {lazy_load_members: true}}}, {log});\n syncFilterId = (await this._currentRequest.response()).filter_id;\n }\n const totalRequestTimeout = timeout + (80 * 1000); // same as riot-web, don't get stuck on wedged long requests\n this._currentRequest = this._hsApi.sync(syncToken, syncFilterId, timeout, {timeout: totalRequestTimeout, log});\n const response = await this._currentRequest.response();\n\n const isInitialSync = !syncToken;\n const sessionState = new SessionSyncProcessState();\n const inviteStates = this._parseInvites(response.rooms);\n const {roomStates, archivedRoomStates} = await this._parseRoomsResponse(\n response.rooms, inviteStates, isInitialSync, log);\n\n try {\n // take a lock on olm sessions used in this sync so sending a message doesn't change them while syncing\n sessionState.lock = await log.wrap(\"obtainSyncLock\", () => this._session.obtainSyncLock(response));\n await log.wrap(\"prepare\", log => this._prepareSync(sessionState, roomStates, response, log));\n await log.wrap(\"afterPrepareSync\", log => Promise.all(roomStates.map(rs => {\n return rs.room.afterPrepareSync(rs.preparation, log);\n })));\n await log.wrap(\"write\", async log => this._writeSync(\n sessionState, inviteStates, roomStates, archivedRoomStates,\n response, syncFilterId, isInitialSync, log));\n } finally {\n sessionState.dispose();\n }\n // sync txn comitted, emit updates and apply changes to in-memory state\n log.wrap(\"after\", log => this._afterSync(\n sessionState, inviteStates, roomStates, archivedRoomStates, log));\n\n const toDeviceEvents = response.to_device?.events;\n return {\n syncToken: response.next_batch,\n roomStates,\n sessionChanges: sessionState.changes,\n hadToDeviceMessages: Array.isArray(toDeviceEvents) && toDeviceEvents.length > 0,\n };\n }\n\n _openPrepareSyncTxn() {\n const storeNames = this._storage.storeNames;\n return this._storage.readTxn([\n storeNames.deviceKeys, // to read device from olm messages\n storeNames.olmSessions,\n storeNames.inboundGroupSessions,\n // to read fragments when loading sync writer when rejoining archived room\n storeNames.timelineFragments,\n // to read fragments when loading sync writer when rejoining archived room\n // to read events that can now be decrypted\n storeNames.timelineEvents,\n ]);\n }\n\n async _prepareSync(sessionState, roomStates, response, log) {\n const prepareTxn = await this._openPrepareSyncTxn();\n sessionState.preparation = await log.wrap(\"session\", log => this._session.prepareSync(\n response, sessionState.lock, prepareTxn, log));\n\n const newKeysByRoom = sessionState.preparation?.newKeysByRoom;\n\n // add any rooms with new keys but no sync response to the list of rooms to be synced\n if (newKeysByRoom) {\n const {hasOwnProperty} = Object.prototype;\n for (const roomId of newKeysByRoom.keys()) {\n const isRoomInResponse = response.rooms?.join && hasOwnProperty.call(response.rooms.join, roomId);\n if (!isRoomInResponse) {\n let room = this._session.rooms.get(roomId);\n if (room) {\n roomStates.push(new RoomSyncProcessState(room, false, {}, room.membership));\n }\n }\n }\n }\n \n await Promise.all(roomStates.map(async rs => {\n const newKeys = newKeysByRoom?.get(rs.room.id);\n rs.preparation = await log.wrap(\"room\", async log => {\n // if previously joined and we still have the timeline for it,\n // this loads the syncWriter at the correct position to continue writing the timeline\n if (rs.isNewRoom) {\n await rs.room.load(null, prepareTxn, log);\n }\n return rs.room.prepareSync(\n rs.roomResponse, rs.membership, newKeys, prepareTxn, log)\n }, log.level.Detail);\n }));\n\n // This is needed for safari to not throw TransactionInactiveErrors on the syncTxn. See docs/INDEXEDDB.md\n await prepareTxn.complete();\n }\n\n async _writeSync(sessionState, inviteStates, roomStates, archivedRoomStates, response, syncFilterId, isInitialSync, log) {\n const syncTxn = await this._openSyncTxn();\n try {\n sessionState.changes = await log.wrap(\"session\", log => this._session.writeSync(\n response, syncFilterId, sessionState.preparation, syncTxn, log));\n await Promise.all(inviteStates.map(async is => {\n is.changes = await log.wrap(\"invite\", log => is.invite.writeSync(\n is.membership, is.roomResponse, syncTxn, log));\n }));\n await Promise.all(roomStates.map(async rs => {\n rs.changes = await log.wrap(\"room\", log => rs.room.writeSync(\n rs.roomResponse, isInitialSync, rs.preparation, syncTxn, log));\n }));\n // important to do this after roomStates,\n // as we're referring to the roomState to get the summaryChanges\n await Promise.all(archivedRoomStates.map(async ars => {\n const summaryChanges = ars.roomState?.summaryChanges;\n ars.changes = await log.wrap(\"archivedRoom\", log => ars.archivedRoom.writeSync(\n summaryChanges, ars.roomResponse, ars.membership, syncTxn, log));\n }));\n } catch(err) {\n // avoid corrupting state by only\n // storing the sync up till the point\n // the exception occurred\n syncTxn.abort(log);\n throw syncTxn.getCause(err);\n }\n await syncTxn.complete(log);\n }\n\n _afterSync(sessionState, inviteStates, roomStates, archivedRoomStates, log) {\n log.wrap(\"session\", log => this._session.afterSync(sessionState.changes, log), log.level.Detail);\n for(let ars of archivedRoomStates) {\n log.wrap(\"archivedRoom\", log => {\n ars.archivedRoom.afterSync(ars.changes, log);\n ars.archivedRoom.release();\n }, log.level.Detail);\n }\n for(let rs of roomStates) {\n log.wrap(\"room\", log => rs.room.afterSync(rs.changes, log), log.level.Detail);\n }\n for(let is of inviteStates) {\n log.wrap(\"invite\", log => is.invite.afterSync(is.changes, log), log.level.Detail);\n }\n this._session.applyRoomCollectionChangesAfterSync(inviteStates, roomStates, archivedRoomStates, log);\n }\n\n _openSyncTxn() {\n const storeNames = this._storage.storeNames;\n return this._storage.readWriteTxn([\n storeNames.session,\n storeNames.roomSummary,\n storeNames.archivedRoomSummary,\n storeNames.invites,\n storeNames.roomState,\n storeNames.roomMembers,\n storeNames.timelineEvents,\n storeNames.timelineRelations,\n storeNames.timelineFragments,\n storeNames.pendingEvents,\n storeNames.userIdentities,\n storeNames.groupSessionDecryptions,\n storeNames.deviceKeys,\n // to discard outbound session when somebody leaves a room\n // and to create room key messages when somebody joins\n storeNames.outboundGroupSessions,\n storeNames.operations,\n storeNames.accountData,\n // to decrypt and store new room keys\n storeNames.olmSessions,\n storeNames.inboundGroupSessions,\n storeNames.calls,\n ]);\n }\n \n async _parseRoomsResponse(roomsSection, inviteStates, isInitialSync, log) {\n const roomStates = [];\n const archivedRoomStates = [];\n if (roomsSection) {\n const allMemberships = [\"join\", \"leave\"];\n for(const membership of allMemberships) {\n const membershipSection = roomsSection[membership];\n if (membershipSection) {\n for (const [roomId, roomResponse] of Object.entries(membershipSection)) {\n // ignore rooms with empty timelines during initial sync,\n // see https://github.com/vector-im/hydrogen-web/issues/15\n if (isInitialSync && timelineIsEmpty(roomResponse)) {\n continue;\n }\n const invite = this._session.invites.get(roomId);\n // if there is an existing invite, add a process state for it\n // so its writeSync and afterSync will run and remove the invite\n if (invite) {\n inviteStates.push(new InviteSyncProcessState(invite, false, null, membership));\n }\n const roomState = this._createRoomSyncState(roomId, roomResponse, membership, isInitialSync);\n if (roomState) {\n roomStates.push(roomState);\n }\n const ars = await this._createArchivedRoomSyncState(roomId, roomState, roomResponse, membership, isInitialSync, log);\n if (ars) {\n archivedRoomStates.push(ars);\n }\n }\n }\n }\n }\n return {roomStates, archivedRoomStates};\n }\n\n _createRoomSyncState(roomId, roomResponse, membership, isInitialSync) {\n let isNewRoom = false;\n let room = this._session.rooms.get(roomId);\n // create room only either on new join,\n // or for an archived room during initial sync,\n // where we create the summaryChanges with a joined\n // room to then adopt by the archived room.\n // This way the limited timeline, members, ...\n // we receive also gets written.\n // In any case, don't create a room for a rejected invite\n if (!room && (membership === \"join\" || (isInitialSync && membership === \"leave\"))) {\n room = this._session.createJoinedRoom(roomId);\n isNewRoom = true;\n }\n if (room) {\n return new RoomSyncProcessState(\n room, isNewRoom, roomResponse, membership);\n }\n }\n\n async _createArchivedRoomSyncState(roomId, roomState, roomResponse, membership, isInitialSync, log) {\n let archivedRoom;\n if (roomState?.shouldAdd && !isInitialSync) {\n // when adding a joined room during incremental sync,\n // always create the archived room to write the removal\n // of the archived summary\n archivedRoom = this._session.createOrGetArchivedRoomForSync(roomId);\n } else if (membership === \"leave\") {\n if (roomState) {\n // we still have a roomState, so we just left it\n // in this case, create a new archivedRoom\n archivedRoom = this._session.createOrGetArchivedRoomForSync(roomId);\n } else {\n // this is an update of an already left room, restore\n // it from storage first, so we can increment it.\n // this happens for example when our membership changes\n // after leaving (e.g. being (un)banned, possibly after being kicked), etc\n archivedRoom = await this._session.loadArchivedRoom(roomId, log);\n }\n }\n if (archivedRoom) {\n return new ArchivedRoomSyncProcessState(\n archivedRoom, roomState, roomResponse, membership);\n }\n }\n\n _parseInvites(roomsSection) {\n const inviteStates = [];\n if (roomsSection?.invite) {\n for (const [roomId, roomResponse] of Object.entries(roomsSection.invite)) {\n let invite = this._session.invites.get(roomId);\n let isNewInvite = false;\n if (!invite) {\n invite = this._session.createInvite(roomId);\n isNewInvite = true;\n }\n inviteStates.push(new InviteSyncProcessState(invite, isNewInvite, roomResponse, \"invite\"));\n }\n }\n return inviteStates;\n }\n\n stop() {\n if (this._status.get() === SyncStatus.Stopped) {\n return;\n }\n this._status.set(SyncStatus.Stopped);\n if (this._currentRequest) {\n this._currentRequest.abort();\n this._currentRequest = null;\n }\n }\n}\n\nclass SessionSyncProcessState {\n constructor() {\n this.lock = null;\n this.preparation = null;\n this.changes = null;\n }\n\n dispose() {\n this.lock?.release();\n }\n}\n\nclass RoomSyncProcessState {\n constructor(room, isNewRoom, roomResponse, membership) {\n this.room = room;\n this.isNewRoom = isNewRoom;\n this.roomResponse = roomResponse;\n this.membership = membership;\n this.preparation = null;\n this.changes = null;\n }\n\n get id() {\n return this.room.id;\n }\n\n get shouldAdd() {\n return this.isNewRoom && this.membership === \"join\";\n }\n\n get shouldRemove() {\n return !this.isNewRoom && this.membership !== \"join\";\n }\n\n get summaryChanges() {\n return this.changes?.summaryChanges;\n }\n}\n\n\nclass ArchivedRoomSyncProcessState {\n constructor(archivedRoom, roomState, roomResponse, membership, isInitialSync) {\n this.archivedRoom = archivedRoom;\n this.roomState = roomState;\n this.roomResponse = roomResponse;\n this.membership = membership;\n this.isInitialSync = isInitialSync;\n this.changes = null;\n }\n\n get id() {\n return this.archivedRoom.id;\n }\n\n get shouldAdd() {\n return (this.roomState || this.isInitialSync) && this.membership === \"leave\";\n }\n\n get shouldRemove() {\n return this.membership === \"join\";\n }\n}\n\nclass InviteSyncProcessState {\n constructor(invite, isNewInvite, roomResponse, membership) {\n this.invite = invite;\n this.isNewInvite = isNewInvite;\n this.membership = membership;\n this.roomResponse = roomResponse;\n this.changes = null;\n }\n\n get id() {\n return this.invite.id;\n }\n\n get shouldAdd() {\n return this.isNewInvite;\n }\n\n get shouldRemove() {\n return this.membership !== \"invite\";\n }\n}\n","/* Copyright 2015 Mark Haines\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use strict';\n\nvar escaped = /[\\\\\\\"\\x00-\\x1F]/g;\nvar escapes = {};\nfor (var i = 0; i < 0x20; ++i) {\n escapes[String.fromCharCode(i)] = (\n '\\\\U' + ('0000' + i.toString(16)).slice(-4).toUpperCase()\n );\n}\nescapes['\\b'] = '\\\\b';\nescapes['\\t'] = '\\\\t';\nescapes['\\n'] = '\\\\n';\nescapes['\\f'] = '\\\\f';\nescapes['\\r'] = '\\\\r';\nescapes['\\\"'] = '\\\\\\\"';\nescapes['\\\\'] = '\\\\\\\\';\n\nfunction escapeString(value) {\n escaped.lastIndex = 0;\n return value.replace(escaped, function(c) { return escapes[c]; });\n}\n\nfunction stringify(value) {\n switch (typeof value) {\n case 'string':\n return '\"' + escapeString(value) + '\"';\n case 'number':\n return isFinite(value) ? value : 'null';\n case 'boolean':\n return value;\n case 'object':\n if (value === null) {\n return 'null';\n }\n if (Array.isArray(value)) {\n return stringifyArray(value);\n }\n return stringifyObject(value);\n default:\n throw new Error('Cannot stringify: ' + typeof value);\n }\n}\n\nfunction stringifyArray(array) {\n var sep = '[';\n var result = '';\n for (var i = 0; i < array.length; ++i) {\n result += sep;\n sep = ',';\n result += stringify(array[i]);\n }\n if (sep != ',') {\n return '[]';\n } else {\n return result + ']';\n }\n}\n\nfunction stringifyObject(object) {\n var sep = '{';\n var result = '';\n var keys = Object.keys(object);\n keys.sort();\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n result += sep + '\"' + escapeString(key) + '\":';\n sep = ',';\n result += stringify(object[key]);\n }\n if (sep != ',') {\n return '{}';\n } else {\n return result + '}';\n }\n}\n\n/** */\nmodule.exports = {stringify: stringify};\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport anotherjson from \"another-json\";\n\nimport type {UnsentStateEvent} from \"../room/common\";\nimport type {ILogItem} from \"../../logging/types\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nexport enum DecryptionSource {\n Sync, Timeline, Retry\n};\n\n// use common prefix so it's easy to clear properties that are not e2ee related during session clear\nexport const SESSION_E2EE_KEY_PREFIX = \"e2ee:\";\nexport const OLM_ALGORITHM = \"m.olm.v1.curve25519-aes-sha2\";\nexport const MEGOLM_ALGORITHM = \"m.megolm.v1.aes-sha2\";\n\nexport class DecryptionError extends Error {\n constructor(private readonly code: string, private readonly event: object, private readonly detailsObj?: object) {\n super(`Decryption error ${code}${detailsObj ? \": \"+JSON.stringify(detailsObj) : \"\"}`);\n }\n}\n\nexport const SIGNATURE_ALGORITHM = \"ed25519\";\n\nexport type SignedValue = {\n signatures?: {[userId: string]: {[keyId: string]: string}}\n unsigned?: object\n}\n\n// we store device keys (and cross-signing) in the format we get them from the server\n// as that is what the signature is calculated on, so to verify and sign, we need\n// it in this format anyway.\nexport type DeviceKey = SignedValue & {\n readonly user_id: string;\n readonly device_id: string;\n readonly algorithms: ReadonlyArray;\n readonly keys: {[keyId: string]: string};\n readonly unsigned: {\n device_display_name?: string\n }\n}\n\nexport function getDeviceEd25519Key(deviceKey: DeviceKey): string {\n return deviceKey.keys[`ed25519:${deviceKey.device_id}`];\n}\n\nexport function getDeviceCurve25519Key(deviceKey: DeviceKey): string {\n return deviceKey.keys[`curve25519:${deviceKey.device_id}`];\n}\n\nexport function getEd25519Signature(signedValue: SignedValue, userId: string, deviceOrKeyId: string): string | undefined {\n return signedValue?.signatures?.[userId]?.[`${SIGNATURE_ALGORITHM}:${deviceOrKeyId}`];\n}\n\nexport enum SignatureVerification {\n Valid,\n Invalid,\n NotSigned,\n}\n\nexport function verifyEd25519Signature(olmUtil: Olm.Utility, userId: string, deviceOrKeyId: string, ed25519Key: string, value: SignedValue, log?: ILogItem): SignatureVerification {\n const signature = getEd25519Signature(value, userId, deviceOrKeyId);\n if (!signature) {\n log?.set(\"no_signature\", true);\n return SignatureVerification.NotSigned;\n }\n const clone = Object.assign({}, value) as object;\n delete clone[\"unsigned\"];\n delete clone[\"signatures\"];\n const canonicalJson = anotherjson.stringify(clone);\n try {\n // throws when signature is invalid\n olmUtil.ed25519_verify(ed25519Key, canonicalJson, signature);\n return SignatureVerification.Valid;\n } catch (err) {\n if (log) {\n const logItem = log.log({l: \"Invalid signature, ignoring.\", ed25519Key, canonicalJson, signature});\n logItem.error = err;\n logItem.logLevel = log.level.Warn;\n }\n return SignatureVerification.Invalid;\n }\n}\n\nexport function createRoomEncryptionEvent(): UnsentStateEvent {\n return {\n \"type\": \"m.room.encryption\",\n \"state_key\": \"\",\n \"content\": {\n \"algorithm\": MEGOLM_ALGORITHM,\n \"rotation_period_ms\": 604800000,\n \"rotation_period_msgs\": 100\n }\n }\n}\n\nexport enum HistoryVisibility {\n Joined = \"joined\",\n Invited = \"invited\",\n WorldReadable = \"world_readable\",\n Shared = \"shared\",\n};\n\nexport function shouldShareKey(membership: string, historyVisibility: HistoryVisibility) {\n switch (historyVisibility) {\n case HistoryVisibility.WorldReadable:\n return true;\n case HistoryVisibility.Shared:\n // was part of room at some time\n return membership !== undefined;\n case HistoryVisibility.Joined:\n return membership === \"join\";\n case HistoryVisibility.Invited:\n return membership === \"invite\" || membership === \"join\";\n default:\n return false;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {StateEvent} from \"../storage/types\";\n\nexport function getPrevContentFromStateEvent(event) {\n // where to look for prev_content is a bit of a mess,\n // see https://matrix.to/#/!NasysSDfxKxZBzJJoE:matrix.org/$DvrAbZJiILkOmOIuRsNoHmh2v7UO5CWp_rYhlGk34fQ?via=matrix.org&via=pixie.town&via=amorgan.xyz\n return event.unsigned?.prev_content || event.prev_content;\n}\n\nexport const REDACTION_TYPE = \"m.room.redaction\";\n\nexport function isRedacted(event) {\n return !!event?.unsigned?.redacted_because;\n}\n\nexport type UnsentStateEvent = { type: string; state_key: string; content: Record };\n\nexport enum RoomStatus {\n None = 1 << 0,\n BeingCreated = 1 << 1,\n Invited = 1 << 2,\n Joined = 1 << 3,\n Replaced = 1 << 4,\n Archived = 1 << 5,\n}\n\nexport enum RoomType {\n DirectMessage,\n Private,\n Public\n}\n\ntype RoomResponse = {\n state?: {\n events?: Array\n },\n timeline?: {\n events?: Array\n }\n}\n\n/** iterates over any state events in a sync room response, in the order that they should be applied (from older to younger events) */\n\nexport function iterateResponseStateEvents(roomResponse: RoomResponse, callback: (StateEvent) => Promise | void): Promise | void {\n let promises: Promise[] | undefined = undefined;\n const callCallback = stateEvent => {\n const result = callback(stateEvent);\n if (result instanceof Promise) {\n promises = promises ?? [];\n promises.push(result);\n }\n };\n // first iterate over state events, they precede the timeline\n const stateEvents = roomResponse.state?.events;\n if (stateEvents) {\n for (let i = 0; i < stateEvents.length; i++) {\n callCallback(stateEvents[i]);\n }\n }\n // now see if there are any state events within the timeline\n let timelineEvents = roomResponse.timeline?.events;\n if (timelineEvents) {\n for (let i = 0; i < timelineEvents.length; i++) {\n const event = timelineEvents[i];\n if (typeof event.state_key === \"string\") {\n callCallback(event);\n }\n }\n }\n if (promises) {\n return Promise.all(promises).then(() => undefined);\n }\n}\n\nexport function tests() {\n return {\n \"test iterateResponseStateEvents with both state and timeline sections\": assert => {\n const roomResponse = {\n state: {\n events: [\n {type: \"m.room.member\", state_key: \"1\"},\n {type: \"m.room.member\", state_key: \"2\", content: {a: 1}},\n ]\n },\n timeline: {\n events: [\n {type: \"m.room.message\"},\n {type: \"m.room.member\", state_key: \"3\"},\n {type: \"m.room.message\"},\n {type: \"m.room.member\", state_key: \"2\", content: {a: 2}},\n ]\n }\n } as unknown as RoomResponse;\n const expectedStateKeys = [\"1\", \"2\", \"3\", \"2\"];\n const expectedAForMember2 = [1, 2];\n iterateResponseStateEvents(roomResponse, event => {\n assert.strictEqual(event.type, \"m.room.member\");\n assert.strictEqual(expectedStateKeys.shift(), event.state_key);\n if (event.state_key === \"2\") {\n assert.strictEqual(expectedAForMember2.shift(), event.content.a);\n }\n });\n assert.strictEqual(expectedStateKeys.length, 0);\n assert.strictEqual(expectedAForMember2.length, 0);\n },\n \"test iterateResponseStateEvents with empty response\": assert => {\n iterateResponseStateEvents({}, () => {\n assert.fail(\"no events expected\");\n });\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MEGOLM_ALGORITHM} from \"../e2ee/common\";\nimport {iterateResponseStateEvents} from \"./common\";\n\nfunction applyTimelineEntries(data, timelineEntries, isInitialSync, canMarkUnread, ownUserId) {\n if (timelineEntries.length) {\n data = timelineEntries.reduce((data, entry) => {\n return processTimelineEvent(data, entry,\n isInitialSync, canMarkUnread, ownUserId);\n }, data);\n }\n return data;\n}\n\nfunction applySyncResponse(data, roomResponse, membership, ownUserId) {\n if (roomResponse.summary) {\n data = updateSummary(data, roomResponse.summary);\n }\n if (membership !== data.membership) {\n data = data.cloneIfNeeded();\n data.membership = membership;\n }\n if (roomResponse.account_data) {\n data = roomResponse.account_data.events.reduce(processRoomAccountData, data);\n }\n // process state events in state and in timeline.\n // non-state events are handled by applyTimelineEntries\n // so decryption is handled properly\n iterateResponseStateEvents(roomResponse, event => {\n data = processStateEvent(data, event, ownUserId);\n });\n const unreadNotifications = roomResponse.unread_notifications;\n if (unreadNotifications) {\n data = processNotificationCounts(data, unreadNotifications);\n }\n\n return data;\n}\n\nfunction processNotificationCounts(data, unreadNotifications) {\n const highlightCount = unreadNotifications.highlight_count || 0;\n if (highlightCount !== data.highlightCount) {\n data = data.cloneIfNeeded();\n data.highlightCount = highlightCount;\n }\n const notificationCount = unreadNotifications.notification_count;\n if (notificationCount !== data.notificationCount) {\n data = data.cloneIfNeeded();\n data.notificationCount = notificationCount;\n }\n return data;\n} \n\nfunction processRoomAccountData(data, event) {\n if (event?.type === \"m.tag\") {\n let tags = event?.content?.tags;\n if (!tags || Array.isArray(tags) || typeof tags !== \"object\") {\n tags = null;\n }\n data = data.cloneIfNeeded();\n data.tags = tags;\n }\n return data;\n}\n\nexport function processStateEvent(data, event, ownUserId) {\n if (event.type === \"m.room.create\") {\n data = data.cloneIfNeeded();\n data.lastMessageTimestamp = event.origin_server_ts;\n } else if (event.type === \"m.room.encryption\") {\n const algorithm = event.content?.algorithm;\n if (!data.encryption && algorithm === MEGOLM_ALGORITHM) {\n data = data.cloneIfNeeded();\n data.encryption = event.content;\n }\n } else if (event.type === \"m.room.name\") {\n const newName = event.content?.name;\n if (newName !== data.name) {\n data = data.cloneIfNeeded();\n data.name = newName;\n }\n } else if (event.type === \"m.room.avatar\") {\n const newUrl = event.content?.url;\n if (newUrl !== data.avatarUrl) {\n data = data.cloneIfNeeded();\n data.avatarUrl = newUrl;\n }\n } else if (event.type === \"m.room.canonical_alias\") {\n const content = event.content;\n data = data.cloneIfNeeded();\n data.canonicalAlias = content.alias;\n } else if (event.type === \"m.room.member\") {\n const content = event.content;\n if (content.is_direct === true && content.membership === \"invite\" && !data.isDirectMessage) {\n let other;\n if (event.sender === ownUserId) {\n other = event.state_key;\n } else if (event.state_key === ownUserId) {\n other = event.sender;\n }\n if (other) {\n data = data.cloneIfNeeded();\n data.isDirectMessage = true;\n data.dmUserId = other;\n }\n } else if (content.membership === \"leave\" && data.isDirectMessage && data.dmUserId === event.state_key) {\n data = data.cloneIfNeeded();\n data.isDirectMessage = false;\n data.dmUserId = null;\n }\n }\n return data;\n}\n\nfunction processTimelineEvent(data, eventEntry, isInitialSync, canMarkUnread, ownUserId) {\n if (eventEntry.eventType === \"m.room.message\") {\n if (!data.lastMessageTimestamp || eventEntry.timestamp > data.lastMessageTimestamp) {\n data = data.cloneIfNeeded();\n data.lastMessageTimestamp = eventEntry.timestamp;\n }\n if (!isInitialSync && eventEntry.sender !== ownUserId && canMarkUnread) {\n data = data.cloneIfNeeded();\n data.isUnread = true;\n }\n }\n return data;\n}\n\nfunction updateSummary(data, summary) {\n const heroes = summary[\"m.heroes\"];\n const joinCount = summary[\"m.joined_member_count\"];\n const inviteCount = summary[\"m.invited_member_count\"];\n // TODO: we could easily calculate if all members are available here and set hasFetchedMembers?\n // so we can avoid calling /members...\n // we'd need to do a count query in the roomMembers store though ...\n if (heroes && Array.isArray(heroes)) {\n data = data.cloneIfNeeded();\n data.heroes = heroes;\n }\n if (Number.isInteger(inviteCount)) {\n data = data.cloneIfNeeded();\n data.inviteCount = inviteCount;\n }\n if (Number.isInteger(joinCount)) {\n data = data.cloneIfNeeded();\n data.joinCount = joinCount;\n }\n return data;\n}\n\nexport class SummaryData {\n constructor(copy, roomId) {\n this.roomId = copy ? copy.roomId : roomId;\n this.name = copy ? copy.name : null;\n this.lastMessageTimestamp = copy ? copy.lastMessageTimestamp : null;\n this.isUnread = copy ? copy.isUnread : false;\n this.encryption = copy ? copy.encryption : null;\n this.membership = copy ? copy.membership : null;\n this.inviteCount = copy ? copy.inviteCount : 0;\n this.joinCount = copy ? copy.joinCount : 0;\n this.heroes = copy ? copy.heroes : null;\n this.canonicalAlias = copy ? copy.canonicalAlias : null;\n this.hasFetchedMembers = copy ? copy.hasFetchedMembers : false;\n this.isTrackingMembers = copy ? copy.isTrackingMembers : false;\n this.avatarUrl = copy ? copy.avatarUrl : null;\n this.notificationCount = copy ? copy.notificationCount : 0;\n this.highlightCount = copy ? copy.highlightCount : 0;\n this.tags = copy ? copy.tags : null;\n this.isDirectMessage = copy ? copy.isDirectMessage : false;\n this.dmUserId = copy ? copy.dmUserId : null;\n this.cloned = copy ? true : false;\n }\n\n changedKeys(other) {\n const props = Object.getOwnPropertyNames(this);\n return props.filter(prop => {\n return prop !== \"cloned\" && this[prop] !== other[prop]\n });\n }\n\n cloneIfNeeded() {\n if (this.cloned) {\n return this;\n } else {\n return new SummaryData(this);\n }\n }\n\n serialize() {\n return Object.entries(this).reduce((obj, [key, value]) => {\n if (key !== \"cloned\" && value !== null) {\n obj[key] = value;\n }\n return obj;\n }, {});\n }\n\n applyTimelineEntries(timelineEntries, isInitialSync, canMarkUnread, ownUserId) {\n return applyTimelineEntries(this, timelineEntries, isInitialSync, canMarkUnread, ownUserId);\n }\n\n applySyncResponse(roomResponse, membership, ownUserId) {\n return applySyncResponse(this, roomResponse, membership, ownUserId);\n }\n\n get needsHeroes() {\n return !this.name && !this.canonicalAlias && this.heroes && this.heroes.length > 0;\n }\n\n isNewJoin(oldData) {\n return this.membership === \"join\" && oldData.membership !== \"join\";\n }\n}\n\nexport class RoomSummary {\n\tconstructor(roomId) {\n this._data = null;\n this.applyChanges(new SummaryData(null, roomId));\n\t}\n\n get data() {\n return this._data;\n }\n\n writeClearUnread(txn) {\n const data = new SummaryData(this._data);\n data.isUnread = false;\n data.notificationCount = 0;\n data.highlightCount = 0;\n txn.roomSummary.set(data.serialize());\n return data;\n }\n\n writeHasFetchedMembers(value, txn) {\n const data = new SummaryData(this._data);\n data.hasFetchedMembers = value;\n txn.roomSummary.set(data.serialize());\n return data;\n }\n\n writeIsTrackingMembers(value, txn) {\n const data = new SummaryData(this._data);\n data.isTrackingMembers = value;\n txn.roomSummary.set(data.serialize());\n return data;\n }\n\n\twriteData(data, txn) {\n\t\tif (data !== this._data) {\n txn.roomSummary.set(data.serialize());\n return data;\n\t\t}\n\t}\n\n /** move summary to archived store when leaving the room */\n writeArchivedData(data, txn) {\n if (data !== this._data) {\n txn.archivedRoomSummary.set(data.serialize());\n return data;\n }\n }\n\n async writeAndApplyData(data, storage) {\n if (data === this._data) {\n return false;\n }\n const txn = await storage.readWriteTxn([\n storage.storeNames.roomSummary,\n ]);\n try {\n txn.roomSummary.set(data.serialize());\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n this.applyChanges(data);\n return true;\n }\n\n applyChanges(data) {\n this._data = data;\n // clear cloned flag, so cloneIfNeeded makes a copy and\n // this._data is not modified if any field is changed.\n this._data.cloned = false;\n }\n\n\tasync load(summary) {\n this.applyChanges(new SummaryData(summary));\n\t}\n}\n\nexport function tests() {\n return {\n \"serialize doesn't include null fields or cloned\": assert => {\n const roomId = \"!123:hs.tld\";\n const data = new SummaryData(null, roomId);\n const clone = data.cloneIfNeeded();\n const serialized = clone.serialize();\n assert.strictEqual(serialized.cloned, undefined);\n assert.equal(serialized.roomId, roomId);\n const nullCount = Object.values(serialized).reduce((count, value) => count + value === null ? 1 : 0, 0);\n assert.strictEqual(nullCount, 0);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport enum StoreNames {\n session = \"session\",\n roomState = \"roomState\",\n roomSummary = \"roomSummary\",\n archivedRoomSummary = \"archivedRoomSummary\",\n invites = \"invites\",\n roomMembers = \"roomMembers\",\n timelineEvents = \"timelineEvents\",\n timelineRelations = \"timelineRelations\",\n timelineFragments = \"timelineFragments\",\n pendingEvents = \"pendingEvents\",\n userIdentities = \"userIdentities\",\n deviceKeys = \"deviceKeys\",\n olmSessions = \"olmSessions\",\n inboundGroupSessions = \"inboundGroupSessions\",\n outboundGroupSessions = \"outboundGroupSessions\",\n groupSessionDecryptions = \"groupSessionDecryptions\",\n operations = \"operations\",\n accountData = \"accountData\",\n calls = \"calls\",\n crossSigningKeys = \"crossSigningKeys\",\n sharedSecrets = \"sharedSecrets\",\n}\n\nexport const STORE_NAMES: Readonly = Object.values(StoreNames);\n\nexport class StorageError extends Error {\n errcode?: string;\n cause: Error | null;\n\n constructor(message: string, cause: Error | null = null) {\n super(message);\n if (cause) {\n this.errcode = cause.name;\n }\n this.cause = cause;\n }\n\n get name(): string {\n return \"StorageError\";\n }\n}\n\nexport const KeyLimits = {\n get minStorageKey(): number {\n // for indexeddb, we use unsigned 32 bit integers as keys\n return 0;\n },\n \n get middleStorageKey(): number {\n // for indexeddb, we use unsigned 32 bit integers as keys\n return 0x7FFFFFFF;\n },\n\n get maxStorageKey(): number {\n // for indexeddb, we use unsigned 32 bit integers as keys\n return 0xFFFFFFFF;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {KeyLimits} from \"../../storage/common\";\nimport {Direction} from \"./Direction\";\n\n// key for events in the timelineEvents store\nexport class EventKey {\n constructor(\n public fragmentId: number,\n public eventIndex: number\n ) {\n }\n\n nextFragmentKey(): EventKey {\n // could take MIN_EVENT_INDEX here if it can't be paged back\n return new EventKey(this.fragmentId + 1, KeyLimits.middleStorageKey);\n }\n\n nextKeyForDirection(direction: Direction): EventKey {\n if (direction.isForward) {\n return this.nextKey();\n } else {\n return this.previousKey();\n }\n }\n\n previousKey(): EventKey {\n return new EventKey(this.fragmentId, this.eventIndex - 1);\n }\n\n nextKey(): EventKey {\n return new EventKey(this.fragmentId, this.eventIndex + 1);\n }\n\n static get maxKey(): EventKey {\n return new EventKey(KeyLimits.maxStorageKey, KeyLimits.maxStorageKey);\n }\n\n static get minKey(): EventKey {\n return new EventKey(KeyLimits.minStorageKey, KeyLimits.minStorageKey);\n }\n\n static get defaultLiveKey(): EventKey {\n return EventKey.defaultFragmentKey(KeyLimits.minStorageKey);\n }\n\n static defaultFragmentKey(fragmentId: number): EventKey {\n return new EventKey(fragmentId, KeyLimits.middleStorageKey);\n }\n\n toString(): string {\n return `[${this.fragmentId}/${this.eventIndex}]`;\n }\n\n equals(other: EventKey): boolean {\n return this.fragmentId === other?.fragmentId && this.eventIndex === other?.eventIndex;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n//entries can be sorted, first by fragment, then by entry index.\nimport {EventKey} from \"../EventKey\";\nexport const PENDING_FRAGMENT_ID = Number.MAX_SAFE_INTEGER;\n\ninterface FragmentIdComparer {\n compare: (a: number, b: number) => number\n}\n\nexport abstract class BaseEntry {\n constructor(\n protected readonly _fragmentIdComparer: FragmentIdComparer\n ) {\n }\n\n abstract get fragmentId(): number;\n abstract get entryIndex(): number;\n abstract updateFrom(other: BaseEntry): void;\n\n compare(otherEntry: BaseEntry): number {\n if (this.fragmentId === otherEntry.fragmentId) {\n return this.entryIndex - otherEntry.entryIndex;\n } else if (this.fragmentId === PENDING_FRAGMENT_ID) {\n return 1;\n } else if (otherEntry.fragmentId === PENDING_FRAGMENT_ID) {\n return -1;\n } else {\n // This might throw if the relation of two fragments is unknown.\n return this._fragmentIdComparer.compare(this.fragmentId, otherEntry.fragmentId);\n }\n }\n\n asEventKey(): EventKey {\n return new EventKey(this.fragmentId, this.entryIndex);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {REDACTION_TYPE} from \"../common\";\n\nexport const REACTION_TYPE = \"m.reaction\";\nexport const ANNOTATION_RELATION_TYPE = \"m.annotation\";\nexport const REFERENCE_RELATION_TYPE = \"m.reference\";\n\nexport function createAnnotation(targetId, key) {\n return {\n \"m.relates_to\": {\n \"event_id\": targetId,\n key,\n \"rel_type\": ANNOTATION_RELATION_TYPE\n }\n };\n}\n\nexport function createReference(targetId) {\n return {\n \"m.relates_to\": {\n \"event_id\": targetId,\n \"rel_type\": REFERENCE_RELATION_TYPE\n }\n };\n}\n\nexport function getRelationTarget(relation) {\n return relation.event_id || relation[\"m.in_reply_to\"]?.event_id\n}\n\nexport function setRelationTarget(relation, target) {\n if (relation.event_id !== undefined) {\n relation.event_id = target;\n } else if (relation[\"m.in_reply_to\"]) {\n relation[\"m.in_reply_to\"].event_id = target;\n }\n}\n\nexport function getRelatedEventId(event) {\n\tif (event.type === REDACTION_TYPE) {\n return event.redacts;\n } else {\n const relation = getRelation(event);\n if (relation) {\n return getRelationTarget(relation);\n }\n }\n return null;\n}\n\nexport function getRelationFromContent(content) {\n return content?.[\"m.relates_to\"];\n}\n\nexport function getRelation(event) {\n\treturn getRelationFromContent(event.content);\n}\n\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class PendingAnnotation {\n constructor() {\n // TODO: use simple member for reaction and redaction as we can't/shouldn't really have more than 2 entries\n // this contains both pending annotation entries, and pending redactions of remote annotation entries \n this._entries = [];\n }\n\n get firstTimestamp() {\n return this._entries.reduce((ts, e) => {\n if (e.isRedaction) {\n return ts;\n }\n return Math.min(e.timestamp, ts);\n }, Number.MAX_SAFE_INTEGER);\n }\n\n get annotationEntry() {\n return this._entries.find(e => !e.isRedaction);\n }\n\n get redactionEntry() {\n return this._entries.find(e => e.isRedaction);\n }\n\n get count() {\n return this._entries.reduce((count, e) => {\n return count + (e.isRedaction ? -1 : 1);\n }, 0);\n }\n\n add(entry) {\n this._entries.push(entry);\n }\n\n remove(entry) {\n const idx = this._entries.indexOf(entry);\n if (idx === -1) {\n return false;\n }\n this._entries.splice(idx, 1);\n return true;\n }\n\n get willAnnotate() {\n const lastEntry = this._entries.reduce((lastEntry, e) => {\n if (!lastEntry || e.pendingEvent.queueIndex > lastEntry.pendingEvent.queueIndex) {\n return e;\n }\n return lastEntry;\n }, null);\n if (lastEntry) {\n return !lastEntry.isRedaction;\n }\n return false;\n }\n\n get isEmpty() {\n return this._entries.length === 0;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nfunction htmlEscape(string) {\n return string.replace(/&/g, \"&\").replace(//g, \">\");\n}\n\nfunction fallbackForNonTextualMessage(msgtype) {\n switch (msgtype) {\n case \"m.file\":\n return \"sent a file.\";\n case \"m.image\":\n return \"sent an image.\";\n case \"m.video\":\n return \"sent a video.\";\n case \"m.audio\":\n return \"sent an audio file.\";\n }\n return null;\n}\n\nfunction fallbackPrefix(msgtype) {\n return msgtype === \"m.emote\" ? \"* \" : \"\";\n}\n\nfunction _createReplyContent(targetId, msgtype, body, formattedBody) {\n return {\n msgtype,\n body,\n \"format\": \"org.matrix.custom.html\",\n \"formatted_body\": formattedBody,\n \"m.relates_to\": {\n \"m.in_reply_to\": {\n \"event_id\": targetId\n }\n }\n };\n}\n\nexport function createReplyContent(entry, msgtype, body) {\n // TODO check for absense of sender / body / msgtype / etc?\n const nonTextual = fallbackForNonTextualMessage(entry.content.msgtype);\n const prefix = fallbackPrefix(entry.content.msgtype);\n const sender = entry.sender;\n const name = entry.displayName || sender;\n\n const formattedBody = nonTextual || entry.content.formatted_body ||\n (entry.content.body && htmlEscape(entry.content.body)) || \"\";\n const formattedFallback = `

In reply to ${prefix}` +\n `${name}
` +\n `${formattedBody}
`;\n\n const plainBody = nonTextual || entry.content.body || \"\";\n const bodyLines = plainBody.split(\"\\n\");\n bodyLines[0] = `> ${prefix}<${sender}> ${bodyLines[0]}`\n const plainFallback = bodyLines.join(\"\\n> \");\n\n const newBody = plainFallback + '\\n\\n' + body;\n const newFormattedBody = formattedFallback + htmlEscape(body);\n return _createReplyContent(entry.id, msgtype, newBody, newFormattedBody);\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseEntry} from \"./BaseEntry\";\nimport {REDACTION_TYPE} from \"../../common\";\nimport {createAnnotation, ANNOTATION_RELATION_TYPE, getRelationFromContent, REFERENCE_RELATION_TYPE} from \"../relations.js\";\nimport {PendingAnnotation} from \"../PendingAnnotation.js\";\nimport {createReplyContent} from \"./reply.js\"\n\n/** Deals mainly with local echo for relations and redactions,\n * so it is shared between PendingEventEntry and EventEntry */\nexport class BaseEventEntry extends BaseEntry {\n constructor(fragmentIdComparer) {\n super(fragmentIdComparer);\n this._pendingRedactions = null;\n this._pendingAnnotations = null;\n this._contextEntry = null;\n this._contextForEntries = null;\n }\n\n get isReply() {\n return !!this.relation?.[\"m.in_reply_to\"];\n }\n\n get isReference() {\n return this.relation?.rel_type === REFERENCE_RELATION_TYPE;\n }\n\n get isRedacting() {\n return !!this._pendingRedactions;\n }\n\n get isRedacted() {\n return this.isRedacting;\n }\n\n get isRedaction() {\n return this.eventType === REDACTION_TYPE;\n }\n\n get redactionReason() {\n if (this._pendingRedactions) {\n return this._pendingRedactions[0].content?.reason;\n }\n return null;\n }\n\n setContextEntry(entry) {\n this._contextEntry = entry;\n entry._setAsContextOf(this);\n }\n\n _setAsContextOf(entry) {\n if (!this._contextForEntries) {\n this._contextForEntries = [];\n }\n this._contextForEntries.push(entry);\n }\n\n get contextForEntries() {\n return this._contextForEntries;\n }\n\n get contextEntry() {\n return this._contextEntry;\n }\n\n /**\n Aggregates relation or redaction of remote relation. \n Used in two situations:\n - to aggregate local relation/redaction of remote relation\n - to mark this entry as being redacted in Timeline._updateEntriesFetchedFromHomeserver\n @return [string] returns the name of the field that has changed, if any\n */\n addLocalRelation(entry) {\n if (entry.eventType === REDACTION_TYPE && entry.isRelatedToId(this.id)) {\n if (!this._pendingRedactions) {\n this._pendingRedactions = [];\n }\n this._pendingRedactions.push(entry);\n if (this._pendingRedactions.length === 1) {\n return \"isRedacted\";\n }\n } else {\n const relationEntry = entry.redactingEntry || entry;\n if (relationEntry.isRelatedToId(this.id)) {\n if (relationEntry.relation.rel_type === ANNOTATION_RELATION_TYPE) {\n if (this._addPendingAnnotation(entry)) {\n return \"pendingAnnotations\";\n }\n }\n }\n }\n }\n \n /**\n deaggregates local relation or a local redaction of a remote relation.\n @return [string] returns the name of the field that has changed, if any\n */\n removeLocalRelation(entry) {\n if (entry.eventType === REDACTION_TYPE && entry.isRelatedToId(this.id) && this._pendingRedactions) {\n const countBefore = this._pendingRedactions.length;\n this._pendingRedactions = this._pendingRedactions.filter(e => e !== entry);\n if (this._pendingRedactions.length === 0) {\n this._pendingRedactions = null;\n if (countBefore !== 0) {\n return \"isRedacted\";\n }\n }\n } else {\n const relationEntry = entry.redactingEntry || entry;\n if (relationEntry.isRelatedToId(this.id)) {\n if (relationEntry.relation?.rel_type === ANNOTATION_RELATION_TYPE && this._pendingAnnotations) {\n if (this._removePendingAnnotation(entry)) {\n return \"pendingAnnotations\";\n }\n }\n }\n }\n }\n\n _addPendingAnnotation(entry) {\n if (!this._pendingAnnotations) {\n this._pendingAnnotations = new Map();\n }\n const {key} = (entry.redactingEntry || entry).relation;\n if (key) {\n let annotation = this._pendingAnnotations.get(key);\n if (!annotation) {\n annotation = new PendingAnnotation();\n this._pendingAnnotations.set(key, annotation);\n }\n annotation.add(entry);\n return true;\n }\n return false;\n }\n\n _removePendingAnnotation(entry) {\n const {key} = (entry.redactingEntry || entry).relation;\n if (key) {\n let annotation = this._pendingAnnotations.get(key);\n if (annotation.remove(entry) && annotation.isEmpty) {\n this._pendingAnnotations.delete(key);\n }\n if (this._pendingAnnotations.size === 0) {\n this._pendingAnnotations = null;\n }\n return true;\n }\n return false;\n }\n\n async abortPendingRedaction() {\n if (this._pendingRedactions) {\n for (const pee of this._pendingRedactions) {\n await pee.pendingEvent.abort();\n }\n // removing the pending events will call removeLocalRelation,\n // so don't clear _pendingRedactions here\n }\n }\n\n get pendingRedaction() {\n if (this._pendingRedactions) {\n return this._pendingRedactions[0];\n }\n return null;\n }\n\n annotate(key) {\n return createAnnotation(this.id, key);\n }\n\n createReplyContent(msgtype, body) {\n return createReplyContent(this, msgtype, body);\n }\n\n /** takes both remote event id and local txn id into account, see overriding in PendingEventEntry */\n isRelatedToId(id) {\n return id && this.relatedEventId === id;\n }\n\n haveAnnotation(key) {\n const haveRemoteReaction = this.annotations?.[key]?.me || false;\n const pendingAnnotation = this.pendingAnnotations?.get(key);\n const willAnnotate = pendingAnnotation?.willAnnotate || false;\n /*\n We have an annotation in these case:\n - remote annotation with me, no pending\n - remote annotation with me, pending redaction and then annotation\n - pending annotation without redaction after it\n */\n return (haveRemoteReaction && (!pendingAnnotation || willAnnotate)) ||\n (!haveRemoteReaction && willAnnotate);\n }\n\n get relation() {\n return getRelationFromContent(this.content);\n }\n\n get pendingAnnotations() {\n return this._pendingAnnotations;\n }\n\n get annotations() {\n return null; //overwritten in EventEntry\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {PENDING_FRAGMENT_ID} from \"./BaseEntry\";\nimport {BaseEventEntry} from \"./BaseEventEntry.js\";\n\nexport class PendingEventEntry extends BaseEventEntry {\n constructor({pendingEvent, member, clock, redactingEntry}) {\n super(null);\n this._pendingEvent = pendingEvent;\n /** @type {RoomMember} */\n this._member = member;\n // try to come up with a timestamp that is around construction time and\n // will be roughly sorted by queueIndex, so it can be used to as a secondary\n // sorting dimension for reactions\n this._timestamp = clock.now() - (100 - pendingEvent.queueIndex);\n this._redactingEntry = redactingEntry;\n }\n\n get fragmentId() {\n return PENDING_FRAGMENT_ID;\n }\n\n get entryIndex() {\n return this._pendingEvent.queueIndex;\n }\n\n get content() {\n return this._pendingEvent.content;\n }\n\n get event() {\n return null;\n }\n\n get eventType() {\n return this._pendingEvent.eventType;\n }\n\n get stateKey() {\n return null;\n }\n\n get sender() {\n return this._member?.userId;\n }\n\n get displayName() {\n return this._member?.name;\n }\n\n get avatarUrl() {\n return this._member?.avatarUrl;\n }\n\n get timestamp() {\n return this._timestamp;\n }\n\n get isPending() {\n return true;\n }\n\n get id() {\n return this._pendingEvent.txnId;\n }\n\n get pendingEvent() {\n return this._pendingEvent;\n }\n\n notifyUpdate() {\n \n }\n\n isRelatedToId(id) {\n if (id && id === this._pendingEvent.relatedTxnId) {\n return true;\n }\n return super.isRelatedToId(id);\n }\n\n get relatedEventId() {\n return this._pendingEvent.relatedEventId;\n }\n\n get redactingEntry() {\n return this._redactingEntry;\n }\n\n get contextEventId() {\n if (this.isReply) {\n return this._pendingEvent.relatedEventId ?? this._pendingEvent.relatedTxnId;\n }\n return null;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class Deferred {\n public readonly promise: Promise;\n public readonly resolve: (value: T) => void;\n public readonly reject: (err: Error) => void;\n private _value?: T;\n\n constructor() {\n let resolve;\n let reject;\n this.promise = new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n })\n this.resolve = (value: T) => {\n this._value = value;\n resolve(value);\n };\n this.reject = reject;\n }\n\n get value(): T | undefined {\n return this._value;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {createEnum} from \"../../../utils/enum\";\nimport {AbortError} from \"../../../utils/error\";\nimport {Deferred} from \"../../../utils/Deferred\";\nimport {REDACTION_TYPE} from \"../common\";\nimport {getRelationFromContent, getRelationTarget, setRelationTarget} from \"../timeline/relations.js\";\n\nexport const SendStatus = createEnum(\n \"Waiting\",\n \"EncryptingAttachments\",\n \"UploadingAttachments\",\n \"Encrypting\",\n \"Sending\",\n \"Sent\",\n \"Error\",\n);\n\nconst unencryptedContentFields = [ \"m.relates_to\" ];\n\nexport class PendingEvent {\n constructor({data, remove, emitUpdate, attachments}) {\n this._data = data;\n this._attachments = attachments;\n this._emitUpdate = emitUpdate;\n this._removeFromQueueCallback = remove;\n this._aborted = false;\n this._status = SendStatus.Waiting;\n this._sendRequest = null;\n this._attachmentsTotalBytes = 0;\n this._deferred = new Deferred()\n if (this._attachments) {\n this._attachmentsTotalBytes = Object.values(this._attachments).reduce((t, a) => t + a.size, 0);\n }\n }\n\n get roomId() { return this._data.roomId; }\n get queueIndex() { return this._data.queueIndex; }\n get eventType() { return this._data.eventType; }\n get txnId() { return this._data.txnId; }\n get remoteId() { return this._data.remoteId; }\n get content() { return this._data.content; }\n get relatedTxnId() { return this._data.relatedTxnId; }\n get relatedEventId() {\n const relation = getRelationFromContent(this.content);\n if (relation) {\n // may be null when target is not sent yet, is intended\n return getRelationTarget(relation);\n } else {\n return this._data.relatedEventId;\n }\n }\n\n setRelatedEventId(eventId) {\n const relation = getRelationFromContent(this.content);\n if (relation) {\n setRelationTarget(relation, eventId);\n } else {\n this._data.relatedEventId = eventId;\n }\n }\n\n get data() { return this._data; }\n\n getAttachment(key) {\n return this._attachments && this._attachments[key];\n }\n\n get needsSending() {\n return !this.remoteId && !this.aborted;\n }\n\n get needsEncryption() {\n return this._data.needsEncryption && !this.aborted;\n }\n\n get needsUpload() {\n return this._data.needsUpload && !this.aborted;\n }\n\n get isMissingAttachments() {\n return this.needsUpload && !this._attachments;\n }\n\n setEncrypting() {\n this._status = SendStatus.Encrypting;\n this._emitUpdate(\"status\");\n }\n\n get contentForEncryption() {\n const content = Object.assign({}, this._data.content);\n for (const field of unencryptedContentFields) {\n delete content[field];\n }\n return content;\n }\n\n _preserveContentFields(into) {\n const content = this._data.content;\n for (const field of unencryptedContentFields) {\n if (content[field] !== undefined) {\n into[field] = content[field];\n }\n }\n }\n\n setEncrypted(type, content) {\n this._preserveContentFields(content);\n this._data.encryptedEventType = type;\n this._data.encryptedContent = content;\n this._data.needsEncryption = false;\n }\n\n setError(error) {\n this._status = SendStatus.Error;\n this._error = error;\n this._emitUpdate(\"status\");\n }\n\n setWaiting() {\n this._status = SendStatus.Waiting;\n this._emitUpdate(\"status\");\n }\n\n get status() { return this._status; }\n get error() { return this._error; }\n\n get hasStartedSending() {\n return this._status === SendStatus.Sending || this._status === SendStatus.Sent;\n }\n\n get attachmentsTotalBytes() {\n return this._attachmentsTotalBytes;\n }\n\n get attachmentsSentBytes() {\n return this._attachments && Object.values(this._attachments).reduce((t, a) => t + a.sentBytes, 0);\n }\n\n async uploadAttachments(hsApi, log) {\n if (!this.needsUpload) {\n return;\n }\n if (!this._attachments) {\n throw new Error(\"attachments missing\");\n }\n if (this.needsEncryption) {\n this._status = SendStatus.EncryptingAttachments;\n this._emitUpdate(\"status\");\n for (const attachment of Object.values(this._attachments)) {\n await log.wrap(\"encrypt\", () => {\n log.set(\"size\", attachment.size);\n return attachment.encrypt();\n });\n if (this.aborted) {\n throw new AbortError();\n }\n }\n }\n this._status = SendStatus.UploadingAttachments;\n this._emitUpdate(\"status\");\n const entries = Object.entries(this._attachments);\n // upload smallest attachments first\n entries.sort(([, a1], [, a2]) => a1.size - a2.size);\n for (const [urlPath, attachment] of entries) {\n await log.wrap(\"upload\", log => {\n log.set(\"size\", attachment.size);\n return attachment.upload(hsApi, () => {\n this._emitUpdate(\"attachmentsSentBytes\");\n }, log);\n });\n attachment.applyToContent(urlPath, this.content);\n }\n this._data.needsUpload = false;\n }\n\n async abort() {\n if (!this._aborted) {\n this._aborted = true;\n if (this._attachments) {\n for (const attachment of Object.values(this._attachments)) {\n attachment.abort();\n }\n }\n this._sendRequest?.abort();\n await this._removeFromQueueCallback();\n }\n }\n\n get aborted() {\n return this._aborted;\n }\n\n async send(hsApi, log) {\n this._status = SendStatus.Sending;\n this._emitUpdate(\"status\");\n const eventType = this._data.encryptedEventType || this._data.eventType;\n const content = this._data.encryptedContent || this._data.content;\n if (eventType === REDACTION_TYPE) {\n this._sendRequest = hsApi.redact(\n this.roomId,\n this._data.relatedEventId,\n this.txnId,\n content,\n {log}\n );\n } else {\n this._sendRequest = hsApi.send(\n this.roomId,\n eventType,\n this.txnId,\n content,\n {log}\n );\n }\n const response = await this._sendRequest.response();\n this._sendRequest = null;\n // both /send and /redact have the same response format\n this._data.remoteId = response.event_id;\n this._deferred.resolve(response.event_id);\n log.set(\"id\", this._data.remoteId);\n this._status = SendStatus.Sent;\n this._emitUpdate(\"status\");\n }\n\n getRemoteId() {\n return this._deferred.promise;\n }\n\n dispose() {\n if (this._attachments) {\n for (const attachment of Object.values(this._attachments)) {\n attachment.dispose();\n }\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseEventEntry} from \"./BaseEventEntry.js\";\nimport {getPrevContentFromStateEvent, isRedacted} from \"../../common\";\nimport {getRelationFromContent, getRelatedEventId} from \"../relations.js\";\n\nexport class EventEntry extends BaseEventEntry {\n constructor(eventEntry, fragmentIdComparer) {\n super(fragmentIdComparer);\n this._eventEntry = eventEntry;\n this._decryptionError = null;\n this._decryptionResult = null;\n }\n\n clone() {\n const clone = new EventEntry(this._eventEntry, this._fragmentIdComparer);\n clone.updateFrom(this);\n return clone;\n }\n\n updateFrom(other) {\n // only update these when we attempted decryption, as some updates (like reactions) don't.\n if (other._decryptionResult) {\n this._decryptionResult = other._decryptionResult;\n }\n if (other._decryptionError) {\n this._decryptionError = other._decryptionError;\n }\n this._contextForEntries = other.contextForEntries;\n this._contextEntry = other.contextEntry;\n }\n\n get event() {\n return this._eventEntry.event;\n }\n\n get fragmentId() {\n return this._eventEntry.fragmentId;\n }\n\n get entryIndex() {\n return this._eventEntry.eventIndex;\n }\n\n get content() {\n return this._decryptionResult?.event?.content || this._eventEntry.event.content;\n }\n\n get prevContent() {\n // doesn't look at _decryptionResult because state events are not encrypted\n return getPrevContentFromStateEvent(this._eventEntry.event);\n }\n\n get eventType() {\n return this._decryptionResult?.event?.type || this._eventEntry.event.type;\n }\n\n get stateKey() {\n return this._eventEntry.event.state_key;\n }\n\n get sender() {\n return this._eventEntry.event.sender;\n }\n\n get displayName() {\n return this._eventEntry.displayName;\n }\n\n get avatarUrl() {\n return this._eventEntry.avatarUrl;\n }\n\n get timestamp() {\n return this._eventEntry.event.origin_server_ts;\n }\n\n get id() {\n return this._eventEntry.event.event_id;\n }\n\n setDecryptionResult(result) {\n this._decryptionResult = result;\n }\n\n get isEncrypted() {\n return this._eventEntry.event.type === \"m.room.encrypted\";\n }\n\n get isDecrypted() {\n return !!this._decryptionResult?.event;\n }\n\n get isVerified() {\n return this.isEncrypted && this._decryptionResult?.isVerified;\n }\n\n get isUnverified() {\n return this.isEncrypted && this._decryptionResult?.isUnverified;\n }\n\n setDecryptionError(err) {\n this._decryptionError = err;\n }\n\n get decryptionError() {\n return this._decryptionError;\n }\n\n get relatedEventId() {\n return getRelatedEventId(this.event);\n }\n\n get isRedacted() {\n return super.isRedacted || isRedacted(this._eventEntry.event);\n }\n\n get redactionReason() {\n const redactionEvent = this._eventEntry.event.unsigned?.redacted_because;\n if (redactionEvent) {\n return redactionEvent.content?.reason;\n }\n // fall back to local echo reason\n return super.redactionReason;\n }\n\n get annotations() {\n return this._eventEntry.annotations;\n }\n\n get relation() {\n const originalContent = this._eventEntry.event.content;\n const originalRelation = originalContent && getRelationFromContent(originalContent);\n return originalRelation || getRelationFromContent(this.content);\n }\n\n // similar to relatedEventID but only for replies and reference relations\n get contextEventId() {\n if (this.isReply || this.isReference) {\n return this.relatedEventId;\n }\n return null;\n }\n\n}\n\nimport {withTextBody, withContent, createEvent} from \"../../../../mocks/event.js\";\nimport {Clock as MockClock} from \"../../../../mocks/Clock.js\";\nimport {PendingEventEntry} from \"./PendingEventEntry.js\";\nimport {PendingEvent} from \"../../sending/PendingEvent.js\";\nimport {createAnnotation} from \"../relations.js\";\n\nexport function tests() {\n let queueIndex = 0;\n const clock = new MockClock();\n\n function addPendingReaction(target, key) {\n queueIndex += 1;\n target.addLocalRelation(new PendingEventEntry({\n pendingEvent: new PendingEvent({data: {\n eventType: \"m.reaction\",\n content: createAnnotation(target.id, key),\n queueIndex,\n txnId: `t${queueIndex}`\n }}),\n clock\n }));\n return target;\n }\n\n function addPendingRedaction(target, key) {\n const pendingReaction = target.pendingAnnotations?.get(key)?.annotationEntry;\n let redactingEntry = pendingReaction;\n // make up a remote entry if we don't have a pending reaction and have an aggregated remote entry\n if (!pendingReaction && target.annotations[key].me) {\n redactingEntry = new EventEntry({\n event: withContent(createAnnotation(target.id, key), createEvent(\"m.reaction\", \"!def\"))\n });\n }\n queueIndex += 1;\n target.addLocalRelation(new PendingEventEntry({\n pendingEvent: new PendingEvent({data: {\n eventType: \"m.room.redaction\",\n relatedTxnId: pendingReaction ? pendingReaction.id : null,\n relatedEventId: pendingReaction ? null : redactingEntry.id,\n queueIndex,\n txnId: `t${queueIndex}`\n }}),\n redactingEntry,\n clock\n }));\n return target;\n }\n\n function remoteAnnotation(key, me, count, obj = {}) {\n obj[key] = {me, count};\n return obj;\n }\n\n return {\n // testing it here because parent class always assumes annotations is null\n \"haveAnnotation\": assert => {\n const msgEvent = withTextBody(\"hi!\", createEvent(\"m.room.message\", \"!abc\"));\n const e1 = new EventEntry({event: msgEvent});\n assert.equal(false, e1.haveAnnotation(\"🚀\"));\n const e2 = new EventEntry({event: msgEvent, annotations: remoteAnnotation(\"🚀\", false, 1)});\n assert.equal(false, e2.haveAnnotation(\"🚀\"));\n const e3 = new EventEntry({event: msgEvent, annotations: remoteAnnotation(\"🚀\", true, 1)});\n assert.equal(true, e3.haveAnnotation(\"🚀\"));\n const e4 = new EventEntry({event: msgEvent, annotations: remoteAnnotation(\"🚀\", true, 2)});\n assert.equal(true, e4.haveAnnotation(\"🚀\"));\n const e5 = addPendingReaction(new EventEntry({event: msgEvent}), \"🚀\");\n assert.equal(true, e5.haveAnnotation(\"🚀\"));\n const e6 = addPendingRedaction(new EventEntry({event: msgEvent, annotations: remoteAnnotation(\"🚀\", true, 1)}), \"🚀\");\n assert.equal(false, e6.haveAnnotation(\"🚀\"));\n const e7 = addPendingReaction(\n addPendingRedaction(\n new EventEntry({event: msgEvent, annotations: remoteAnnotation(\"🚀\", true, 1)}),\n \"🚀\"),\n \"🚀\");\n assert.equal(true, e7.haveAnnotation(\"🚀\"));\n const e8 = addPendingRedaction(\n addPendingReaction(\n new EventEntry({event: msgEvent}),\n \"🚀\"),\n \"🚀\");\n assert.equal(false, e8.haveAnnotation(\"🚀\"));\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function createEventEntry(key, roomId, event) {\n return {\n fragmentId: key.fragmentId,\n eventIndex: key.eventIndex,\n roomId,\n event: event,\n };\n}\n\nexport function directionalAppend(array, value, direction) {\n if (direction.isForward) {\n array.push(value);\n } else {\n array.unshift(value);\n }\n}\n\nexport function directionalConcat(array, otherArray, direction) {\n if (direction.isForward) {\n return array.concat(otherArray);\n } else {\n return otherArray.concat(array);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {getPrevContentFromStateEvent} from \"../common\";\n\nexport const EVENT_TYPE = \"m.room.member\";\n\nexport class RoomMember {\n constructor(data) {\n this._data = data;\n }\n\n static fromUserId(roomId, userId, membership) {\n return new RoomMember({roomId, userId, membership});\n }\n\n static fromMemberEvent(roomId, memberEvent) {\n const userId = memberEvent?.state_key;\n if (typeof userId !== \"string\") {\n return;\n }\n const content = memberEvent.content;\n const prevContent = getPrevContentFromStateEvent(memberEvent);\n const membership = content?.membership;\n // fall back to prev_content for these as synapse doesn't (always?)\n // put them on content for \"leave\" memberships\n const displayName = content?.displayname || prevContent?.displayname;\n const avatarUrl = content?.avatar_url || prevContent?.avatar_url;\n return this._validateAndCreateMember(roomId, userId, membership, displayName, avatarUrl);\n }\n /**\n * Creates a (historical) member from a member event that is the next member event\n * after the point in time where we need a member for. This will use `prev_content`.\n */\n static fromReplacingMemberEvent(roomId, memberEvent) {\n const userId = memberEvent && memberEvent.state_key;\n if (typeof userId !== \"string\") {\n return;\n }\n const content = getPrevContentFromStateEvent(memberEvent);\n return this._validateAndCreateMember(roomId, userId,\n content?.membership,\n content?.displayname,\n content?.avatar_url\n );\n }\n\n static _validateAndCreateMember(roomId, userId, membership, displayName, avatarUrl) {\n if (typeof membership !== \"string\") {\n return;\n }\n return new RoomMember({\n roomId,\n userId,\n membership,\n avatarUrl,\n displayName,\n });\n }\n\n get membership() {\n return this._data.membership;\n }\n\n /**\n * @return {String?} the display name, if any\n */\n get displayName() {\n return this._data.displayName;\n }\n\n /**\n * @return {String} the display name or userId\n */\n get name() {\n return this._data.displayName || this._data.userId;\n }\n\n /**\n * @return {String?} the avatar mxc url, if any\n */\n get avatarUrl() {\n return this._data.avatarUrl;\n }\n\n get roomId() {\n return this._data.roomId;\n }\n\n get userId() {\n return this._data.userId;\n }\n\n serialize() {\n return this._data;\n }\n\n equals(other) {\n const data = this._data;\n const otherData = other._data;\n return data.roomId === otherData.roomId &&\n data.userId === otherData.userId &&\n data.membership === otherData.membership &&\n data.displayName === otherData.displayName &&\n data.avatarUrl === otherData.avatarUrl;\n }\n}\n\nexport class MemberChange {\n constructor(member, previousMembership) {\n this.member = member;\n this.previousMembership = previousMembership;\n }\n\n get roomId() {\n return this.member.roomId;\n }\n\n get userId() {\n return this.member.userId;\n }\n\n get membership() {\n return this.member.membership;\n }\n\n get wasInvited() {\n return this.previousMembership === \"invite\" && this.membership !== \"invite\";\n }\n\n get hasLeft() {\n return this.previousMembership === \"join\" && this.membership !== \"join\";\n }\n\n /** The result can be a false negative when all of these apply:\n * - the complete set of room members hasn't been fetched yet.\n * - the member event for this change was received in the\n * state section and wasn't present in the timeline section.\n * - the room response was limited, e.g. there was a gap.\n * \n * This is because during sync, in this case it is not possible\n * to distinguish between a new member that joined the room\n * during a gap and a lazy-loading member.\n * */\n get hasJoined() {\n return this.previousMembership !== \"join\" && this.membership === \"join\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function isValidFragmentId(id) {\n return typeof id === \"number\";\n}\n\n// copied over from matrix-js-sdk, copyright 2016 OpenMarket Ltd\n/* _REDACT_KEEP_KEY_MAP gives the keys we keep when an event is redacted\n *\n * This is specified here:\n * http://matrix.org/speculator/spec/HEAD/client_server/latest.html#redactions\n *\n * Also:\n * - We keep 'unsigned' since that is created by the local server\n * - We keep user_id for backwards-compat with v1\n */\nconst _REDACT_KEEP_KEY_MAP = [\n 'event_id', 'type', 'room_id', 'user_id', 'sender', 'state_key', 'prev_state',\n 'content', 'unsigned', 'origin_server_ts',\n].reduce(function(ret, val) {\n ret[val] = 1; return ret;\n}, {});\n\n// a map from event type to the .content keys we keep when an event is redacted\nconst _REDACT_KEEP_CONTENT_MAP = {\n 'm.room.member': {'membership': 1},\n 'm.room.create': {'creator': 1},\n 'm.room.join_rules': {'join_rule': 1},\n 'm.room.power_levels': {'ban': 1, 'events': 1, 'events_default': 1,\n 'kick': 1, 'redact': 1, 'state_default': 1,\n 'users': 1, 'users_default': 1,\n },\n 'm.room.aliases': {'aliases': 1},\n};\n// end of matrix-js-sdk code\n\nexport function redactEvent(redactionEvent, redactedEvent) {\n for (const key of Object.keys(redactedEvent)) {\n if (!_REDACT_KEEP_KEY_MAP[key]) {\n delete redactedEvent[key];\n }\n }\n const { content } = redactedEvent;\n const keepMap = _REDACT_KEEP_CONTENT_MAP[redactedEvent.type];\n for (const key of Object.keys(content)) {\n if (!keepMap?.[key]) {\n delete content[key];\n }\n }\n redactedEvent.unsigned = redactedEvent.unsigned || {};\n redactedEvent.unsigned.redacted_because = redactionEvent;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/*\nlookups will be far more frequent than changing fragment order,\nso data structure should be optimized for fast lookup\n\nwe can have a Map: fragmentId to sortIndex\n\nchanging the order, we would need to rebuild the index\nlets do this the stupid way for now, changing any fragment rebuilds all islands\n\nto build this:\nfirst load all fragments\nput them in a map by id\nnow iterate through them\n\nuntil no more fragments\n get the first\n create an island array, and add to list with islands\n going backwards and forwards\n get and remove sibling and prepend/append it to island array\n stop when no more previous/next\n return list with islands\n\n*/\n\nimport {isValidFragmentId} from \"./common.js\";\n\nfunction findBackwardSiblingFragments(current, byId) {\n const sortedSiblings = [];\n while (isValidFragmentId(current.previousId)) {\n const previous = byId.get(current.previousId);\n if (!previous) {\n break;\n }\n if (previous.nextId !== current.id) {\n throw new Error(`Previous fragment ${previous.id} doesn't point back to ${current.id}`);\n }\n byId.delete(current.previousId);\n sortedSiblings.unshift(previous);\n current = previous;\n }\n return sortedSiblings;\n}\n\nfunction findForwardSiblingFragments(current, byId) {\n const sortedSiblings = [];\n while (isValidFragmentId(current.nextId)) {\n const next = byId.get(current.nextId);\n if (!next) {\n break;\n }\n if (next.previousId !== current.id) {\n throw new Error(`Next fragment ${next.id} doesn't point back to ${current.id}`);\n }\n byId.delete(current.nextId);\n sortedSiblings.push(next);\n current = next;\n }\n return sortedSiblings;\n}\n\n\nfunction createIslands(fragments) {\n const byId = new Map();\n for(let f of fragments) {\n byId.set(f.id, f);\n }\n\n const islands = [];\n while(byId.size) {\n const current = byId.values().next().value;\n byId.delete(current.id);\n // new island\n const previousSiblings = findBackwardSiblingFragments(current, byId);\n const nextSiblings = findForwardSiblingFragments(current, byId);\n const island = previousSiblings.concat(current, nextSiblings);\n islands.push(island);\n }\n return islands.map(a => new Island(a));\n}\n\nclass Fragment {\n constructor(id, previousId, nextId) {\n this.id = id;\n this.previousId = previousId;\n this.nextId = nextId;\n }\n}\n\nclass Island {\n constructor(sortedFragments) {\n this._idToSortIndex = new Map();\n sortedFragments.forEach((f, i) => {\n this._idToSortIndex.set(f.id, i);\n });\n }\n\n compare(idA, idB) {\n const sortIndexA = this._idToSortIndex.get(idA);\n if (sortIndexA === undefined) {\n throw new Error(`first id ${idA} isn't part of this island`);\n }\n const sortIndexB = this._idToSortIndex.get(idB);\n if (sortIndexB === undefined) {\n throw new Error(`second id ${idB} isn't part of this island`);\n }\n return sortIndexA - sortIndexB;\n }\n\n get fragmentIds() {\n return this._idToSortIndex.keys();\n }\n}\n\nexport class CompareError extends Error {\n get name() { return \"CompareError\"; }\n}\n\n/*\nindex for fast lookup of how two fragments can be sorted\n*/\nexport class FragmentIdComparer {\n constructor(fragments) {\n this._fragmentsById = fragments.reduce((map, f) => {map.set(f.id, f); return map;}, new Map());\n this.rebuild(fragments);\n }\n\n _getIsland(id) {\n const island = this._idToIsland.get(id);\n if (island === undefined) {\n throw new CompareError(`Unknown fragment id ${id}`);\n }\n return island;\n }\n\n compare(idA, idB) {\n if (idA === idB) {\n return 0;\n }\n const islandA = this._getIsland(idA);\n const islandB = this._getIsland(idB);\n if (islandA !== islandB) {\n throw new CompareError(`${idA} and ${idB} are on different islands, can't tell order`);\n }\n return islandA.compare(idA, idB);\n }\n\n rebuild(fragments) {\n const islands = createIslands(fragments);\n this._idToIsland = new Map();\n for(let island of islands) {\n for(let id of island.fragmentIds) {\n this._idToIsland.set(id, island);\n }\n }\n }\n\n /** use for fragments coming out of persistence, not newly created ones, or also fragments for a new island (like for a permalink) */\n add(fragment) {\n const copy = new Fragment(fragment.id, fragment.previousId, fragment.nextId);\n this._fragmentsById.set(fragment.id, copy);\n this.rebuild(this._fragmentsById.values());\n }\n\n /** use for appending newly created fragments */\n append(id, previousId) {\n const fragment = new Fragment(id, previousId, null);\n const prevFragment = this._fragmentsById.get(previousId);\n if (prevFragment) {\n prevFragment.nextId = id;\n }\n this._fragmentsById.set(id, fragment);\n this.rebuild(this._fragmentsById.values());\n }\n\n /** use for prepending newly created fragments */\n prepend(id, nextId) {\n const fragment = new Fragment(id, null, nextId);\n const nextFragment = this._fragmentsById.get(nextId);\n if (nextFragment) {\n nextFragment.previousId = id;\n }\n this._fragmentsById.set(id, fragment);\n this.rebuild(this._fragmentsById.values());\n }\n}\n\nexport function tests() {\n return {\n test_1_island_3_fragments(assert) {\n const index = new FragmentIdComparer([\n {id: 3, previousId: 2},\n {id: 1, nextId: 2},\n {id: 2, nextId: 3, previousId: 1},\n ]);\n assert(index.compare(1, 2) < 0);\n assert(index.compare(2, 1) > 0);\n\n assert(index.compare(1, 3) < 0);\n assert(index.compare(3, 1) > 0);\n \n assert(index.compare(2, 3) < 0);\n assert(index.compare(3, 2) > 0);\n \n assert.equal(index.compare(1, 1), 0);\n },\n test_falsy_id(assert) {\n const index = new FragmentIdComparer([\n {id: 0, nextId: 1},\n {id: 1, previousId: 0},\n ]);\n assert(index.compare(0, 1) < 0);\n assert(index.compare(1, 0) > 0);\n },\n test_falsy_id_reverse(assert) {\n const index = new FragmentIdComparer([\n {id: 1, previousId: 0},\n {id: 0, nextId: 1},\n ]);\n assert(index.compare(0, 1) < 0);\n assert(index.compare(1, 0) > 0);\n },\n test_allow_unknown_id(assert) {\n // as we tend to load fragments incrementally\n // as events come into view, we need to allow\n // unknown previousId/nextId in the fragments that we do load\n assert.doesNotThrow(() => {\n new FragmentIdComparer([\n {id: 1, previousId: 2},\n {id: 0, nextId: 3},\n ]);\n });\n },\n test_throw_on_link_mismatch(assert) {\n // as we tend to load fragments incrementally\n // as events come into view, we need to allow\n // unknown previousId/nextId in the fragments that we do load\n assert.throws(() => {\n new FragmentIdComparer([\n {id: 1, previousId: 0},\n {id: 0, nextId: 2},\n ]);\n });\n },\n test_2_island_dont_compare(assert) {\n const index = new FragmentIdComparer([\n {id: 1},\n {id: 2},\n ]);\n assert.throws(() => index.compare(1, 2));\n assert.throws(() => index.compare(2, 1));\n },\n test_2_island_compare_internally(assert) {\n const index = new FragmentIdComparer([\n {id: 1, nextId: 2},\n {id: 2, previousId: 1},\n {id: 11, nextId: 12},\n {id: 12, previousId: 11},\n \n ]);\n\n assert(index.compare(1, 2) < 0);\n assert(index.compare(11, 12) < 0);\n \n assert.throws(() => index.compare(1, 11));\n assert.throws(() => index.compare(12, 2));\n },\n test_unknown_id(assert) {\n const index = new FragmentIdComparer([{id: 1}]);\n assert.throws(() => index.compare(1, 2));\n assert.throws(() => index.compare(2, 1));\n },\n test_rebuild_flushes_old_state(assert) {\n const index = new FragmentIdComparer([\n {id: 1, nextId: 2},\n {id: 2, previousId: 1},\n ]);\n index.rebuild([\n {id: 11, nextId: 12},\n {id: 12, previousId: 11},\n ]);\n \n assert.throws(() => index.compare(1, 2));\n assert(index.compare(11, 12) < 0);\n },\n test_append(assert) {\n const index = new FragmentIdComparer([]);\n // add livefragment when opening timeline,\n // note that there is no nextId as the sync\n // hasn't come in yet\n index.add({id: 1});\n // now sync comes in and replaces the live fragment\n index.append(2, 1);\n assert(index.compare(1, 2) < 0);\n },\n test_prepend(assert) {\n const index = new FragmentIdComparer([]);\n index.add({id: 2});\n index.prepend(1, 2);\n assert(index.compare(1, 2) < 0);\n }\n }\n}\n","const scriptRel = (function detectScriptRel() {\n // @ts-ignore\n const relList = document.createElement('link').relList;\n // @ts-ignore\n return relList && relList.supports && relList.supports('modulepreload')\n ? 'modulepreload'\n : 'preload';\n})();const seen = {};const base = './';export const __vitePreload = function preload(baseModule, deps) {\n // @ts-ignore\n if (!__VITE_IS_MODERN__ || !deps || deps.length === 0) {\n return baseModule();\n }\n return Promise.all(deps.map((dep) => {\n // @ts-ignore\n dep = `${base}${dep}`;\n // @ts-ignore\n if (dep in seen)\n return;\n // @ts-ignore\n seen[dep] = true;\n const isCss = dep.endsWith('.css');\n const cssSelector = isCss ? '[rel=\"stylesheet\"]' : '';\n // @ts-ignore check if the file is already preloaded by SSR markup\n if (document.querySelector(`link[href=\"${dep}\"]${cssSelector}`)) {\n return;\n }\n // @ts-ignore\n const link = document.createElement('link');\n // @ts-ignore\n link.rel = isCss ? 'stylesheet' : scriptRel;\n if (!isCss) {\n link.as = 'script';\n link.crossOrigin = '';\n }\n link.href = dep;\n // @ts-ignore\n document.head.appendChild(link);\n if (isCss) {\n return new Promise((res, rej) => {\n link.addEventListener('load', res);\n link.addEventListener('error', () => rej(new Error(`Unable to preload CSS for ${dep}`)));\n });\n }\n })).then(() => baseModule());\n}","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { StorageError } from \"../common\";\n\nfunction _sourceName(source: IDBIndex | IDBObjectStore): string {\n return \"objectStore\" in source ?\n `${source.objectStore.name}.${source.name}` :\n source.name;\n}\n\nfunction _sourceDatabase(source: IDBIndex | IDBObjectStore): string {\n return \"objectStore\" in source ?\n source.objectStore?.transaction?.db?.name :\n source.transaction?.db?.name;\n}\n\nexport class IDBError extends StorageError {\n storeName: string;\n databaseName: string;\n\n constructor(message: string, sourceOrCursor: IDBIndex | IDBCursor | IDBObjectStore | null, cause: DOMException | null = null) {\n const source = (sourceOrCursor && \"source\" in sourceOrCursor) ? sourceOrCursor.source : sourceOrCursor;\n const storeName = source ? _sourceName(source) : \"\";\n const databaseName = source ? _sourceDatabase(source) : \"\";\n let fullMessage = `${message} on ${databaseName}.${storeName}`;\n if (cause) {\n fullMessage += \": \";\n if (typeof cause.name === \"string\") {\n fullMessage += `(name: ${cause.name}) `;\n }\n if (typeof cause.code === \"number\") {\n fullMessage += `(code: ${cause.code}) `;\n }\n }\n if (cause) {\n fullMessage += cause.message;\n }\n super(fullMessage, cause);\n this.storeName = storeName;\n this.databaseName = databaseName;\n }\n}\n\nexport class IDBRequestError extends IDBError {\n private errorEvent: Event;\n\n constructor(errorEvent: Event) {\n const request = errorEvent.target as IDBRequest;\n const source = request.source;\n const cause = request.error;\n super(\"IDBRequest failed\", source, cause);\n this.errorEvent = errorEvent;\n }\n\n preventTransactionAbort() {\n this.errorEvent.preventDefault();\n }\n}\n\nexport class IDBRequestAttemptError extends IDBError {\n constructor(method: string, source: IDBIndex | IDBObjectStore, cause: DOMException, params: any[]) {\n super(`${method}(${params.map(p => JSON.stringify(p)).join(\", \")}) failed`, source, cause);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { IDBRequestError } from \"./error\";\nimport { StorageError } from \"../common\";\nimport { AbortError } from \"../../../utils/error\";\n\nlet needsSyncPromise = false;\n\nexport const DONE = { done: true }\nexport const NOT_DONE = { done: false }\n\n/* should be called on legacy platforms to see\n if transactions close before draining the microtask queue (IE11 on Windows 7).\n If this is the case, promises need to be resolved\n synchronously from the idb request handler to prevent the transaction from closing prematurely.\n*/\nexport async function checkNeedsSyncPromise(): Promise {\n // important to have it turned off while doing the test,\n // otherwise reqAsPromise would not fail\n needsSyncPromise = false;\n const NAME = \"test-idb-needs-sync-promise\";\n const db = await openDatabase(NAME, db => {\n db.createObjectStore(\"test\", {keyPath: \"key\"});\n }, 1);\n const txn = db.transaction(\"test\", \"readonly\");\n try {\n await reqAsPromise(txn.objectStore(\"test\").get(1));\n await reqAsPromise(txn.objectStore(\"test\").get(2));\n } catch (err) {\n // err.name would be either TransactionInactiveError or InvalidStateError,\n // but let's not exclude any other failure modes\n needsSyncPromise = true;\n }\n // we could delete the store here, \n // but let's not create it on every page load on legacy platforms,\n // and just keep it around\n return needsSyncPromise;\n}\n\n// storage keys are defined to be unsigned 32bit numbers in KeyLimits, which is assumed by idb\nexport function encodeUint32(n: number): string {\n const hex = n.toString(16);\n return \"0\".repeat(8 - hex.length) + hex;\n}\n\n// used for logs where timestamp is part of key, which is larger than 32 bit\nexport function encodeUint64(n: number): string {\n const hex = n.toString(16);\n return \"0\".repeat(16 - hex.length) + hex;\n}\n\nexport function decodeUint32(str: string): number {\n return parseInt(str, 16);\n}\n\nexport type CreateObjectStore = (db : IDBDatabase, txn: IDBTransaction | null, oldVersion: number, version: number) => any\n\nexport function openDatabase(name: string, createObjectStore: CreateObjectStore, version: number, idbFactory: IDBFactory = window.indexedDB): Promise {\n const req = idbFactory.open(name, version);\n req.onupgradeneeded = async (ev : IDBVersionChangeEvent) => {\n const req = ev.target as IDBRequest;\n const db = req.result;\n const txn = req.transaction!;\n const oldVersion = ev.oldVersion;\n try {\n await createObjectStore(db, txn, oldVersion, version);\n } catch (err) {\n // try aborting on error, if that hasn't been done already\n try {\n txn.abort();\n } catch (err) {\n // No-op: `InvalidStateError` is only thrown if the transaction has\n // already been committed or aborted. Since we wanted the txn to\n // be aborted anyway, it doesn't matter if this fails.\n }\n }\n }; \n return reqAsPromise(req);\n}\n\nexport function reqAsPromise(req: IDBRequest): Promise {\n return new Promise((resolve, reject) => {\n req.addEventListener(\"success\", event => {\n resolve((event.target as IDBRequest).result);\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n });\n req.addEventListener(\"error\", event => {\n const error = new IDBRequestError(event);\n reject(error);\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n });\n });\n}\n\nexport function txnAsPromise(txn): Promise {\n let error;\n return new Promise((resolve, reject) => {\n txn.addEventListener(\"complete\", () => {\n resolve();\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n });\n txn.addEventListener(\"abort\", event => {\n reject(new AbortError());\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n });\n });\n}\n\n/**\n * This type is rather complicated, but I hope that this is for a good reason. There\n * are currently two uses for `iterateCursor`: iterating a regular cursor, and iterating\n * a key-only cursor, which does not have values. These two uses are distinct, and iteration\n * never stops or starts having a value halfway through.\n *\n * Each of the argument functions currently either assumes the value will be there, or that it won't. We thus can't\n * just accept a function argument `(T | undefined) => { done: boolean }`, since this messes with\n * the type safety in both cases: the former case will have to check for `undefined`, and\n * the latter would have an argument that can be `T`, even though it never will.\n *\n * So the approach here is to let TypeScript infer and accept (via generics) the type of\n * the cursor, which is either `IDBCursorWithValue` or `IDBCursor`. Since the type is accepted\n * via generics, we can actually vary the types of the actual function arguments depending on it.\n * Thus, when a value is available (an `IDBCursorWithValue` is given), we require a function `(T) => ...`, and when it is not, we require\n * a function `(undefined) => ...`.\n */\ntype CursorIterator = (value: I extends IDBCursorWithValue ? T : undefined, key: IDBValidKey, cursor: I) => { done: boolean, jumpTo?: IDBValidKey }\n\nexport function iterateCursor(cursorRequest: IDBRequest, processValue: CursorIterator): Promise {\n // TODO: does cursor already have a value here??\n return new Promise((resolve, reject) => {\n cursorRequest.onerror = event => {\n reject(new IDBRequestError(event));\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n };\n // collect results\n cursorRequest.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest).result;\n if (!cursor) {\n resolve(false);\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n return; // end of results\n }\n const result = processValue(cursor[\"value\"], cursor.key, cursor);\n // TODO: don't use object for result and assume it's jumpTo when not === true/false or undefined\n const done = result?.done;\n const jumpTo = result?.jumpTo;\n\n if (done) {\n resolve(true);\n // @ts-ignore\n needsSyncPromise && Promise._flush && Promise._flush();\n } else if(jumpTo) {\n cursor.continue(jumpTo);\n } else {\n cursor.continue();\n }\n };\n }).catch(err => {\n throw new StorageError(\"iterateCursor failed\", err);\n });\n}\n\ntype Pred = (value: T) => boolean\n\nexport async function fetchResults(cursor: IDBRequest, isDone: Pred): Promise {\n const results: T[] = [];\n await iterateCursor(cursor, (value) => {\n results.push(value);\n return {done: isDone(results)};\n });\n return results;\n}\n\ntype ToCursor = (store: IDBObjectStore) => IDBRequest\n\nexport async function select(db: IDBDatabase, storeName: string, toCursor: ToCursor, isDone: Pred): Promise {\n if (!isDone) {\n isDone = () => false;\n }\n if (!toCursor) {\n toCursor = store => store.openCursor();\n }\n const tx = db.transaction([storeName], \"readonly\");\n const store = tx.objectStore(storeName);\n const cursor = toCursor(store);\n return await fetchResults(cursor, isDone);\n}\n\nexport async function findStoreValue(db: IDBDatabase, storeName: string, toCursor: ToCursor, matchesValue: Pred): Promise {\n if (!matchesValue) {\n matchesValue = () => true;\n }\n if (!toCursor) {\n toCursor = store => store.openCursor();\n }\n\n const tx = db.transaction([storeName], \"readwrite\");\n const store = tx.objectStore(storeName);\n const cursor = await reqAsPromise(toCursor(store));\n let match;\n const matched = await iterateCursor(cursor, (value) => {\n if (matchesValue(value)) {\n match = value;\n return DONE;\n }\n return NOT_DONE;\n });\n if (!matched) {\n throw new StorageError(\"Value not found\");\n }\n return match;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {iterateCursor, DONE, NOT_DONE, reqAsPromise} from \"./utils\";\nimport {StorageError} from \"../common\";\nimport {ILogItem} from \"../../../logging/types\";\nimport {IDBKey} from \"./Transaction\";\n\n// this is the part of the Transaction class API that is used here and in the Store subclass,\n// to make it easier to replace it with alternative implementations in schema.ts and unit tests\nexport interface ITransaction {\n idbFactory: IDBFactory;\n IDBKeyRange: typeof IDBKeyRange;\n databaseName: string;\n addWriteError(error: StorageError, refItem: ILogItem | undefined, operationName: string, keys: IDBKey[] | undefined);\n}\n\ntype Reducer = (acc: B, val: A) => B\n\nexport type IDBQuery = IDBValidKey | IDBKeyRange | undefined | null\n\ninterface QueryTargetInterface {\n openCursor(range?: IDBQuery, direction?: IDBCursorDirection | undefined): IDBRequest;\n openKeyCursor(range?: IDBQuery, direction?: IDBCursorDirection | undefined): IDBRequest;\n supports(method: string): boolean;\n keyPath: string | string[];\n count(keyRange?: IDBKeyRange): IDBRequest;\n get(key: IDBValidKey | IDBKeyRange): IDBRequest;\n getKey(key: IDBValidKey | IDBKeyRange): IDBRequest;\n}\n\nexport class QueryTarget {\n protected _target: QueryTargetInterface;\n protected _transaction: ITransaction;\n\n constructor(target: QueryTargetInterface, transaction: ITransaction) {\n this._target = target;\n this._transaction = transaction;\n }\n\n get idbFactory(): IDBFactory {\n return this._transaction.idbFactory;\n }\n\n get IDBKeyRange(): typeof IDBKeyRange {\n return this._transaction.IDBKeyRange;\n }\n\n get databaseName(): string {\n return this._transaction.databaseName;\n }\n\n _openCursor(range?: IDBQuery, direction?: IDBCursorDirection): IDBRequest {\n if (range && direction) {\n return this._target.openCursor(range, direction);\n } else if (range) {\n return this._target.openCursor(range);\n } else if (direction) {\n return this._target.openCursor(null, direction);\n } else {\n return this._target.openCursor();\n }\n }\n\n supports(methodName: string): boolean {\n return this._target.supports(methodName);\n }\n\n count(keyRange?: IDBKeyRange): Promise {\n return reqAsPromise(this._target.count(keyRange));\n }\n\n get(key: IDBValidKey | IDBKeyRange): Promise {\n return reqAsPromise(this._target.get(key));\n }\n\n getKey(key: IDBValidKey | IDBKeyRange): Promise {\n if (this._target.supports(\"getKey\")) {\n return reqAsPromise(this._target.getKey(key));\n } else {\n return reqAsPromise(this._target.get(key)).then(value => {\n if (value) {\n let keyPath = this._target.keyPath;\n if (typeof keyPath === \"string\") {\n keyPath = [keyPath];\n }\n return keyPath.reduce((obj, key) => obj[key], value);\n }\n });\n }\n }\n\n reduce(range: IDBQuery, reducer: Reducer, initialValue: B): Promise {\n return this._reduce(range, reducer, initialValue, \"next\");\n }\n\n reduceReverse(range: IDBQuery, reducer: Reducer, initialValue: B): Promise {\n return this._reduce(range, reducer, initialValue, \"prev\");\n }\n \n selectLimit(range: IDBQuery, amount: number): Promise {\n return this._selectLimit(range, amount, \"next\");\n }\n\n selectLimitReverse(range: IDBQuery, amount: number): Promise {\n return this._selectLimit(range, amount, \"prev\");\n }\n\n selectWhile(range: IDBQuery, predicate: (v: T) => boolean): Promise {\n return this._selectWhile(range, predicate, \"next\");\n }\n\n selectWhileReverse(range: IDBQuery, predicate: (v: T) => boolean): Promise {\n return this._selectWhile(range, predicate, \"prev\");\n }\n\n async selectAll(range?: IDBQuery, direction?: IDBCursorDirection): Promise {\n const cursor = this._openCursor(range, direction);\n const results: T[] = [];\n await iterateCursor(cursor, (value) => {\n results.push(value);\n return NOT_DONE;\n });\n return results;\n }\n\n selectFirst(range: IDBQuery): Promise {\n return this._find(range, () => true, \"next\");\n }\n\n selectLast(range: IDBQuery): Promise {\n return this._find(range, () => true, \"prev\");\n }\n\n find(range: IDBQuery, predicate: (v: T) => boolean): Promise {\n return this._find(range, predicate, \"next\");\n }\n\n findReverse(range: IDBQuery, predicate: (v : T) => boolean): Promise {\n return this._find(range, predicate, \"prev\");\n }\n\n async findMaxKey(range: IDBQuery): Promise {\n const cursor = this._target.openKeyCursor(range, \"prev\");\n let maxKey;\n await iterateCursor(cursor, (_, key) => {\n maxKey = key;\n return DONE;\n });\n return maxKey;\n }\n\n\n async iterateValues(range: IDBQuery, callback: (val: T, key: IDBValidKey, cur: IDBCursorWithValue) => boolean): Promise {\n const cursor = this._target.openCursor(range, \"next\");\n await iterateCursor(cursor, (value, key, cur) => {\n return {done: callback(value, key, cur)};\n });\n }\n\n async iterateKeys(range: IDBQuery, callback: (key: IDBValidKey, cur: IDBCursor) => boolean): Promise {\n const cursor = this._target.openKeyCursor(range, \"next\");\n await iterateCursor(cursor, (_, key, cur) => {\n return {done: callback(key, cur)};\n });\n }\n\n /**\n * Checks if a given set of keys exist.\n * If the callback returns true, the search is halted and callback won't be called again.\n */\n async findExistingKeys(keys: IDBValidKey[], backwards: boolean, callback: (key: IDBValidKey, pk: IDBValidKey) => boolean): Promise {\n const compareKeys = (a, b) => backwards ? -this.idbFactory.cmp(a, b) : this.idbFactory.cmp(a, b);\n const sortedKeys = keys.slice().sort(compareKeys);\n const firstKey = sortedKeys[0];\n const lastKey = sortedKeys[sortedKeys.length - 1];\n const direction = backwards ? \"prev\" : \"next\";\n const cursor = this._target.openKeyCursor(this.IDBKeyRange.bound(firstKey, lastKey), direction);\n let index = 0;\n await iterateCursor(cursor, (value, key, cursor) => {\n while (index < sortedKeys.length && compareKeys(sortedKeys[index], key) < 0) {\n index += 1;\n }\n let done = false;\n if (sortedKeys[index] === key) {\n const pk = cursor.primaryKey;\n done = callback(key, pk);\n index += 1;\n }\n if (done || index >= sortedKeys.length) {\n return DONE;\n } else {\n return {\n done: false,\n jumpTo: sortedKeys[index],\n }\n }\n });\n }\n\n _reduce(range: IDBQuery, reducer: (reduced: B, value: T) => B, initialValue: B, direction: IDBCursorDirection): Promise {\n let reducedValue = initialValue;\n const cursor = this._openCursor(range, direction);\n return iterateCursor(cursor, (value) => {\n reducedValue = reducer(reducedValue, value);\n return NOT_DONE;\n });\n }\n\n _selectLimit(range: IDBQuery, amount: number, direction: IDBCursorDirection): Promise {\n return this._selectUntil(range, (results) => {\n return results.length === amount;\n }, direction);\n }\n\n async _selectUntil(range: IDBQuery, predicate: (vs: T[], v: T) => boolean, direction: IDBCursorDirection): Promise {\n const cursor = this._openCursor(range, direction);\n const results: T[] = [];\n await iterateCursor(cursor, (value) => {\n results.push(value);\n return {done: predicate(results, value)};\n });\n return results;\n }\n\n // allows you to fetch one too much that won't get added when the predicate fails\n async _selectWhile(range: IDBQuery, predicate: (v: T) => boolean, direction: IDBCursorDirection): Promise {\n const cursor = this._openCursor(range, direction);\n const results: T[] = [];\n await iterateCursor(cursor, (value) => {\n const passesPredicate = predicate(value);\n if (passesPredicate) {\n results.push(value);\n }\n return {done: !passesPredicate};\n });\n return results;\n }\n\n async iterateWhile(range: IDBQuery, predicate: (v: T) => boolean): Promise {\n const cursor = this._openCursor(range, \"next\");\n await iterateCursor(cursor, (value) => {\n const passesPredicate = predicate(value);\n return {done: !passesPredicate};\n });\n }\n\n async _find(range: IDBQuery, predicate: (v: T) => boolean, direction: IDBCursorDirection): Promise {\n const cursor = this._openCursor(range, direction);\n let result;\n const found = await iterateCursor(cursor, (value) => {\n const found = predicate(value);\n if (found) {\n result = value;\n }\n return {done: found};\n });\n if (found) {\n return result;\n }\n }\n}\n\nimport {createMockDatabase, createMockIDBFactory, getMockIDBKeyRange} from \"../../../mocks/Storage\";\nimport {txnAsPromise} from \"./utils\";\nimport {QueryTargetWrapper, Store} from \"./Store\";\n\nexport async function tests() {\n\n class MockTransaction {\n constructor(public readonly idbFactory: IDBFactory, readonly idbKeyRangeType: typeof IDBKeyRange) {}\n\n get IDBKeyRange(): typeof IDBKeyRange {\n return this.idbKeyRangeType;\n }\n get databaseName(): string { return \"mockdb\"; }\n addWriteError(error: StorageError, refItem: ILogItem | undefined, operationName: string, keys: IDBKey[] | undefined) {}\n }\n\n interface TestEntry {\n key: string\n }\n\n async function createTestStore(): Promise> {\n const idbFactory = await createMockIDBFactory();\n const idbKeyRangeType = await getMockIDBKeyRange();\n const mockImpl = new MockTransaction(idbFactory, idbKeyRangeType);\n const db = await createMockDatabase(\"findExistingKeys\", (db: IDBDatabase) => {\n db.createObjectStore(\"test\", {keyPath: \"key\"});\n }, idbFactory);\n const txn = db.transaction([\"test\"], \"readwrite\");\n return new Store(txn.objectStore(\"test\"), mockImpl);\n }\n\n return {\n \"findExistingKeys should not match on empty store\": async assert => {\n const store = await createTestStore();\n await store.findExistingKeys([\"2db1a709-d8f1-4c40-a835-f312badd277a\", \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"], false, () => {\n assert.fail(\"no key should match\");\n return false;\n });\n },\n \"findExistingKeys should not match any existing keys (in between sorting order)\": async assert => {\n const store = await createTestStore();\n store.add({key: \"43cd16eb-a6b4-4b9d-ab36-ab87d1b038c3\"});\n store.add({key: \"b655e7c5-e02d-4823-a7af-4202b12de659\"});\n await store.findExistingKeys([\"2db1a709-d8f1-4c40-a835-f312badd277a\", \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"], false, () => {\n assert.fail(\"no key should match\");\n return false;\n });\n },\n \"findExistingKeys should match only existing keys\": async assert => {\n const store = await createTestStore();\n store.add({key: \"2db1a709-d8f1-4c40-a835-f312badd277a\"});\n store.add({key: \"43cd16eb-a6b4-4b9d-ab36-ab87d1b038c3\"});\n store.add({key: \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"});\n const found: string[] = [];\n await store.findExistingKeys([\n \"2db1a709-d8f1-4c40-a835-f312badd277a\",\n \"eac3ef5c-a48f-4e19-b41d-ebd1d84c53f2\",\n \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"\n ], false, (key: IDBValidKey) => {\n found.push(key as string);\n return false;\n });\n assert.equal(found.length, 2);\n assert.equal(found[0], \"2db1a709-d8f1-4c40-a835-f312badd277a\");\n assert.equal(found[1], \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\");\n },\n \"findExistingKeys should match all if all exist\": async assert => {\n const store = await createTestStore();\n store.add({key: \"2db1a709-d8f1-4c40-a835-f312badd277a\"});\n store.add({key: \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"});\n store.add({key: \"b655e7c5-e02d-4823-a7af-4202b12de659\"});\n const found: string[] = [];\n await store.findExistingKeys([\n \"2db1a709-d8f1-4c40-a835-f312badd277a\",\n \"b655e7c5-e02d-4823-a7af-4202b12de659\",\n \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"\n ], false, (key: IDBValidKey) => {\n found.push(key as string);\n return false;\n });\n assert.equal(found.length, 3);\n assert.equal(found[0], \"2db1a709-d8f1-4c40-a835-f312badd277a\");\n assert.equal(found[1], \"b655e7c5-e02d-4823-a7af-4202b12de659\");\n assert.equal(found[2], \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\");\n },\n \"findExistingKeys should stop matching when callback returns true\": async assert => {\n const store = await createTestStore();\n store.add({key: \"2db1a709-d8f1-4c40-a835-f312badd277a\"});\n store.add({key: \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"});\n store.add({key: \"b655e7c5-e02d-4823-a7af-4202b12de659\"});\n const found: string[] = [];\n await store.findExistingKeys([\n \"2db1a709-d8f1-4c40-a835-f312badd277a\",\n \"b655e7c5-e02d-4823-a7af-4202b12de659\",\n \"fe7aa5c2-d4ed-4278-b3b0-f49d48d11df2\"\n ], false, (key: IDBValidKey) => {\n found.push(key as string);\n return true;\n });\n assert.equal(found.length, 1);\n assert.equal(found[0], \"2db1a709-d8f1-4c40-a835-f312badd277a\");\n },\n \n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {QueryTarget, IDBQuery, ITransaction} from \"./QueryTarget\";\nimport {IDBRequestError, IDBRequestAttemptError} from \"./error\";\nimport {reqAsPromise} from \"./utils\";\nimport {Transaction, IDBKey} from \"./Transaction\";\nimport {ILogItem} from \"../../../logging/types\";\n\nconst LOG_REQUESTS = false;\n\nfunction logRequest(method: string, params: any[], source: any): void {\n const storeName = source?.name;\n const databaseName = source?.transaction?.db?.name;\n console.info(`${databaseName}.${storeName}.${method}(${params.map(p => JSON.stringify(p)).join(\", \")})`);\n}\n\nexport class QueryTargetWrapper {\n private _qt: IDBIndex | IDBObjectStore;\n\n constructor(qt: IDBIndex | IDBObjectStore) {\n this._qt = qt;\n }\n\n get keyPath(): string | string[] {\n return this._qtStore.keyPath;\n }\n\n get _qtStore(): IDBObjectStore {\n if (\"objectStore\" in this._qt) {\n return this._qt.objectStore;\n }\n return this._qt;\n }\n\n supports(methodName: string): boolean {\n return !!this._qt[methodName];\n }\n \n openKeyCursor(range?: IDBQuery, direction?: IDBCursorDirection | undefined): IDBRequest {\n try {\n // not supported on Edge 15\n if (!this._qt.openKeyCursor) {\n LOG_REQUESTS && logRequest(\"openCursor\", [range, direction], this._qt);\n return this.openCursor(range, direction);\n }\n LOG_REQUESTS && logRequest(\"openKeyCursor\", [range, direction], this._qt);\n return this._qt.openKeyCursor(range, direction)\n } catch(err) {\n throw new IDBRequestAttemptError(\"openKeyCursor\", this._qt, err, [range, direction]);\n }\n }\n \n openCursor(range?: IDBQuery, direction?: IDBCursorDirection | undefined): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"openCursor\", [], this._qt);\n return this._qt.openCursor(range, direction)\n } catch(err) {\n throw new IDBRequestAttemptError(\"openCursor\", this._qt, err, [range, direction]);\n }\n }\n\n put(item: T, key?: IDBValidKey | undefined): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"put\", [item, key], this._qt);\n return this._qtStore.put(item, key);\n } catch(err) {\n throw new IDBRequestAttemptError(\"put\", this._qt, err, [item, key]);\n }\n }\n\n add(item: T, key?: IDBValidKey | undefined): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"add\", [item, key], this._qt);\n return this._qtStore.add(item, key);\n } catch(err) {\n throw new IDBRequestAttemptError(\"add\", this._qt, err, [item, key]);\n }\n }\n\n get(key: IDBValidKey | IDBKeyRange): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"get\", [key], this._qt);\n return this._qt.get(key);\n } catch(err) {\n throw new IDBRequestAttemptError(\"get\", this._qt, err, [key]);\n }\n }\n \n getKey(key: IDBValidKey | IDBKeyRange): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"getKey\", [key], this._qt);\n return this._qt.getKey(key)\n } catch(err) {\n throw new IDBRequestAttemptError(\"getKey\", this._qt, err, [key]);\n }\n }\n\n delete(key: IDBValidKey | IDBKeyRange): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"delete\", [key], this._qt);\n return this._qtStore.delete(key);\n } catch(err) {\n throw new IDBRequestAttemptError(\"delete\", this._qt, err, [key]);\n }\n }\n\n clear(): IDBRequest {\n try {\n LOG_REQUESTS && logRequest(\"clear\", [], this._qt);\n return this._qtStore.clear();\n }\n catch (err) {\n throw new IDBRequestAttemptError(\"delete\", this._qt, err, []);\n }\n }\n\n count(keyRange?: IDBKeyRange): IDBRequest {\n try {\n return this._qt.count(keyRange);\n } catch(err) {\n throw new IDBRequestAttemptError(\"count\", this._qt, err, [keyRange]);\n }\n }\n\n index(name: string): IDBIndex {\n try {\n return this._qtStore.index(name);\n } catch(err) {\n // TODO: map to different error? this is not a request\n throw new IDBRequestAttemptError(\"index\", this._qt, err, [name]);\n }\n }\n\n get indexNames(): string[] {\n return Array.from(this._qtStore.indexNames);\n }\n}\n\nexport class Store extends QueryTarget {\n constructor(idbStore: IDBObjectStore, transaction: ITransaction) {\n super(new QueryTargetWrapper(idbStore), transaction);\n }\n\n get _idbStore(): QueryTargetWrapper {\n return (this._target as QueryTargetWrapper);\n }\n\n index(indexName: string): QueryTarget {\n return new QueryTarget(new QueryTargetWrapper(this._idbStore.index(indexName)), this._transaction);\n }\n\n put(value: T, log?: ILogItem): void {\n // If this request fails, the error will bubble up to the transaction and abort it,\n // which is the behaviour we want. Therefore, it is ok to not create a promise for this\n // request and await it.\n // \n // Perhaps at some later point, we will want to handle an error (like ConstraintError) for\n // individual write requests. In that case, we should add a method that returns a promise (e.g. putAndObserve)\n // and call preventDefault on the event to prevent it from aborting the transaction\n // \n // Note that this can still throw synchronously, like it does for TransactionInactiveError,\n // see https://www.w3.org/TR/IndexedDB-2/#transaction-lifetime-concept\n const request = this._idbStore.put(value);\n this._prepareErrorLog(request, log, \"put\", undefined, value);\n }\n\n add(value: T, log?: ILogItem): void {\n // ok to not monitor result of request, see comment in `put`.\n const request = this._idbStore.add(value);\n this._prepareErrorLog(request, log, \"add\", undefined, value);\n }\n\n async tryAdd(value: T, log: ILogItem): Promise {\n try {\n await reqAsPromise(this._idbStore.add(value));\n return true;\n } catch (err) {\n if (err instanceof IDBRequestError) {\n log.log({l: \"could not write\", id: this._getKeys(value), e: err}, log.level.Warn);\n err.preventTransactionAbort();\n return false;\n } else {\n throw err;\n }\n }\n }\n\n delete(keyOrKeyRange: IDBValidKey | IDBKeyRange, log?: ILogItem): void {\n // ok to not monitor result of request, see comment in `put`.\n const request = this._idbStore.delete(keyOrKeyRange);\n this._prepareErrorLog(request, log, \"delete\", keyOrKeyRange, undefined);\n }\n\n clear(log?: ILogItem): void {\n const request = this._idbStore.clear();\n this._prepareErrorLog(request, log, \"delete\", undefined, undefined);\n }\n\n private _prepareErrorLog(request: IDBRequest, log: ILogItem | undefined, operationName: string, key: IDBKey | undefined, value: T | undefined) {\n if (log) {\n log.ensureRefId();\n }\n reqAsPromise(request).catch(err => {\n let keys : IDBKey[] | undefined = undefined;\n if (value) {\n keys = this._getKeys(value);\n } else if (key) {\n keys = [key];\n }\n this._transaction.addWriteError(err, log, operationName, keys);\n });\n }\n\n private _getKeys(value: T): IDBValidKey[] {\n const keys: IDBValidKey[] = [];\n const {keyPath} = this._idbStore;\n try {\n keys.push(this._readKeyPath(value, keyPath));\n } catch (err) {\n console.warn(\"could not read keyPath\", keyPath);\n }\n for (const indexName of this._idbStore.indexNames) {\n try {\n const index = this._idbStore.index(indexName);\n keys.push(this._readKeyPath(value, index.keyPath));\n } catch (err) {\n console.warn(\"could not read index\", indexName);\n }\n }\n return keys;\n }\n\n private _readKeyPath(value: T, keyPath: string[] | string): IDBValidKey {\n if (Array.isArray(keyPath)) {\n let field: any = value;\n for (const part of keyPath) {\n if (typeof field === \"object\") {\n field = field[part];\n } else {\n break;\n }\n }\n return field as IDBValidKey;\n } else {\n return value[keyPath] as IDBValidKey;\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function stringify(value: any): string {\n return JSON.stringify(encodeValue(value));\n}\n\nexport function parse(value: string): any {\n return decodeValue(JSON.parse(value));\n}\n\nfunction encodeValue(value: any): any {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n // TypedArray\n if (value.byteLength) {\n return {_type: value.constructor.name, value: Array.from(value)};\n }\n let newObj = {};\n for (const prop in value) {\n if (value.hasOwnProperty(prop)) {\n newObj[prop] = encodeValue(value[prop]);\n }\n }\n return newObj;\n } else {\n return value;\n }\n}\n\nfunction decodeValue(value: any): any {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n if (typeof value._type === \"string\") {\n switch (value._type) {\n case \"Int8Array\": return Int8Array.from(value.value);\n case \"Uint8Array\": return Uint8Array.from(value.value);\n case \"Uint8ClampedArray\": return Uint8ClampedArray.from(value.value);\n case \"Int16Array\": return Int16Array.from(value.value);\n case \"Uint16Array\": return Uint16Array.from(value.value);\n case \"Int32Array\": return Int32Array.from(value.value);\n case \"Uint32Array\": return Uint32Array.from(value.value);\n case \"Float32Array\": return Float32Array.from(value.value);\n case \"Float64Array\": return Float64Array.from(value.value);\n case \"BigInt64Array\": return BigInt64Array.from(value.value);\n case \"BigUint64Array\": return BigUint64Array.from(value.value);\n default:\n return value.value;\n }\n }\n let newObj = {};\n for (const prop in value) {\n if (value.hasOwnProperty(prop)) {\n newObj[prop] = decodeValue(value[prop]);\n }\n }\n return newObj;\n } else {\n return value;\n }\n}\n\nexport function tests() {\n return {\n \"Uint8Array and primitives\": assert => {\n const value = {\n foo: \"bar\",\n bar: 5,\n baz: false,\n fuzz: new Uint8Array([3, 1, 2])\n };\n const serialized = stringify(value);\n assert.strictEqual(typeof serialized, \"string\");\n const deserialized = parse(serialized);\n assert.strictEqual(deserialized.foo, \"bar\");\n assert.strictEqual(deserialized.bar, 5);\n assert.strictEqual(deserialized.baz, false);\n assert(deserialized.fuzz instanceof Uint8Array);\n assert.strictEqual(deserialized.fuzz.length, 3);\n assert.strictEqual(deserialized.fuzz[0], 3);\n assert.strictEqual(deserialized.fuzz[1], 1);\n assert.strictEqual(deserialized.fuzz[2], 2);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\nimport {IDOMStorage} from \"../types\";\nimport {SESSION_E2EE_KEY_PREFIX} from \"../../../e2ee/common\";\nimport {parse, stringify} from \"../../../../utils/typedJSON\";\nimport type {ILogItem} from \"../../../../logging/types\";\n\nexport interface SessionEntry {\n key: string;\n value: any;\n}\n\nfunction getLocalStorageKeyPrefix(databaseName: string): string {\n return `${databaseName}.session.`;\n}\n\nexport function clearKeysFromLocalStorage(localStorage: IDOMStorage, databaseName: string): void {\n const keys: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(getLocalStorageKeyPrefix(databaseName))) {\n keys.push(key);\n }\n }\n for (const key of keys) {\n localStorage.removeItem(key);\n }\n}\n\nexport class SessionStore {\n private _sessionStore: Store\n private _localStorage: IDOMStorage;\n\n constructor(sessionStore: Store, localStorage: IDOMStorage) {\n this._sessionStore = sessionStore;\n this._localStorage = localStorage;\n }\n\n private get _localStorageKeyPrefix(): string {\n return getLocalStorageKeyPrefix(this._sessionStore.databaseName);\n }\n\n async get(key: string): Promise {\n const entry = await this._sessionStore.get(key);\n if (entry) {\n return entry.value;\n }\n }\n\n _writeKeyToLocalStorage(key: string, value: any) {\n // we backup to localStorage so when idb gets cleared for some reason, we don't lose our e2ee identity\n try {\n const lsKey = this._localStorageKeyPrefix + key;\n const lsValue = stringify(value);\n this._localStorage.setItem(lsKey, lsValue);\n } catch (err) {\n console.error(\"could not write to localStorage\", err);\n }\n }\n\n writeE2EEIdentityToLocalStorage() {\n this._sessionStore.iterateValues(undefined, (entry: SessionEntry, key: string) => {\n if (key.startsWith(SESSION_E2EE_KEY_PREFIX)) {\n this._writeKeyToLocalStorage(key, entry.value);\n }\n return false;\n });\n }\n\n async tryRestoreE2EEIdentityFromLocalStorage(log: ILogItem): Promise {\n let success = false;\n const lsPrefix = this._localStorageKeyPrefix;\n const prefix = lsPrefix + SESSION_E2EE_KEY_PREFIX;\n for(let i = 0; i < this._localStorage.length; i += 1) {\n const lsKey = this._localStorage.key(i)!;\n if (lsKey.startsWith(prefix)) {\n const value = parse(this._localStorage.getItem(lsKey)!);\n const key = lsKey.substr(lsPrefix.length);\n // we check if we don't have this key already, as we don't want to override anything\n const hasKey = (await this._sessionStore.getKey(key)) === key;\n log.set(key, !hasKey);\n if (!hasKey) {\n this._sessionStore.put({key, value});\n success = true;\n }\n }\n }\n return success;\n }\n\n set(key: string, value: any): void {\n if (key.startsWith(SESSION_E2EE_KEY_PREFIX)) {\n this._writeKeyToLocalStorage(key, value);\n }\n this._sessionStore.put({key, value});\n }\n\n add(key: string, value: any): void {\n if (key.startsWith(SESSION_E2EE_KEY_PREFIX)) {\n this._writeKeyToLocalStorage(key, value);\n }\n this._sessionStore.add({key, value});\n }\n\n remove(key: string): void {\n if (key.startsWith(SESSION_E2EE_KEY_PREFIX)) {\n this._localStorage.removeItem(this._localStorageKeyPrefix + key);\n }\n this._sessionStore.delete(key);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\nstore contains:\n\troomId\n\tname\n\tlastMessage\n\tunreadCount\n\tmentionCount\n\tisEncrypted\n\tisDirectMessage\n\tmembership\n\tinviteCount\n\tjoinCount\n*/\nimport {Store} from \"../Store\";\nimport {SummaryData} from \"../../../room/RoomSummary\";\n\n/** Used for both roomSummary and archivedRoomSummary stores */\nexport class RoomSummaryStore {\n private _summaryStore: Store;\n\n constructor(summaryStore: Store) {\n this._summaryStore = summaryStore;\n }\n\n getAll(): Promise {\n return this._summaryStore.selectAll();\n }\n\n set(summary: SummaryData): void {\n this._summaryStore.put(summary);\n }\n\n get(roomId: string): Promise {\n return this._summaryStore.get(roomId);\n }\n\n async has(roomId: string): Promise {\n const fetchedKey = await this._summaryStore.getKey(roomId);\n return roomId === fetchedKey;\n }\n\n remove(roomId: string): void {\n this._summaryStore.delete(roomId);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\nimport {MemberData} from \"./RoomMemberStore\";\n\n// TODO: Move to Invite when that's TypeScript.\nexport interface InviteData {\n roomId: string;\n isEncrypted: boolean;\n isDirectMessage: boolean;\n name?: string;\n avatarUrl?: string;\n avatarColorId: number;\n canonicalAlias?: string;\n timestamp: number;\n joinRule: string;\n inviter?: MemberData;\n}\n\nexport class InviteStore {\n private _inviteStore: Store;\n\n constructor(inviteStore: Store) {\n this._inviteStore = inviteStore;\n }\n\n getAll(): Promise {\n return this._inviteStore.selectAll();\n }\n\n set(invite: InviteData): void {\n this._inviteStore.put(invite);\n }\n\n remove(roomId: string): void {\n this._inviteStore.delete(roomId);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {ILogItem, ISerializedItem} from \"./types\";\n\nexport enum LogLevel {\n All = 1,\n Debug,\n Detail,\n Info,\n Warn,\n Error,\n Fatal,\n Off\n}\n\nexport class LogFilter {\n private _min?: LogLevel;\n private _parentFilter?: LogFilter;\n\n constructor(parentFilter?: LogFilter) {\n this._parentFilter = parentFilter;\n }\n\n filter(item: ILogItem, children: ISerializedItem[] | null): boolean {\n if (this._parentFilter) {\n if (!this._parentFilter.filter(item, children)) {\n return false;\n }\n }\n // neither our children or us have a loglevel high enough, filter out.\n if (this._min !== undefined && !Array.isArray(children) && item.logLevel < this._min) {\n return false;\n } else {\n return true;\n }\n }\n\n /* methods to build the filter */\n minLevel(logLevel: LogLevel): LogFilter {\n this._min = logLevel;\n return this;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {LogLevel} from \"./LogFilter\";\nimport type {ILogger, ILogItem, ILogReporter, LabelOrValues, LogCallback, LogItemValues} from \"./types\";\n\nfunction noop (): void {}\n\nexport class NullLogger implements ILogger {\n public readonly item: ILogItem = new NullLogItem(this);\n\n log(labelOrValues: LabelOrValues): ILogItem {\n return this.item;\n }\n\n addReporter() {}\n\n get reporters(): ReadonlyArray {\n return [];\n }\n\n getOpenRootItems(): Iterable {\n return [];\n }\n\n forceFinish(): void {}\n\n child(labelOrValues: LabelOrValues): ILogItem {\n return this.item;\n }\n\n run(_, callback: LogCallback): T {\n return callback(this.item); \n }\n\n wrapOrRun(item: ILogItem | undefined, _, callback: LogCallback): T {\n if (item) {\n return item.wrap(_, callback);\n } else {\n return this.run(_, callback);\n }\n }\n\n runDetached(_, callback): ILogItem {\n new Promise(r => r(callback(this.item))).then(noop, noop);\n return this.item;\n }\n \n get level(): typeof LogLevel {\n return LogLevel;\n }\n}\n\nexport class NullLogItem implements ILogItem {\n public readonly logger: NullLogger;\n public readonly logLevel: LogLevel;\n public children?: Array;\n public values: LogItemValues;\n public error?: Error;\n\n constructor(logger: NullLogger) {\n this.logger = logger;\n }\n\n discard(): void {\n // noop\n }\n\n wrap(_: LabelOrValues, callback: LogCallback): T {\n return this.run(callback);\n }\n\n run(callback: LogCallback): T {\n return callback(this);\n }\n\n\n log(labelOrValues: LabelOrValues): ILogItem {\n return this;\n }\n \n set(labelOrValues: LabelOrValues): ILogItem { return this; }\n\n runDetached(_: LabelOrValues, callback: LogCallback): ILogItem {\n new Promise(r => r(callback(this))).then(noop, noop);\n return this;\n }\n\n wrapDetached(_: LabelOrValues, _callback: LogCallback): void {\n return this.refDetached();\n }\n\n refDetached(): void {}\n\n ensureRefId(): void {}\n\n get level(): typeof LogLevel {\n return LogLevel;\n }\n\n get duration(): 0 {\n return 0;\n }\n\n catch(err: Error): Error {\n return err;\n }\n\n child(): ILogItem {\n return this;\n }\n\n finish(): void {}\n forceFinish(): void {}\n\n serialize(): undefined {\n return undefined;\n }\n}\n\nexport const Instance = new NullLogger(); \n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventKey} from \"../../../room/timeline/EventKey\";\nimport { StorageError } from \"../../common\";\nimport { encodeUint32, decodeUint32 } from \"../utils\";\nimport {KeyLimits} from \"../../common\";\nimport {Store} from \"../Store\";\nimport {TimelineEvent, StateEvent} from \"../../types\";\nimport {ILogItem} from \"../../../../logging/types\";\n\ninterface Annotation {\n count: number;\n me: boolean;\n firstTimestamp: number;\n}\n\ninterface TimelineEventEntry {\n roomId: string;\n fragmentId: number;\n eventIndex: number;\n event: TimelineEvent | StateEvent;\n displayName?: string;\n avatarUrl?: string;\n annotations?: { [key : string]: Annotation };\n}\n\ntype TimelineEventStorageEntry = TimelineEventEntry & { key: string, eventIdKey: string };\n\nfunction encodeKey(roomId: string, fragmentId: number, eventIndex: number): string {\n return `${roomId}|${encodeUint32(fragmentId)}|${encodeUint32(eventIndex)}`;\n}\n\nfunction decodeKey(key: string): { roomId: string, eventKey: EventKey } {\n const [roomId, fragmentId, eventIndex] = key.split(\"|\");\n return {roomId, eventKey: new EventKey(decodeUint32(fragmentId), decodeUint32(eventIndex))};\n}\n\nfunction encodeEventIdKey(roomId: string, eventId: string): string {\n return `${roomId}|${eventId}`;\n}\n\nfunction decodeEventIdKey(eventIdKey: string): { roomId: string, eventId: string } {\n const [roomId, eventId] = eventIdKey.split(\"|\");\n return {roomId, eventId};\n}\n\nclass Range {\n private _IDBKeyRange: typeof IDBKeyRange;\n private _only?: EventKey;\n private _lower?: EventKey;\n private _upper?: EventKey;\n private _lowerOpen: boolean;\n private _upperOpen: boolean;\n\n constructor(_IDBKeyRange: any, only?: EventKey, lower?: EventKey, upper?: EventKey, lowerOpen: boolean = false, upperOpen: boolean = false) {\n this._IDBKeyRange = _IDBKeyRange;\n this._only = only;\n this._lower = lower;\n this._upper = upper;\n this._lowerOpen = lowerOpen;\n this._upperOpen = upperOpen;\n }\n\n asIDBKeyRange(roomId: string): IDBKeyRange | undefined {\n try {\n // only\n if (this._only) {\n return this._IDBKeyRange.only(encodeKey(roomId, this._only.fragmentId, this._only.eventIndex));\n }\n // lowerBound\n // also bound as we don't want to move into another roomId\n if (this._lower && !this._upper) {\n return this._IDBKeyRange.bound(\n encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex),\n encodeKey(roomId, this._lower.fragmentId, KeyLimits.maxStorageKey),\n this._lowerOpen,\n false\n );\n }\n // upperBound\n // also bound as we don't want to move into another roomId\n if (!this._lower && this._upper) {\n return this._IDBKeyRange.bound(\n encodeKey(roomId, this._upper.fragmentId, KeyLimits.minStorageKey),\n encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex),\n false,\n this._upperOpen\n );\n }\n // bound\n if (this._lower && this._upper) {\n return this._IDBKeyRange.bound(\n encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex),\n encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex),\n this._lowerOpen,\n this._upperOpen\n );\n }\n } catch(err) {\n throw new StorageError(`IDBKeyRange failed with data: ` + JSON.stringify(this), err);\n }\n }\n}\n/*\n * @typedef {Object} Gap\n * @property {?string} prev_batch the pagination token for this backwards facing gap\n * @property {?string} next_batch the pagination token for this forwards facing gap\n *\n * @typedef {Object} Event\n * @property {string} event_id the id of the event\n * @property {string} type the\n * @property {?string} state_key the state key of this state event\n *\n * @typedef {Object} Entry\n * @property {string} roomId\n * @property {EventKey} eventKey\n * @property {?Event} event if an event entry, the event\n * @property {?Gap} gap if a gap entry, the gap\n*/\nexport class TimelineEventStore {\n private _timelineStore: Store;\n\n constructor(timelineStore: Store) {\n this._timelineStore = timelineStore;\n }\n\n /** Creates a range that only includes the given key\n * @param eventKey the key\n * @return the created range\n */\n onlyRange(eventKey: EventKey): Range {\n return new Range(this._timelineStore.IDBKeyRange, eventKey);\n }\n\n /** Creates a range that includes all keys before eventKey, and optionally also the key itself.\n * @param eventKey the key\n * @param [open=false] whether the key is included (false) or excluded (true) from the range at the upper end.\n * @return the created range\n */\n upperBoundRange(eventKey: EventKey, open=false): Range {\n return new Range(this._timelineStore.IDBKeyRange, undefined, undefined, eventKey, undefined, open);\n }\n\n /** Creates a range that includes all keys after eventKey, and optionally also the key itself.\n * @param eventKey the key\n * @param [open=false] whether the key is included (false) or excluded (true) from the range at the lower end.\n * @return the created range\n */\n lowerBoundRange(eventKey: EventKey, open=false): Range {\n return new Range(this._timelineStore.IDBKeyRange, undefined, eventKey, undefined, open);\n }\n\n /** Creates a range that includes all keys between `lower` and `upper`, and optionally the given keys as well.\n * @param lower the lower key\n * @param upper the upper key\n * @param [lowerOpen=false] whether the lower key is included (false) or excluded (true) from the range.\n * @param [upperOpen=false] whether the upper key is included (false) or excluded (true) from the range.\n * @return the created range\n */\n boundRange(lower: EventKey, upper: EventKey, lowerOpen=false, upperOpen=false): Range {\n return new Range(this._timelineStore.IDBKeyRange, undefined, lower, upper, lowerOpen, upperOpen);\n }\n\n /** Looks up the last `amount` entries in the timeline for `roomId`.\n * @param roomId\n * @param fragmentId\n * @param amount\n * @return a promise resolving to an array with 0 or more entries, in ascending order.\n */\n async lastEvents(roomId: string, fragmentId: number, amount: number): Promise {\n const eventKey = EventKey.maxKey;\n eventKey.fragmentId = fragmentId;\n return this.eventsBefore(roomId, eventKey, amount);\n }\n\n /** Looks up the first `amount` entries in the timeline for `roomId`.\n * @param roomId\n * @param fragmentId\n * @param amount\n * @return a promise resolving to an array with 0 or more entries, in ascending order.\n */\n async firstEvents(roomId: string, fragmentId: number, amount: number): Promise {\n const eventKey = EventKey.minKey;\n eventKey.fragmentId = fragmentId;\n return this.eventsAfter(roomId, eventKey, amount);\n }\n\n /** Looks up `amount` entries after `eventKey` in the timeline for `roomId` within the same fragment.\n * The entry for `eventKey` is not included.\n * @param roomId\n * @param eventKey\n * @param amount\n * @return a promise resolving to an array with 0 or more entries, in ascending order.\n */\n eventsAfter(roomId: string, eventKey: EventKey, amount: number): Promise {\n const idbRange = this.lowerBoundRange(eventKey, true).asIDBKeyRange(roomId);\n return this._timelineStore.selectLimit(idbRange, amount);\n }\n\n /** Looks up `amount` entries before `eventKey` in the timeline for `roomId` within the same fragment.\n * The entry for `eventKey` is not included.\n * @param roomId\n * @param eventKey\n * @param amount\n * @return a promise resolving to an array with 0 or more entries, in ascending order.\n */\n async eventsBefore(roomId: string, eventKey: EventKey, amount: number): Promise {\n const range = this.upperBoundRange(eventKey, true).asIDBKeyRange(roomId);\n const events = await this._timelineStore.selectLimitReverse(range, amount);\n events.reverse(); // because we fetched them backwards\n return events;\n }\n\n async getEventKeysForIds(roomId: string, eventIds: string[]): Promise> {\n const byEventId = this._timelineStore.index(\"byEventId\");\n const keys = eventIds.map(eventId => encodeEventIdKey(roomId, eventId));\n const results = new Map();\n await byEventId.findExistingKeys(keys, false, (indexKey, pk) => {\n const {eventId} = decodeEventIdKey(indexKey as string);\n const {eventKey} = decodeKey(pk as string);\n results.set(eventId, eventKey);\n return false;\n });\n return results;\n }\n\n /** Finds the first eventId that occurs in the store, if any.\n * For optimal performance, `eventIds` should be in chronological order.\n *\n * The order in which results are returned might be different than `eventIds`.\n * Call the return value to obtain the next {id, event} pair.\n * @param roomId\n * @param eventIds\n * @return\n */\n // performance comment from above refers to the fact that there *might*\n // be a correlation between event_id sorting order and chronology.\n // In that case we could avoid running over all eventIds, as the reported order by findExistingKeys\n // would match the order of eventIds. That's why findLast is also passed as backwards to keysExist.\n // also passing them in chronological order makes sense as that's how we'll receive them almost always.\n async findFirstOccurringEventId(roomId: string, eventIds: string[]): Promise {\n const byEventId = this._timelineStore.index(\"byEventId\");\n const keys = eventIds.map(eventId => encodeEventIdKey(roomId, eventId));\n const results = new Array(keys.length);\n let firstFoundKey: string | undefined;\n\n // find first result that is found and has no undefined results before it\n function firstFoundAndPrecedingResolved(): string | undefined {\n for(let i = 0; i < results.length; ++i) {\n if (results[i] === undefined) {\n return;\n } else if(results[i] === true) {\n return keys[i];\n }\n }\n }\n\n await byEventId.findExistingKeys(keys, false, (key, found) => {\n // T[].search(T, number), but we want T[].search(R, number), so cast\n const index = (keys as IDBValidKey[]).indexOf(key);\n results[index] = found;\n firstFoundKey = firstFoundAndPrecedingResolved();\n return !!firstFoundKey;\n });\n return firstFoundKey && decodeEventIdKey(firstFoundKey).eventId;\n }\n\n /** Inserts a new entry into the store.\n * \n * If the event already exists in the store (either the eventKey or the event id\n * are already known for the given roomId), this operation has no effect.\n * \n * Returns if the event was not yet known and the entry was written.\n */\n tryInsert(entry: TimelineEventEntry, log: ILogItem): Promise {\n (entry as TimelineEventStorageEntry).key = encodeKey(entry.roomId, entry.fragmentId, entry.eventIndex);\n (entry as TimelineEventStorageEntry).eventIdKey = encodeEventIdKey(entry.roomId, entry.event.event_id);\n return this._timelineStore.tryAdd(entry as TimelineEventStorageEntry, log);\n }\n\n /** Updates the entry into the store with the given [roomId, eventKey] combination.\n * If not yet present, will insert. Might be slower than add.\n * @param entry the entry to update.\n * @return nothing. To wait for the operation to finish, await the transaction it's part of.\n */\n update(entry: TimelineEventEntry): void {\n this._timelineStore.put(entry as TimelineEventStorageEntry);\n }\n\n get(roomId: string, eventKey: EventKey): Promise {\n return this._timelineStore.get(encodeKey(roomId, eventKey.fragmentId, eventKey.eventIndex));\n }\n\n getByEventId(roomId: string, eventId: string): Promise {\n return this._timelineStore.index(\"byEventId\").get(encodeEventIdKey(roomId, eventId));\n }\n\n removeAllForRoom(roomId: string): void {\n const minKey = encodeKey(roomId, KeyLimits.minStorageKey, KeyLimits.minStorageKey);\n const maxKey = encodeKey(roomId, KeyLimits.maxStorageKey, KeyLimits.maxStorageKey);\n const range = this._timelineStore.IDBKeyRange.bound(minKey, maxKey);\n this._timelineStore.delete(range);\n }\n}\n\nimport {createMockStorage} from \"../../../../mocks/Storage\";\nimport {createEvent, withTextBody} from \"../../../../mocks/event.js\";\nimport {createEventEntry} from \"../../../room/timeline/persistence/common.js\";\nimport {Instance as nullLogger} from \"../../../../logging/NullLogger\";\n\nexport function tests() {\n\n const sortedIds = [\n \"$2wZy1W-QdcwaAwz68nfz1oc-3SsZKVDy8d86ERP1Pm0\",\n \"$4RWaZ5142grUgTnQyr_5qiPTOwzAOimt5MsXg6m1diM\",\n \"$4izqHE2Wf5US_-e_za942pZ10CDNJjDncUMmhqBUVQw\",\n \"$Oil2Afq2cBLqMAeJTAHjA3Is9T5Wmaa2ogVRlFJ_gzE\",\n \"$Wyl-7u-YqnPJElkPufIRXRFTYP-eFxQ4iD-SmLQo2Rw\",\n \"$b-eWaZtp22vL9mp0h7odbpphOZQ-rnp54qjyTQPARgo\",\n \"$sS9rTv8u2m9o4RaMI2jGOnpMtb9t8_0euiQLhNFW380\",\n \"$uZLkB9rzTKvJAK2QrQNX-prwQ2Niajdi0fvvRnyCtz8\",\n \"$vGecIBZFex9_vlQf1E1LjtQXE3q5GwERIHMiy4mOWv0\",\n \"$vdLgAnwjHj0cicU3MA4ynLHUBGOIFhvvksY3loqzjF\",\n ];\n\n const insertedIds = [\n sortedIds[5],\n sortedIds[3],\n sortedIds[9],\n sortedIds[7],\n sortedIds[1],\n ];\n\n const checkedIds = [\n sortedIds[2],\n sortedIds[4],\n sortedIds[3],\n sortedIds[0],\n sortedIds[8],\n sortedIds[9],\n sortedIds[6],\n ];\n\n const roomId = \"!fjsdf423423jksdfdsf:hs.tld\";\n\n function createEventWithId(id) {\n return withTextBody(\"hello\", createEvent(\"m.room.message\", id, \"@alice:hs.tld\"));\n }\n\n return {\n \"getEventKeysForIds\": async assert => {\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents]);\n let eventKey = EventKey.defaultFragmentKey(109);\n for (const insertedId of insertedIds) {\n const entry = createEventEntry(eventKey.nextKey(), roomId, createEventWithId(insertedId));\n assert(await txn.timelineEvents.tryInsert(entry, nullLogger.item));\n eventKey = eventKey.nextKey();\n }\n const eventKeyMap = await txn.timelineEvents.getEventKeysForIds(roomId, checkedIds);\n assert.equal(eventKeyMap.size, 2);\n const eventKey1 = eventKeyMap.get(\"$Oil2Afq2cBLqMAeJTAHjA3Is9T5Wmaa2ogVRlFJ_gzE\")!;\n assert.equal(eventKey1.fragmentId, 109);\n assert.equal(eventKey1.eventIndex, 0x80000001);\n const eventKey2 = eventKeyMap.get(\"$vdLgAnwjHj0cicU3MA4ynLHUBGOIFhvvksY3loqzjF\")!;\n assert.equal(eventKey2.fragmentId, 109);\n assert.equal(eventKey2.eventIndex, 0x80000002);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport const MIN_UNICODE = \"\\u{0}\";\nexport const MAX_UNICODE = \"\\u{10FFFF}\";\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {MIN_UNICODE, MAX_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\n\nfunction encodeKey(roomId: string, targetEventId: string, relType: string, sourceEventId: string): string {\n return `${roomId}|${targetEventId}|${relType}|${sourceEventId}`;\n}\n\ninterface RelationEntry {\n roomId: string;\n targetEventId: string;\n sourceEventId: string;\n relType: string;\n}\n\nfunction decodeKey(key: string): RelationEntry {\n const [roomId, targetEventId, relType, sourceEventId] = key.split(\"|\");\n return {roomId, targetEventId, relType, sourceEventId};\n}\n\nexport class TimelineRelationStore {\n private _store: Store<{ key: string }>;\n\n constructor(store: Store<{ key: string }>) {\n this._store = store;\n }\n\n add(roomId: string, targetEventId: string, relType: string, sourceEventId: string): void {\n this._store.add({key: encodeKey(roomId, targetEventId, relType, sourceEventId)});\n }\n\n remove(roomId: string, targetEventId: string, relType: string, sourceEventId: string): void {\n this._store.delete(encodeKey(roomId, targetEventId, relType, sourceEventId));\n }\n\n removeAllForTarget(roomId: string, targetId: string): void {\n const range = this._store.IDBKeyRange.bound(\n encodeKey(roomId, targetId, MIN_UNICODE, MIN_UNICODE),\n encodeKey(roomId, targetId, MAX_UNICODE, MAX_UNICODE),\n true,\n true\n );\n this._store.delete(range);\n }\n\n removeAllForRoom(roomId: string) {\n const range = this._store.IDBKeyRange.bound(\n encodeKey(roomId, MIN_UNICODE, MIN_UNICODE, MIN_UNICODE),\n encodeKey(roomId, MAX_UNICODE, MAX_UNICODE, MAX_UNICODE),\n true,\n true\n );\n this._store.delete(range);\n }\n\n async getForTargetAndType(roomId: string, targetId: string, relType: string): Promise {\n // exclude both keys as they are theoretical min and max,\n // but we should't have a match for just the room id, or room id with max\n const range = this._store.IDBKeyRange.bound(\n encodeKey(roomId, targetId, relType, MIN_UNICODE),\n encodeKey(roomId, targetId, relType, MAX_UNICODE),\n true,\n true\n );\n const items = await this._store.selectAll(range);\n return items.map(i => decodeKey(i.key));\n }\n\n async getAllForTarget(roomId: string, targetId: string): Promise {\n // exclude both keys as they are theoretical min and max,\n // but we should't have a match for just the room id, or room id with max\n const range = this._store.IDBKeyRange.bound(\n encodeKey(roomId, targetId, MIN_UNICODE, MIN_UNICODE),\n encodeKey(roomId, targetId, MAX_UNICODE, MAX_UNICODE),\n true,\n true\n );\n const items = await this._store.selectAll(range);\n return items.map(i => decodeKey(i.key));\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MIN_UNICODE, MAX_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\nimport {StateEvent} from \"../../types\";\n\nfunction encodeKey(roomId: string, eventType: string, stateKey: string) {\n return `${roomId}|${eventType}|${stateKey}`;\n}\n\nexport interface RoomStateEntry {\n roomId: string;\n event: StateEvent;\n key: string;\n}\n\nexport class RoomStateStore {\n private _roomStateStore: Store;\n\n constructor(idbStore: Store) {\n this._roomStateStore = idbStore;\n }\n\n get(roomId: string, type: string, stateKey: string): Promise {\n const key = encodeKey(roomId, type, stateKey);\n return this._roomStateStore.get(key);\n }\n\n getAllForType(roomId: string, type: string): Promise {\n const range = this._roomStateStore.IDBKeyRange.bound(\n encodeKey(roomId, type, \"\"),\n encodeKey(roomId, type, MAX_UNICODE),\n false,\n true\n );\n return this._roomStateStore.selectAll(range);\n }\n\n set(roomId: string, event: StateEvent): void {\n const key = encodeKey(roomId, event.type, event.state_key);\n const entry = {roomId, event, key};\n this._roomStateStore.put(entry);\n }\n\n removeAllForRoom(roomId: string): void {\n // exclude both keys as they are theoretical min and max,\n // but we should't have a match for just the room id, or room id with max\n const range = this._roomStateStore.IDBKeyRange.bound(roomId, `${roomId}|${MAX_UNICODE}`, true, true);\n this._roomStateStore.delete(range);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MAX_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\n\nfunction encodeKey(roomId: string, userId: string) {\n return `${roomId}|${userId}`;\n}\n\nfunction decodeKey(key: string): { roomId: string, userId: string } {\n const [roomId, userId] = key.split(\"|\");\n return {roomId, userId};\n}\n\n// TODO: Move to RoomMember when that's TypeScript.\nexport interface MemberData {\n roomId: string;\n userId: string;\n avatarUrl: string;\n displayName: string;\n membership: \"join\" | \"leave\" | \"invite\" | \"ban\";\n}\n\ntype MemberStorageEntry = MemberData & { key: string }\n\n// no historical members\nexport class RoomMemberStore {\n private _roomMembersStore: Store;\n\n constructor(roomMembersStore: Store) {\n this._roomMembersStore = roomMembersStore;\n }\n\n get(roomId: string, userId: string): Promise {\n return this._roomMembersStore.get(encodeKey(roomId, userId));\n }\n\n set(member: MemberData): void {\n // Object.assign would be more typesafe, but small objects \n (member as MemberStorageEntry).key = encodeKey(member.roomId, member.userId);\n this._roomMembersStore.put(member as MemberStorageEntry);\n }\n\n getAll(roomId: string): Promise {\n const range = this._roomMembersStore.IDBKeyRange.lowerBound(encodeKey(roomId, \"\"));\n return this._roomMembersStore.selectWhile(range, member => {\n return member.roomId === roomId;\n });\n }\n\n async getAllUserIds(roomId: string): Promise {\n const userIds: string[] = [];\n const range = this._roomMembersStore.IDBKeyRange.lowerBound(encodeKey(roomId, \"\"));\n await this._roomMembersStore.iterateKeys(range, key => {\n const decodedKey = decodeKey(key as string);\n // prevent running into the next room\n if (decodedKey.roomId === roomId) {\n userIds.push(decodedKey.userId);\n return false; // fetch more\n }\n return true; // done\n });\n return userIds;\n }\n\n removeAllForRoom(roomId: string): void {\n // exclude both keys as they are theoretical min and max,\n // but we should't have a match for just the room id, or room id with max\n const range = this._roomMembersStore.IDBKeyRange.bound(roomId, `${roomId}|${MAX_UNICODE}`, true, true);\n this._roomMembersStore.delete(range);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { StorageError } from \"../../common\";\nimport {KeyLimits} from \"../../common\";\nimport { encodeUint32 } from \"../utils\";\nimport {Store} from \"../Store\";\n\ninterface Fragment {\n roomId: string;\n id: number;\n previousId: number | null;\n nextId: number | null;\n previousToken: string | null;\n nextToken: string | null;\n}\n\ntype FragmentEntry = Fragment & { key: string }\n\nfunction encodeKey(roomId: string, fragmentId: number): string {\n return `${roomId}|${encodeUint32(fragmentId)}`;\n}\n\nexport class TimelineFragmentStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n _allRange(roomId: string): IDBKeyRange {\n try {\n return this._store.IDBKeyRange.bound(\n encodeKey(roomId, KeyLimits.minStorageKey),\n encodeKey(roomId, KeyLimits.maxStorageKey)\n );\n } catch (err) {\n throw new StorageError(`error from IDBKeyRange with roomId ${roomId}`, err);\n }\n }\n\n all(roomId: string): Promise {\n return this._store.selectAll(this._allRange(roomId));\n }\n\n /** Returns the fragment without a nextToken and without nextId,\n if any, with the largest id if there are multiple (which should not happen) */\n liveFragment(roomId: string): Promise {\n // why do we need this?\n // Ok, take the case where you've got a /context fragment and a /sync fragment\n // They are not connected. So, upon loading the persister, which one do we take? We can't sort them ...\n // we assume that the one without a nextToken and without a nextId is a live one\n // there should really be only one like this\n\n // reverse because assuming live fragment has bigger id than non-live ones\n return this._store.findReverse(this._allRange(roomId), fragment => {\n return typeof fragment.nextId !== \"number\" && typeof fragment.nextToken !== \"string\";\n });\n }\n\n // should generate an id an return it?\n // depends if we want to do anything smart with fragment ids,\n // like give them meaning depending on range. not for now probably ...\n add(fragment: Fragment): void {\n (fragment as FragmentEntry).key = encodeKey(fragment.roomId, fragment.id);\n this._store.add(fragment as FragmentEntry);\n }\n\n update(fragment: FragmentEntry): void {\n this._store.put(fragment);\n }\n\n get(roomId: string, fragmentId: number): Promise {\n return this._store.get(encodeKey(roomId, fragmentId));\n }\n\n removeAllForRoom(roomId: string): void {\n this._store.delete(this._allRange(roomId));\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { encodeUint32, decodeUint32 } from \"../utils\";\nimport {KeyLimits} from \"../../common\";\nimport {Store} from \"../Store\";\nimport {Content} from \"../../types\";\n\ninterface PendingEntry {\n roomId: string;\n queueIndex: number;\n eventType: string;\n content: Content;\n relatexTxnId: string | null;\n relatedEventId: string | null;\n txnId?: string;\n needsEncryption: boolean;\n needsUpload: boolean;\n key: string;\n}\n\nfunction encodeKey(roomId: string, queueIndex: number): string {\n return `${roomId}|${encodeUint32(queueIndex)}`;\n}\n\nfunction decodeKey(key: string): { roomId: string, queueIndex: number } {\n const [roomId, encodedQueueIndex] = key.split(\"|\");\n const queueIndex = decodeUint32(encodedQueueIndex);\n return {roomId, queueIndex};\n}\n\nexport class PendingEventStore {\n private _eventStore: Store;\n\n constructor(eventStore: Store) {\n this._eventStore = eventStore;\n }\n\n async getMaxQueueIndex(roomId: string): Promise {\n const range = this._eventStore.IDBKeyRange.bound(\n encodeKey(roomId, KeyLimits.minStorageKey),\n encodeKey(roomId, KeyLimits.maxStorageKey),\n false,\n false,\n );\n const maxKey = await this._eventStore.findMaxKey(range);\n if (maxKey) {\n return decodeKey(maxKey as string).queueIndex;\n }\n }\n\n remove(roomId: string, queueIndex: number) {\n const keyRange = this._eventStore.IDBKeyRange.only(encodeKey(roomId, queueIndex));\n this._eventStore.delete(keyRange);\n }\n\n async exists(roomId: string, queueIndex: number): Promise {\n const keyRange = this._eventStore.IDBKeyRange.only(encodeKey(roomId, queueIndex));\n const key = await this._eventStore.getKey(keyRange);\n return !!key;\n }\n \n add(pendingEvent: PendingEntry): void {\n pendingEvent.key = encodeKey(pendingEvent.roomId, pendingEvent.queueIndex);\n this._eventStore.add(pendingEvent);\n }\n\n update(pendingEvent: PendingEntry): void {\n this._eventStore.put(pendingEvent);\n }\n\n getAll(): Promise {\n return this._eventStore.selectAll();\n }\n\n removeAllForRoom(roomId: string): void {\n const minKey = encodeKey(roomId, KeyLimits.minStorageKey);\n const maxKey = encodeKey(roomId, KeyLimits.maxStorageKey);\n const range = this._eventStore.IDBKeyRange.bound(minKey, maxKey);\n this._eventStore.delete(range);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\nimport type {UserIdentity} from \"../../../e2ee/DeviceTracker\";\n\nexport class UserIdentityStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n get(userId: string): Promise {\n return this._store.get(userId);\n }\n\n set(userIdentity: UserIdentity): void {\n this._store.put(userIdentity);\n }\n\n remove(userId: string): void {\n this._store.delete(userId);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MAX_UNICODE, MIN_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\nimport {getDeviceCurve25519Key} from \"../../../e2ee/common\";\nimport type {DeviceKey} from \"../../../e2ee/common\";\n\ntype DeviceKeyEntry = {\n key: string; // key in storage, not a crypto key\n curve25519Key: string;\n deviceKey: DeviceKey\n}\n\nfunction encodeKey(userId: string, deviceId: string): string {\n return `${userId}|${deviceId}`;\n}\n\nfunction decodeKey(key: string): { userId: string, deviceId: string } {\n const [userId, deviceId] = key.split(\"|\");\n return {userId, deviceId};\n}\n\nexport class DeviceKeyStore {\n private _store: Store;\n \n constructor(store: Store) {\n this._store = store;\n }\n\n async getAllForUserId(userId: string): Promise {\n const range = this._store.IDBKeyRange.lowerBound(encodeKey(userId, MIN_UNICODE));\n const entries = await this._store.selectWhile(range, device => {\n return device.deviceKey.user_id === userId;\n });\n return entries.map(e => e.deviceKey);\n }\n\n async getAllDeviceIds(userId: string): Promise {\n const deviceIds: string[] = [];\n const range = this._store.IDBKeyRange.lowerBound(encodeKey(userId, MIN_UNICODE));\n await this._store.iterateKeys(range, key => {\n const decodedKey = decodeKey(key as string);\n // prevent running into the next room\n if (decodedKey.userId === userId) {\n deviceIds.push(decodedKey.deviceId);\n return false; // fetch more\n }\n return true; // done\n });\n return deviceIds;\n }\n\n async get(userId: string, deviceId: string): Promise {\n return (await this._store.get(encodeKey(userId, deviceId)))?.deviceKey;\n }\n\n set(deviceKey: DeviceKey): void {\n this._store.put({\n key: encodeKey(deviceKey.user_id, deviceKey.device_id),\n curve25519Key: getDeviceCurve25519Key(deviceKey)!,\n deviceKey\n });\n }\n\n async getByCurve25519Key(curve25519Key: string): Promise {\n const entry = await this._store.index(\"byCurve25519Key\").get(curve25519Key);\n return entry?.deviceKey;\n }\n\n remove(userId: string, deviceId: string): void {\n this._store.delete(encodeKey(userId, deviceId));\n }\n\n removeAllForUser(userId: string): void {\n // exclude both keys as they are theoretical min and max,\n // but we should't have a match for just the room id, or room id with max\n const range = this._store.IDBKeyRange.bound(encodeKey(userId, MIN_UNICODE), encodeKey(userId, MAX_UNICODE), true, true);\n this._store.delete(range);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MAX_UNICODE, MIN_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\nimport type {CrossSigningKey} from \"../../../verification/CrossSigning\";\n\ntype CrossSigningKeyEntry = {\n crossSigningKey: CrossSigningKey\n key: string; // key in storage, not a crypto key\n}\n\nfunction encodeKey(userId: string, usage: string): string {\n return `${userId}|${usage}`;\n}\n\nfunction decodeKey(key: string): { userId: string, usage: string } {\n const [userId, usage] = key.split(\"|\");\n return {userId, usage};\n}\n\nexport class CrossSigningKeyStore {\n private _store: Store;\n \n constructor(store: Store) {\n this._store = store;\n }\n\n async get(userId: string, deviceId: string): Promise {\n return (await this._store.get(encodeKey(userId, deviceId)))?.crossSigningKey;\n }\n\n set(crossSigningKey: CrossSigningKey): void {\n this._store.put({\n key:encodeKey(crossSigningKey[\"user_id\"], crossSigningKey.usage[0]),\n crossSigningKey\n });\n }\n\n remove(userId: string, usage: string): void {\n this._store.delete(encodeKey(userId, usage));\n }\n\n removeAllForUser(userId: string): void {\n // exclude both keys as they are theoretical min and max,\n // but we should't have a match for just the room id, or room id with max\n const range = this._store.IDBKeyRange.bound(encodeKey(userId, MIN_UNICODE), encodeKey(userId, MAX_UNICODE), true, true);\n this._store.delete(range);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\n\nfunction encodeKey(senderKey: string, sessionId: string): string {\n return `${senderKey}|${sessionId}`;\n}\n\nfunction decodeKey(key: string): { senderKey: string, sessionId: string } {\n const [senderKey, sessionId] = key.split(\"|\");\n return {senderKey, sessionId};\n}\n\nexport type OlmSessionEntry = {\n session: string;\n sessionId: string;\n senderKey: string;\n lastUsed: number;\n}\n\ntype OlmSessionStoredEntry = OlmSessionEntry & { key: string };\n\nexport class OlmSessionStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n async getSessionIds(senderKey: string): Promise {\n const sessionIds: string[] = [];\n const range = this._store.IDBKeyRange.lowerBound(encodeKey(senderKey, \"\"));\n await this._store.iterateKeys(range, key => {\n const decodedKey = decodeKey(key as string);\n // prevent running into the next room\n if (decodedKey.senderKey === senderKey) {\n sessionIds.push(decodedKey.sessionId);\n return false; // fetch more\n }\n return true; // done\n });\n return sessionIds;\n }\n\n getAll(senderKey: string): Promise {\n const range = this._store.IDBKeyRange.lowerBound(encodeKey(senderKey, \"\"));\n return this._store.selectWhile(range, session => {\n return session.senderKey === senderKey;\n });\n }\n\n get(senderKey: string, sessionId: string): Promise {\n return this._store.get(encodeKey(senderKey, sessionId));\n }\n\n set(session: OlmSessionEntry): void {\n (session as OlmSessionStoredEntry).key = encodeKey(session.senderKey, session.sessionId);\n this._store.put(session as OlmSessionStoredEntry);\n }\n\n remove(senderKey: string, sessionId: string): void {\n this._store.delete(encodeKey(senderKey, sessionId));\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MIN_UNICODE, MAX_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\n\nexport enum BackupStatus {\n NotBackedUp = 0,\n BackedUp = 1\n}\n\nexport enum KeySource {\n DeviceMessage = 1,\n Backup,\n Outbound\n}\n\nexport interface InboundGroupSessionEntry {\n roomId: string;\n senderKey: string;\n sessionId: string;\n session?: string;\n claimedKeys?: { [algorithm : string] : string };\n eventIds?: string[];\n backup: BackupStatus,\n source: KeySource\n}\n\ntype InboundGroupSessionStorageEntry = InboundGroupSessionEntry & { key: string };\n\n\nfunction encodeKey(roomId: string, senderKey: string, sessionId: string): string {\n return `${roomId}|${senderKey}|${sessionId}`;\n}\n\nexport class InboundGroupSessionStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n async has(roomId: string, senderKey: string, sessionId: string): Promise {\n const key = encodeKey(roomId, senderKey, sessionId);\n const fetchedKey = await this._store.getKey(key);\n return key === fetchedKey;\n }\n\n get(roomId: string, senderKey: string, sessionId: string): Promise {\n return this._store.get(encodeKey(roomId, senderKey, sessionId));\n }\n\n set(session: InboundGroupSessionEntry): void {\n const storageEntry = session as InboundGroupSessionStorageEntry;\n storageEntry.key = encodeKey(session.roomId, session.senderKey, session.sessionId);\n this._store.put(storageEntry);\n }\n\n removeAllForRoom(roomId: string) {\n const range = this._store.IDBKeyRange.bound(\n encodeKey(roomId, MIN_UNICODE, MIN_UNICODE),\n encodeKey(roomId, MAX_UNICODE, MAX_UNICODE)\n );\n this._store.delete(range);\n }\n countNonBackedUpSessions(): Promise {\n return this._store.index(\"byBackup\").count(this._store.IDBKeyRange.only(BackupStatus.NotBackedUp));\n }\n\n getFirstNonBackedUpSessions(amount: number): Promise {\n return this._store.index(\"byBackup\").selectLimit(this._store.IDBKeyRange.only(BackupStatus.NotBackedUp), amount);\n }\n\n async markAsBackedUp(roomId: string, senderKey: string, sessionId: string): Promise {\n const entry = await this._store.get(encodeKey(roomId, senderKey, sessionId));\n if (entry) {\n entry.backup = BackupStatus.BackedUp;\n this._store.put(entry);\n }\n }\n\n async markAllAsNotBackedUp(): Promise {\n const backedUpKey = this._store.IDBKeyRange.only(BackupStatus.BackedUp);\n let count = 0;\n await this._store.index(\"byBackup\").iterateValues(backedUpKey, (val: InboundGroupSessionEntry, key: IDBValidKey, cur: IDBCursorWithValue) => {\n val.backup = BackupStatus.NotBackedUp;\n cur.update(val);\n count += 1;\n return false;\n });\n return count;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\n\ninterface OutboundSession {\n roomId: string;\n session: string;\n createdAt: number;\n}\n\nexport class OutboundGroupSessionStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n remove(roomId: string): void {\n this._store.delete(roomId);\n }\n\n get(roomId: string): Promise {\n return this._store.get(roomId);\n }\n\n set(session: OutboundSession): void {\n this._store.put(session);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MIN_UNICODE, MAX_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\n\nfunction encodeKey(roomId: string, sessionId: string, messageIndex: number | string): string {\n return `${roomId}|${sessionId}|${messageIndex}`;\n}\n\ninterface GroupSessionDecryption {\n eventId: string;\n timestamp: number;\n}\n\ntype GroupSessionEntry = GroupSessionDecryption & { key: string }\n\nexport class GroupSessionDecryptionStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n get(roomId: string, sessionId: string, messageIndex: number): Promise {\n return this._store.get(encodeKey(roomId, sessionId, messageIndex));\n }\n\n set(roomId: string, sessionId: string, messageIndex: number, decryption: GroupSessionDecryption): void {\n (decryption as GroupSessionEntry).key = encodeKey(roomId, sessionId, messageIndex);\n this._store.put(decryption as GroupSessionEntry);\n }\n \n removeAllForRoom(roomId: string): void {\n const range = this._store.IDBKeyRange.bound(\n encodeKey(roomId, MIN_UNICODE, MIN_UNICODE),\n encodeKey(roomId, MAX_UNICODE, MAX_UNICODE)\n );\n this._store.delete(range);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {MIN_UNICODE, MAX_UNICODE} from \"./common\";\nimport {Store} from \"../Store\";\n\nexport function encodeScopeTypeKey(scope: string, type: string): string {\n return `${scope}|${type}`;\n}\n\ninterface BaseOperation {\n id: string;\n scope: string;\n userIds: string[];\n}\n\ntype OperationType = { type: \"share_room_key\"; roomKeyMessage: RoomKeyMessage; }\n\ntype Operation = BaseOperation & OperationType\n\ntype OperationEntry = Operation & { scopeTypeKey: string; }\n\ninterface RoomKeyMessage {\n room_id: string;\n session_id: string;\n session_key: string;\n algorithm: string;\n chain_index: number;\n}\n\nexport class OperationStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n getAll(): Promise {\n return this._store.selectAll();\n }\n\n async getAllByTypeAndScope(type: string, scope: string): Promise {\n const key = encodeScopeTypeKey(scope, type);\n const results: Operation[] = [];\n await this._store.index(\"byScopeAndType\").iterateWhile(key, value => {\n if (value.scopeTypeKey !== key) {\n return false;\n }\n results.push(value);\n return true;\n });\n return results;\n }\n\n add(operation: Operation): void {\n (operation as OperationEntry).scopeTypeKey = encodeScopeTypeKey(operation.scope, operation.type);\n this._store.add(operation as OperationEntry);\n }\n\n update(operation: Operation): void {\n this._store.put(operation as OperationEntry);\n }\n\n remove(id: string): void {\n this._store.delete(id);\n }\n\n async removeAllForScope(scope: string): Promise {\n const range = this._store.IDBKeyRange.bound(\n encodeScopeTypeKey(scope, MIN_UNICODE),\n encodeScopeTypeKey(scope, MAX_UNICODE)\n );\n const index = this._store.index(\"byScopeAndType\");\n await index.iterateValues(range, (_, __, cur) => {\n cur.delete();\n return true;\n });\n return;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\nimport {Content} from \"../../types\";\n\nexport interface AccountDataEntry {\n type: string;\n content: Content;\n}\n\nexport class AccountDataStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n async get(type: string): Promise {\n return await this._store.get(type);\n }\n\n set(event: AccountDataEntry): void {\n this._store.put(event);\n }\n\n async getAll(): Promise> {\n return await this._store.selectAll();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Store} from \"../Store\";\nimport {StateEvent} from \"../../types\";\nimport {MIN_UNICODE, MAX_UNICODE} from \"./common\";\n\nfunction encodeKey(intent: string, roomId: string, callId: string) {\n return `${intent}|${roomId}|${callId}`;\n}\n\nfunction decodeStorageEntry(storageEntry: CallStorageEntry): CallEntry {\n const [intent, roomId, callId] = storageEntry.key.split(\"|\");\n return {intent, roomId, callId, timestamp: storageEntry.timestamp};\n}\n\nexport interface CallEntry {\n intent: string;\n roomId: string;\n callId: string;\n timestamp: number;\n}\n\ntype CallStorageEntry = {\n key: string;\n timestamp: number;\n}\n\nexport class CallStore {\n private _callStore: Store;\n\n constructor(idbStore: Store) {\n this._callStore = idbStore;\n }\n\n async getByIntent(intent: string): Promise {\n const range = this._callStore.IDBKeyRange.bound(\n encodeKey(intent, MIN_UNICODE, MIN_UNICODE),\n encodeKey(intent, MAX_UNICODE, MAX_UNICODE),\n true,\n true\n );\n const storageEntries = await this._callStore.selectAll(range);\n return storageEntries.map(e => decodeStorageEntry(e));\n }\n\n async getByIntentAndRoom(intent: string, roomId: string): Promise {\n const range = this._callStore.IDBKeyRange.bound(\n encodeKey(intent, roomId, MIN_UNICODE),\n encodeKey(intent, roomId, MAX_UNICODE),\n true,\n true\n );\n const storageEntries = await this._callStore.selectAll(range);\n return storageEntries.map(e => decodeStorageEntry(e));\n }\n\n add(entry: CallEntry) {\n const storageEntry: CallStorageEntry = {\n key: encodeKey(entry.intent, entry.roomId, entry.callId),\n timestamp: entry.timestamp\n };\n this._callStore.add(storageEntry);\n }\n\n remove(intent: string, roomId: string, callId: string): void {\n this._callStore.delete(encodeKey(intent, roomId, callId));\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Store} from \"../Store\";\n\ntype SharedSecret = any;\n\nexport class SharedSecretStore {\n private _store: Store;\n\n constructor(store: Store) {\n this._store = store;\n }\n\n get(name: string): Promise {\n return this._store.get(name);\n }\n\n set(name: string, secret: SharedSecret): void {\n secret.key = name;\n this._store.put(secret);\n }\n\n remove(name: string): void {\n this._store.delete(name);\n }\n\n deleteAllSecrets(): void {\n this._store.clear();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {StoreNames} from \"../common\";\nimport {txnAsPromise} from \"./utils\";\nimport {StorageError} from \"../common\";\nimport {Store} from \"./Store\";\nimport {Storage} from \"./Storage\";\nimport {SessionStore} from \"./stores/SessionStore\";\nimport {RoomSummaryStore} from \"./stores/RoomSummaryStore\";\nimport {InviteStore} from \"./stores/InviteStore\";\nimport {TimelineEventStore} from \"./stores/TimelineEventStore\";\nimport {TimelineRelationStore} from \"./stores/TimelineRelationStore\";\nimport {RoomStateStore} from \"./stores/RoomStateStore\";\nimport {RoomMemberStore} from \"./stores/RoomMemberStore\";\nimport {TimelineFragmentStore} from \"./stores/TimelineFragmentStore\";\nimport {PendingEventStore} from \"./stores/PendingEventStore\";\nimport {UserIdentityStore} from \"./stores/UserIdentityStore\";\nimport {DeviceKeyStore} from \"./stores/DeviceKeyStore\";\nimport {CrossSigningKeyStore} from \"./stores/CrossSigningKeyStore\";\nimport {OlmSessionStore} from \"./stores/OlmSessionStore\";\nimport {InboundGroupSessionStore} from \"./stores/InboundGroupSessionStore\";\nimport {OutboundGroupSessionStore} from \"./stores/OutboundGroupSessionStore\";\nimport {GroupSessionDecryptionStore} from \"./stores/GroupSessionDecryptionStore\";\nimport {OperationStore} from \"./stores/OperationStore\";\nimport {AccountDataStore} from \"./stores/AccountDataStore\";\nimport {CallStore} from \"./stores/CallStore\";\nimport {SharedSecretStore} from \"./stores/SharedSecretStore\";\nimport type {ILogger, ILogItem} from \"../../../logging/types\";\n\nexport type IDBKey = IDBValidKey | IDBKeyRange;\n\nclass WriteErrorInfo {\n constructor(\n public readonly error: StorageError,\n public readonly refItem: ILogItem | undefined,\n public readonly operationName: string,\n public readonly keys: IDBKey[] | undefined,\n ) {}\n}\n\nexport class Transaction {\n private _txn: IDBTransaction;\n private _allowedStoreNames: StoreNames[];\n private _stores: { [storeName in StoreNames]?: any };\n private _storage: Storage;\n private _writeErrors: WriteErrorInfo[];\n\n constructor(txn: IDBTransaction, allowedStoreNames: StoreNames[], storage: Storage) {\n this._txn = txn;\n this._allowedStoreNames = allowedStoreNames;\n this._stores = {};\n this._storage = storage;\n this._writeErrors = [];\n }\n\n get idbFactory(): IDBFactory {\n return this._storage.idbFactory;\n }\n\n get IDBKeyRange(): typeof IDBKeyRange {\n return this._storage.IDBKeyRange;\n }\n\n get databaseName(): string {\n return this._storage.databaseName;\n }\n\n get logger(): ILogger {\n return this._storage.logger;\n }\n\n _idbStore(name: StoreNames): Store {\n if (!this._allowedStoreNames.includes(name)) {\n // more specific error? this is a bug, so maybe not ...\n throw new StorageError(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(\", \")} are allowed.`);\n }\n return new Store(this._txn.objectStore(name), this);\n }\n\n _store(name: StoreNames, mapStore: (idbStore: Store) => T): T {\n if (!this._stores[name]) {\n const idbStore = this._idbStore(name);\n this._stores[name] = mapStore(idbStore);\n }\n return this._stores[name];\n }\n\n get session(): SessionStore {\n return this._store(StoreNames.session, idbStore => new SessionStore(idbStore, this._storage.localStorage));\n }\n\n get roomSummary(): RoomSummaryStore {\n return this._store(StoreNames.roomSummary, idbStore => new RoomSummaryStore(idbStore));\n }\n \n get archivedRoomSummary(): RoomSummaryStore {\n return this._store(StoreNames.archivedRoomSummary, idbStore => new RoomSummaryStore(idbStore));\n }\n\n get invites(): InviteStore {\n return this._store(StoreNames.invites, idbStore => new InviteStore(idbStore));\n }\n\n get timelineFragments(): TimelineFragmentStore {\n return this._store(StoreNames.timelineFragments, idbStore => new TimelineFragmentStore(idbStore));\n }\n\n get timelineEvents(): TimelineEventStore {\n return this._store(StoreNames.timelineEvents, idbStore => new TimelineEventStore(idbStore));\n }\n\n get timelineRelations(): TimelineRelationStore {\n return this._store(StoreNames.timelineRelations, idbStore => new TimelineRelationStore(idbStore));\n }\n\n get roomState(): RoomStateStore {\n return this._store(StoreNames.roomState, idbStore => new RoomStateStore(idbStore));\n }\n\n get roomMembers(): RoomMemberStore {\n return this._store(StoreNames.roomMembers, idbStore => new RoomMemberStore(idbStore));\n }\n\n get pendingEvents(): PendingEventStore {\n return this._store(StoreNames.pendingEvents, idbStore => new PendingEventStore(idbStore));\n }\n\n get userIdentities(): UserIdentityStore {\n return this._store(StoreNames.userIdentities, idbStore => new UserIdentityStore(idbStore));\n }\n\n get deviceKeys(): DeviceKeyStore {\n return this._store(StoreNames.deviceKeys, idbStore => new DeviceKeyStore(idbStore));\n }\n \n get crossSigningKeys(): CrossSigningKeyStore {\n return this._store(StoreNames.crossSigningKeys, idbStore => new CrossSigningKeyStore(idbStore));\n }\n \n get olmSessions(): OlmSessionStore {\n return this._store(StoreNames.olmSessions, idbStore => new OlmSessionStore(idbStore));\n }\n \n get inboundGroupSessions(): InboundGroupSessionStore {\n return this._store(StoreNames.inboundGroupSessions, idbStore => new InboundGroupSessionStore(idbStore));\n }\n \n get outboundGroupSessions(): OutboundGroupSessionStore {\n return this._store(StoreNames.outboundGroupSessions, idbStore => new OutboundGroupSessionStore(idbStore));\n }\n\n get groupSessionDecryptions(): GroupSessionDecryptionStore {\n return this._store(StoreNames.groupSessionDecryptions, idbStore => new GroupSessionDecryptionStore(idbStore));\n }\n\n get operations(): OperationStore {\n return this._store(StoreNames.operations, idbStore => new OperationStore(idbStore));\n }\n\n get accountData(): AccountDataStore {\n return this._store(StoreNames.accountData, idbStore => new AccountDataStore(idbStore));\n }\n \n get calls(): CallStore {\n return this._store(StoreNames.calls, idbStore => new CallStore(idbStore));\n }\n\n get sharedSecrets(): SharedSecretStore {\n return this._store(StoreNames.sharedSecrets, idbStore => new SharedSecretStore(idbStore));\n }\n\n async complete(log?: ILogItem): Promise {\n try {\n await txnAsPromise(this._txn);\n } catch (err) {\n if (this._writeErrors.length) {\n this._logWriteErrors(log);\n throw this._writeErrors[0].error;\n }\n throw err;\n }\n }\n\n getCause(error: Error) {\n if (error instanceof StorageError) {\n if (error.errcode === \"AbortError\" && this._writeErrors.length) {\n return this._writeErrors[0].error;\n }\n }\n return error;\n }\n\n abort(log?: ILogItem): void {\n // TODO: should we wrap the exception in a StorageError?\n try {\n this._txn.abort();\n } catch (abortErr) {\n log?.set(\"couldNotAbortTxn\", true);\n }\n if (this._writeErrors.length) {\n this._logWriteErrors(log);\n }\n }\n\n addWriteError(error: StorageError, refItem: ILogItem | undefined, operationName: string, keys: IDBKey[] | undefined) {\n // don't log subsequent `AbortError`s\n if (error.errcode !== \"AbortError\" || this._writeErrors.length === 0) {\n this._writeErrors.push(new WriteErrorInfo(error, refItem, operationName, keys));\n }\n }\n\n private _logWriteErrors(parentItem: ILogItem | undefined) {\n const callback = errorGroupItem => {\n // we don't have context when there is no parentItem, so at least log stores\n if (!parentItem) {\n errorGroupItem.set(\"allowedStoreNames\", this._allowedStoreNames);\n }\n for (const info of this._writeErrors) {\n errorGroupItem.wrap({l: info.operationName, id: info.keys}, item => {\n if (info.refItem) {\n item.refDetached(info.refItem);\n }\n item.catch(info.error);\n });\n }\n };\n const label = `${this._writeErrors.length} storage write operation(s) failed`;\n if (parentItem) {\n parentItem.wrap(label, callback);\n } else {\n this.logger.run(label, callback);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {IDOMStorage} from \"./types\";\nimport {Transaction} from \"./Transaction\";\nimport { STORE_NAMES, StoreNames, StorageError } from \"../common\";\nimport { reqAsPromise } from \"./utils\";\nimport { ILogger } from \"../../../logging/types\";\n\nconst WEBKITEARLYCLOSETXNBUG_BOGUS_KEY = \"782rh281re38-boguskey\";\n\nexport class Storage {\n private _db: IDBDatabase;\n private _hasWebkitEarlyCloseTxnBug: boolean;\n\n readonly logger: ILogger;\n readonly idbFactory: IDBFactory\n readonly IDBKeyRange: typeof IDBKeyRange;\n readonly storeNames: typeof StoreNames;\n readonly localStorage: IDOMStorage;\n\n constructor(idbDatabase: IDBDatabase, idbFactory: IDBFactory, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean, localStorage: IDOMStorage, logger: ILogger) {\n this._db = idbDatabase;\n this.idbFactory = idbFactory;\n this.IDBKeyRange = _IDBKeyRange;\n this._hasWebkitEarlyCloseTxnBug = hasWebkitEarlyCloseTxnBug;\n this.storeNames = StoreNames;\n this.localStorage = localStorage;\n this.logger = logger;\n }\n\n _validateStoreNames(storeNames: StoreNames[]): void {\n const idx = storeNames.findIndex(name => !STORE_NAMES.includes(name));\n if (idx !== -1) {\n throw new StorageError(`Tried top, a transaction unknown store ${storeNames[idx]}`);\n }\n }\n\n async readTxn(storeNames: StoreNames[]): Promise {\n this._validateStoreNames(storeNames);\n try {\n const txn = this._db.transaction(storeNames, \"readonly\");\n // https://bugs.webkit.org/show_bug.cgi?id=222746 workaround,\n // await a bogus idb request on the new txn so it doesn't close early if we await a microtask first\n if (this._hasWebkitEarlyCloseTxnBug) {\n await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY));\n }\n return new Transaction(txn, storeNames, this);\n } catch(err) {\n throw new StorageError(\"readTxn failed\", err);\n }\n }\n\n async readWriteTxn(storeNames: StoreNames[]): Promise {\n this._validateStoreNames(storeNames);\n try {\n const txn = this._db.transaction(storeNames, \"readwrite\");\n // https://bugs.webkit.org/show_bug.cgi?id=222746 workaround,\n // await a bogus idb request on the new txn so it doesn't close early if we await a microtask first\n if (this._hasWebkitEarlyCloseTxnBug) {\n await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY));\n }\n return new Transaction(txn, storeNames, this);\n } catch(err) {\n throw new StorageError(\"readWriteTxn failed\", err);\n }\n }\n\n close(): void {\n this._db.close();\n }\n\n get databaseName(): string {\n return this._db.name;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { iterateCursor, NOT_DONE, txnAsPromise } from \"./utils\";\nimport { STORE_NAMES, StoreNames } from \"../common\";\n\nexport type Export = { [storeName in StoreNames] : any[] }\n\nexport async function exportSession(db: IDBDatabase): Promise {\n const txn = db.transaction(STORE_NAMES, \"readonly\");\n const data = {};\n await Promise.all(STORE_NAMES.map(async name => {\n const results: any[] = data[name] = []; // initialize in deterministic order\n const store = txn.objectStore(name);\n await iterateCursor(store.openCursor(), (value) => {\n results.push(value);\n return NOT_DONE;\n });\n }));\n return data as Export;\n}\n\nexport async function importSession(db: IDBDatabase, data: Export): Promise {\n const txn = db.transaction(STORE_NAMES, \"readwrite\");\n for (const name of STORE_NAMES) {\n const store = txn.objectStore(name);\n for (const value of data[name]) {\n store.add(value);\n }\n }\n await txnAsPromise(txn);\n}\n","/*\nCopyright 2016-2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { PkSigning } from \"@matrix-org/olm\";\nimport anotherjson from \"another-json\";\nimport type {SignedValue} from \"../e2ee/common\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\n// from matrix-js-sdk\n/**\n * Sign a JSON object using public key cryptography\n * @param obj - Object to sign. The object will be modified to include\n * the new signature\n * @param key - the signing object or the private key\n * seed\n * @param userId - The user ID who owns the signing key\n * @param pubKey - The public key (ignored if key is a seed)\n * @returns the signature for the object\n */\n export function pkSign(olmUtil: Olm, obj: SignedValue, key: Uint8Array | PkSigning, userId: string, pubKey: string): string {\n let createdKey = false;\n if (key instanceof Uint8Array) {\n const keyObj = new olmUtil.PkSigning();\n pubKey = keyObj.init_with_seed(key);\n key = keyObj;\n createdKey = true;\n }\n const sigs = obj.signatures || {};\n delete obj.signatures;\n const unsigned = obj.unsigned;\n if (obj.unsigned) delete obj.unsigned;\n try {\n const mysigs = sigs[userId] || {};\n sigs[userId] = mysigs;\n\n return (mysigs[\"ed25519:\" + pubKey] = key.sign(anotherjson.stringify(obj)));\n } finally {\n obj.signatures = sigs;\n if (unsigned) obj.unsigned = unsigned;\n if (createdKey) {\n key.free();\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {ILogItem} from \"../../../../logging/types\";\nimport type {Account} from \"../../../e2ee/Account.js\";\nimport type {DeviceTracker} from \"../../../e2ee/DeviceTracker.js\";\nimport {IChannel} from \"../channel/IChannel\";\nimport {HomeServerApi} from \"../../../net/HomeServerApi\";\nimport {SASProgressEvents} from \"../types\";\nimport {EventEmitter} from \"../../../../utils/EventEmitter\";\n\nexport type Options = {\n ourUserId: string;\n ourUserDeviceId: string;\n otherUserId: string;\n log: ILogItem;\n olmSas: Olm.SAS;\n olmUtil: Olm.Utility;\n channel: IChannel;\n e2eeAccount: Account;\n deviceTracker: DeviceTracker;\n hsApi: HomeServerApi;\n eventEmitter: EventEmitter\n}\n\nexport abstract class BaseSASVerificationStage {\n protected ourUserId: string;\n protected ourUserDeviceId: string;\n protected otherUserId: string;\n protected log: ILogItem;\n protected olmSAS: Olm.SAS;\n protected olmUtil: Olm.Utility;\n protected _nextStage: BaseSASVerificationStage;\n protected channel: IChannel;\n protected options: Options;\n protected e2eeAccount: Account;\n protected deviceTracker: DeviceTracker;\n protected hsApi: HomeServerApi;\n protected eventEmitter: EventEmitter;\n\n constructor(options: Options) {\n this.options = options;\n this.ourUserId = options.ourUserId;\n this.ourUserDeviceId = options.ourUserDeviceId\n this.otherUserId = options.otherUserId;\n this.log = options.log;\n this.olmSAS = options.olmSas;\n this.olmUtil = options.olmUtil;\n this.channel = options.channel;\n this.e2eeAccount = options.e2eeAccount;\n this.deviceTracker = options.deviceTracker;\n this.hsApi = options.hsApi;\n this.eventEmitter = options.eventEmitter;\n }\n\n setNextStage(stage: BaseSASVerificationStage) {\n this._nextStage = stage;\n }\n\n get nextStage(): BaseSASVerificationStage {\n return this._nextStage;\n }\n\n get otherUserDeviceId(): string {\n const id = this.channel.otherUserDeviceId;\n if (!id) {\n throw new Error(\"Accessed otherUserDeviceId before it was set in channel!\");\n }\n return id;\n }\n\n abstract completeStage(): Promise;\n}\n","export const enum VerificationEventType {\n Request = \"m.key.verification.request\",\n Ready = \"m.key.verification.ready\",\n Start = \"m.key.verification.start\",\n Accept = \"m.key.verification.accept\",\n Key = \"m.key.verification.key\",\n Cancel = \"m.key.verification.cancel\",\n Mac = \"m.key.verification.mac\",\n Done = \"m.key.verification.done\",\n}\n\nexport const enum CancelReason {\n UserCancelled = \"m.user\",\n TimedOut = \"m.timeout\",\n UnknownTransaction = \"m.unknown_transaction\",\n UnknownMethod = \"m.unknown_method\",\n UnexpectedMessage = \"m.unexpected_message\",\n KeyMismatch = \"m.key_mismatch\",\n UserMismatch = \"m.user_mismatch\",\n InvalidMessage = \"m.invalid_message\",\n OtherDeviceAccepted = \"m.accepted\",\n // SAS specific\n MismatchedCommitment = \"m.mismatched_commitment\",\n MismatchedSAS = \"m.mismatched_sas\",\n}\n","// From element-web\nexport type KeyAgreement = \"curve25519-hkdf-sha256\" | \"curve25519\";\nexport type MacMethod = \"hkdf-hmac-sha256.v2\" | \"org.matrix.msc3783.hkdf-hmac-sha256\" | \"hkdf-hmac-sha256\" | \"hmac-sha256\";\n\nexport const KEY_AGREEMENT_LIST: KeyAgreement[] = [\"curve25519-hkdf-sha256\", \"curve25519\"];\nexport const HASHES_LIST = [\"sha256\"];\nexport const MAC_LIST: MacMethod[] = [\n \"hkdf-hmac-sha256.v2\",\n \"org.matrix.msc3783.hkdf-hmac-sha256\",\n \"hkdf-hmac-sha256\",\n \"hmac-sha256\",\n];\nexport const SAS_LIST = [\"decimal\", \"emoji\"];\nexport const SAS_SET = new Set(SAS_LIST);\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Copied from element-web\n\ntype EmojiMapping = [emoji: string, name: string];\n\nconst emojiMapping: EmojiMapping[] = [\n [\"🐶\", \"dog\"], // 0\n [\"🐱\", \"cat\"], // 1\n [\"🦁\", \"lion\"], // 2\n [\"🐎\", \"horse\"], // 3\n [\"🦄\", \"unicorn\"], // 4\n [\"🐷\", \"pig\"], // 5\n [\"🐘\", \"elephant\"], // 6\n [\"🐰\", \"rabbit\"], // 7\n [\"🐼\", \"panda\"], // 8\n [\"🐓\", \"rooster\"], // 9\n [\"🐧\", \"penguin\"], // 10\n [\"🐢\", \"turtle\"], // 11\n [\"🐟\", \"fish\"], // 12\n [\"🐙\", \"octopus\"], // 13\n [\"🦋\", \"butterfly\"], // 14\n [\"🌷\", \"flower\"], // 15\n [\"🌳\", \"tree\"], // 16\n [\"🌵\", \"cactus\"], // 17\n [\"🍄\", \"mushroom\"], // 18\n [\"🌏\", \"globe\"], // 19\n [\"🌙\", \"moon\"], // 20\n [\"☁️\", \"cloud\"], // 21\n [\"🔥\", \"fire\"], // 22\n [\"🍌\", \"banana\"], // 23\n [\"🍎\", \"apple\"], // 24\n [\"🍓\", \"strawberry\"], // 25\n [\"🌽\", \"corn\"], // 26\n [\"🍕\", \"pizza\"], // 27\n [\"🎂\", \"cake\"], // 28\n [\"❤️\", \"heart\"], // 29\n [\"🙂\", \"smiley\"], // 30\n [\"🤖\", \"robot\"], // 31\n [\"🎩\", \"hat\"], // 32\n [\"👓\", \"glasses\"], // 33\n [\"🔧\", \"spanner\"], // 34\n [\"🎅\", \"santa\"], // 35\n [\"👍\", \"thumbs up\"], // 36\n [\"☂️\", \"umbrella\"], // 37\n [\"⌛\", \"hourglass\"], // 38\n [\"⏰\", \"clock\"], // 39\n [\"🎁\", \"gift\"], // 40\n [\"💡\", \"light bulb\"], // 41\n [\"📕\", \"book\"], // 42\n [\"✏️\", \"pencil\"], // 43\n [\"📎\", \"paperclip\"], // 44\n [\"✂️\", \"scissors\"], // 45\n [\"🔒\", \"lock\"], // 46\n [\"🔑\", \"key\"], // 47\n [\"🔨\", \"hammer\"], // 48\n [\"☎️\", \"telephone\"], // 49\n [\"🏁\", \"flag\"], // 50\n [\"🚂\", \"train\"], // 51\n [\"🚲\", \"bicycle\"], // 52\n [\"✈️\", \"aeroplane\"], // 53\n [\"🚀\", \"rocket\"], // 54\n [\"🏆\", \"trophy\"], // 55\n [\"⚽\", \"ball\"], // 56\n [\"🎸\", \"guitar\"], // 57\n [\"🎺\", \"trumpet\"], // 58\n [\"🔔\", \"bell\"], // 59\n [\"⚓️\", \"anchor\"], // 60\n [\"🎧\", \"headphones\"], // 61\n [\"📁\", \"folder\"], // 62\n [\"📌\", \"pin\"], // 63\n];\n\nexport function generateEmojiSas(sasBytes: number[]): EmojiMapping[] {\n const emojis = [\n // just like base64 encoding\n sasBytes[0] >> 2,\n ((sasBytes[0] & 0x3) << 4) | (sasBytes[1] >> 4),\n ((sasBytes[1] & 0xf) << 2) | (sasBytes[2] >> 6),\n sasBytes[2] & 0x3f,\n sasBytes[3] >> 2,\n ((sasBytes[3] & 0x3) << 4) | (sasBytes[4] >> 4),\n ((sasBytes[4] & 0xf) << 2) | (sasBytes[5] >> 6),\n ];\n return emojis.map((num) => emojiMapping[num]);\n}\n\n/**\n * Implementation of decimal encoding of SAS as per:\n * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal\n * @param sasBytes - the five bytes generated by HKDF\n * @returns the derived three numbers between 1000 and 9191 inclusive\n */\nexport function generateDecimalSas(sasBytes: number[]): [number, number, number] {\n /*\n * +--------+--------+--------+--------+--------+\n * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |\n * +--------+--------+--------+--------+--------+\n * bits: 87654321 87654321 87654321 87654321 87654321\n * \\____________/\\_____________/\\____________/\n * 1st number 2nd number 3rd number\n */\n return [\n ((sasBytes[0] << 5) | (sasBytes[1] >> 3)) + 1000,\n (((sasBytes[1] & 0x7) << 10) | (sasBytes[2] << 2) | (sasBytes[3] >> 6)) + 1000,\n (((sasBytes[3] & 0x3f) << 7) | (sasBytes[4] >> 1)) + 1000,\n ];\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {ILogItem} from \"../../../logging/types\";\nimport type {MacMethod} from \"./stages/constants\";\n\nconst macMethods: Record = {\n \"hkdf-hmac-sha256\": \"calculate_mac\",\n \"org.matrix.msc3783.hkdf-hmac-sha256\": \"calculate_mac_fixed_base64\",\n \"hkdf-hmac-sha256.v2\": \"calculate_mac_fixed_base64\",\n \"hmac-sha256\": \"calculate_mac_long_kdf\",\n};\n\nexport function createCalculateMAC(olmSAS: Olm.SAS, method: MacMethod) {\n return function (input: string, info: string, log: ILogItem): string {\n return log.wrap({ l: \"calculate MAC\", method}, () => {\n const mac = olmSAS[macMethods[method]](input, info);\n return mac;\n });\n };\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {VerificationEventType} from \"../channel/types\";\n\nexport class SendDoneStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"SendDoneStage.completeStage\", async (log) => {\n await this.channel.send(VerificationEventType.Done, {}, log);\n await this.channel.waitForEvent(VerificationEventType.Done);\n this.eventEmitter.emit(\"VerificationCompleted\", this.otherUserDeviceId);\n });\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {ILogItem} from \"../../../../logging/types\";\nimport {CancelReason, VerificationEventType} from \"../channel/types\";\nimport {createCalculateMAC} from \"../mac\";\nimport {SendDoneStage} from \"./SendDoneStage\";\nimport {KeyUsage, getKeyEd25519Key} from \"../../CrossSigning\";\nimport {getDeviceEd25519Key} from \"../../../e2ee/common\";\n\nexport type KeyVerifier = (keyId: string, publicKey: string, keyInfo: string) => boolean;\n\nexport class VerifyMacStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"VerifyMacStage.completeStage\", async (log) => {\n const acceptMessage = this.channel.acceptMessage.content;\n const macMethod = acceptMessage.message_authentication_code;\n const calculateMAC = createCalculateMAC(this.olmSAS, macMethod);\n await this.checkMAC(calculateMAC, log);\n this.setNextStage(new SendDoneStage(this.options));\n });\n }\n\n private async checkMAC(calculateMAC: (input: string, info: string, log: ILogItem) => string, log: ILogItem): Promise {\n const {content} = this.channel.getReceivedMessage(VerificationEventType.Mac);\n const baseInfo =\n \"MATRIX_KEY_VERIFICATION_MAC\" +\n this.otherUserId +\n this.otherUserDeviceId +\n this.ourUserId +\n this.ourUserDeviceId +\n this.channel.id;\n\n const calculatedMAC = calculateMAC(Object.keys(content.mac).sort().join(\",\"), baseInfo + \"KEY_IDS\", log);\n if (content.keys !== calculatedMAC) {\n log.log({ l: \"MAC verification failed for keys field\", keys: content.keys, calculated: calculatedMAC });\n this.channel.cancelVerification(CancelReason.KeyMismatch);\n return;\n }\n\n await this.verifyKeys(content.mac, (keyId, key, keyInfo) => {\n const calculatedMAC = calculateMAC(key, baseInfo + keyId, log);\n const matches = keyInfo === calculatedMAC;\n if (!matches) {\n log.log({ l: \"Mac verification failed for key\", keyMac: keyInfo, calculatedMAC, keyId, key });\n this.channel.cancelVerification(CancelReason.KeyMismatch);\n }\n return matches;\n }, log);\n }\n\n protected async verifyKeys(keys: Record, verifier: KeyVerifier, log: ILogItem): Promise {\n const userId = this.otherUserId;\n for (const [keyId, keyInfo] of Object.entries(keys)) {\n const deviceIdOrMSK = keyId.split(\":\", 2)[1];\n const device = await this.deviceTracker.deviceForId(userId, deviceIdOrMSK, this.hsApi, log);\n if (device) {\n if (!verifier(keyId, getDeviceEd25519Key(device), keyInfo)) {\n throw new Error(`MAC verification failed for key ${keyInfo}`);\n }\n } else {\n // If we were not able to find the device, then deviceIdOrMSK is actually the MSK!\n const key = await this.deviceTracker.getCrossSigningKeyForUser(userId, KeyUsage.Master, this.hsApi, log);\n if (!key) {\n log.log({ l: \"Fetching msk failed\", userId });\n throw new Error(\"Fetching MSK for user failed!\");\n }\n const masterKey = getKeyEd25519Key(key);\n if(!(masterKey && verifier(keyId, masterKey, keyInfo))) {\n throw new Error(`MAC verification failed for key ${keyInfo}`);\n }\n }\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {ILogItem} from \"../../../../logging/types\";\nimport {VerificationEventType} from \"../channel/types\";\nimport {createCalculateMAC} from \"../mac\";\nimport {VerifyMacStage} from \"./VerifyMacStage\";\nimport {getKeyEd25519Key, KeyUsage} from \"../../CrossSigning\";\n\nexport class SendMacStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"SendMacStage.completeStage\", async (log) => {\n const acceptMessage = this.channel.acceptMessage.content;\n const macMethod = acceptMessage.message_authentication_code;\n const calculateMAC = createCalculateMAC(this.olmSAS, macMethod);\n await this.sendMAC(calculateMAC, log);\n await this.channel.waitForEvent(VerificationEventType.Mac);\n this.setNextStage(new VerifyMacStage(this.options));\n });\n }\n\n private async sendMAC(calculateMAC: (input: string, info: string, log: ILogItem) => string, log: ILogItem): Promise {\n const mac: Record = {};\n const keyList: string[] = [];\n const baseInfo =\n \"MATRIX_KEY_VERIFICATION_MAC\" +\n this.ourUserId +\n this.ourUserDeviceId +\n this.otherUserId +\n this.otherUserDeviceId +\n this.channel.id;\n\n const deviceKeyId = `ed25519:${this.ourUserDeviceId}`;\n const deviceKeys = this.e2eeAccount.getUnsignedDeviceKey();\n mac[deviceKeyId] = calculateMAC(deviceKeys.keys[deviceKeyId], baseInfo + deviceKeyId, log);\n keyList.push(deviceKeyId);\n\n const key = await this.deviceTracker.getCrossSigningKeyForUser(this.ourUserId, KeyUsage.Master, this.hsApi, log);\n if (!key) {\n log.log({ l: \"Fetching msk failed\", userId: this.ourUserId });\n throw new Error(\"Fetching MSK for user failed!\");\n }\n const crossSigningKey = getKeyEd25519Key(key);\n if (crossSigningKey) {\n const crossSigningKeyId = `ed25519:${crossSigningKey}`;\n mac[crossSigningKeyId] = calculateMAC(crossSigningKey, baseInfo + crossSigningKeyId, log);\n keyList.push(crossSigningKeyId);\n }\n\n const keys = calculateMAC(keyList.sort().join(\",\"), baseInfo + \"KEY_IDS\", log);\n await this.channel.send(VerificationEventType.Mac, { mac, keys }, log);\n }\n}\n\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class VerificationCancelledError extends Error {\n get name(): string {\n return \"VerificationCancelledError\";\n }\n\n get message(): string {\n return \"Verification is cancelled!\";\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport anotherjson from \"another-json\";\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {CancelReason, VerificationEventType} from \"../channel/types\";\nimport {generateEmojiSas} from \"../generator\";\nimport {ILogItem} from \"../../../../logging/types\";\nimport {SendMacStage} from \"./SendMacStage\";\nimport {VerificationCancelledError} from \"../VerificationCancelledError\";\n\ntype SASUserInfo = {\n userId: string;\n deviceId: string;\n publicKey: string;\n};\n\ntype SASUserInfoCollection = {\n our: SASUserInfo;\n their: SASUserInfo;\n id: string;\n initiatedByMe: boolean;\n};\n\nconst calculateKeyAgreement = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"curve25519-hkdf-sha256\": function (sas: SASUserInfoCollection, olmSAS: Olm.SAS, bytes: number): Uint8Array {\n const ourInfo = `${sas.our.userId}|${sas.our.deviceId}|` + `${sas.our.publicKey}|`;\n const theirInfo = `${sas.their.userId}|${sas.their.deviceId}|${sas.their.publicKey}|`;\n const sasInfo =\n \"MATRIX_KEY_VERIFICATION_SAS|\" +\n (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) + sas.id;\n return olmSAS.generate_bytes(sasInfo, bytes);\n },\n \"curve25519\": function (sas: SASUserInfoCollection, olmSAS: Olm.SAS, bytes: number): Uint8Array {\n const ourInfo = `${sas.our.userId}${sas.our.deviceId}`;\n const theirInfo = `${sas.their.userId}${sas.their.deviceId}`;\n const sasInfo =\n \"MATRIX_KEY_VERIFICATION_SAS\" +\n (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) + sas.id;\n return olmSAS.generate_bytes(sasInfo, bytes);\n },\n} as const;\n\nexport class CalculateSASStage extends BaseSASVerificationStage {\n private resolve: () => void;\n private reject: (error: VerificationCancelledError) => void;\n\n public emoji: ReturnType;\n\n async completeStage() {\n await this.log.wrap(\"CalculateSASStage.completeStage\", async (log) => {\n // 1. Check the hash commitment\n if (this.channel.initiatedByUs && !await this.verifyHashCommitment(log)) {\n return;\n }\n // 2. Calculate the SAS\n const emojiConfirmationPromise: Promise = new Promise((res, rej) => {\n this.resolve = res;\n this.reject = rej;\n });\n this.olmSAS.set_their_key(this.theirKey);\n const sasBytes = this.generateSASBytes();\n this.emoji = generateEmojiSas(Array.from(sasBytes));\n this.eventEmitter.emit(\"EmojiGenerated\", this);\n const cancellationReceived = this.channel.waitForEvent(VerificationEventType.Cancel);\n // Don't get stuck on waiting for user input!\n await Promise.race([emojiConfirmationPromise, cancellationReceived]);\n this.setNextStage(new SendMacStage(this.options));\n });\n }\n\n async verifyHashCommitment(log: ILogItem) {\n return await log.wrap(\"CalculateSASStage.verifyHashCommitment\", async () => {\n const acceptMessage = this.channel.getReceivedMessage(VerificationEventType.Accept).content;\n const keyMessage = this.channel.getReceivedMessage(VerificationEventType.Key).content;\n const commitmentStr = keyMessage.key + anotherjson.stringify(this.channel.startMessage.content);\n const receivedCommitment = acceptMessage.commitment;\n const hash = this.olmUtil.sha256(commitmentStr);\n if (hash !== receivedCommitment) {\n log.log({l: \"Commitment mismatched!\", received: receivedCommitment, calculated: hash});\n await this.channel.cancelVerification(CancelReason.MismatchedCommitment);\n return false;\n }\n return true;\n });\n }\n\n private generateSASBytes(): Uint8Array {\n const keyAgreement = this.channel.acceptMessage.content.key_agreement_protocol;\n const otherUserDeviceId = this.otherUserDeviceId;\n const sasBytes = calculateKeyAgreement[keyAgreement]({\n our: {\n userId: this.ourUserId,\n deviceId: this.ourUserDeviceId,\n publicKey: this.olmSAS.get_pubkey(),\n },\n their: {\n userId: this.otherUserId,\n deviceId: otherUserDeviceId,\n publicKey: this.theirKey,\n },\n id: this.channel.id,\n initiatedByMe: this.channel.initiatedByUs,\n }, this.olmSAS, 6);\n return sasBytes;\n }\n\n async setEmojiMatch(match: boolean) {\n if (match) {\n this.resolve();\n }\n else {\n await this.channel.cancelVerification(CancelReason.MismatchedSAS);\n this.reject(new VerificationCancelledError());\n }\n }\n\n get theirKey(): string {\n const {content} = this.channel.getReceivedMessage(VerificationEventType.Key);\n return content.key;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {VerificationEventType} from \"../channel/types\";\nimport {CalculateSASStage} from \"./CalculateSASStage\";\n\nexport class SendKeyStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"SendKeyStage.completeStage\", async (log) => {\n const ourSasKey = this.olmSAS.get_pubkey();\n await this.channel.send(VerificationEventType.Key, {key: ourSasKey}, log);\n /**\n * We may have already got the key in SendAcceptVerificationStage,\n * in which case waitForEvent will return a resolved promise with\n * that content. Otherwise, waitForEvent will actually wait for the\n * key message.\n */\n await this.channel.waitForEvent(VerificationEventType.Key);\n this.setNextStage(new CalculateSASStage(this.options));\n });\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport anotherjson from \"another-json\";\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {HASHES_LIST, MAC_LIST, SAS_SET, KEY_AGREEMENT_LIST} from \"./constants\";\nimport {CancelReason, VerificationEventType} from \"../channel/types\";\nimport {SendKeyStage} from \"./SendKeyStage\";\n\n// from element-web\nfunction intersection(anArray: T[], aSet: Set): T[] {\n return Array.isArray(anArray) ? anArray.filter((x) => aSet.has(x)) : [];\n}\n\nexport class SendAcceptVerificationStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"SendAcceptVerificationStage.completeStage\", async (log) => {\n const {content: startMessage} = this.channel.startMessage;\n const keyAgreement = intersection(KEY_AGREEMENT_LIST, new Set(startMessage.key_agreement_protocols))[0];\n const hashMethod = intersection(HASHES_LIST, new Set(startMessage.hashes))[0];\n const macMethod = intersection(MAC_LIST, new Set(startMessage.message_authentication_codes))[0];\n const sasMethod = intersection(startMessage.short_authentication_string, SAS_SET);\n if (!keyAgreement || !hashMethod || !macMethod || !sasMethod.length) {\n await this.channel.cancelVerification(CancelReason.UnknownMethod);\n return;\n }\n const ourPubKey = this.olmSAS.get_pubkey();\n const commitmentStr = ourPubKey + anotherjson.stringify(startMessage);\n const content = {\n key_agreement_protocol: keyAgreement,\n hash: hashMethod,\n message_authentication_code: macMethod,\n short_authentication_string: sasMethod,\n commitment: this.olmUtil.sha256(commitmentStr),\n };\n await this.channel.send(VerificationEventType.Accept, content, log);\n await this.channel.waitForEvent(VerificationEventType.Key);\n this.setNextStage(new SendKeyStage(this.options));\n });\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {CancelReason, VerificationEventType} from \"../channel/types\";\nimport {KEY_AGREEMENT_LIST, HASHES_LIST, MAC_LIST, SAS_LIST} from \"./constants\";\nimport {SendAcceptVerificationStage} from \"./SendAcceptVerificationStage\";\nimport {SendKeyStage} from \"./SendKeyStage\";\nimport {Deferred} from \"../../../../utils/Deferred\";\nimport type {ILogItem} from \"../../../../logging/types\";\n\nexport class SelectVerificationMethodStage extends BaseSASVerificationStage {\n private hasSentStartMessage?: Promise;\n private allowSelection = true;\n public otherDeviceName: string;\n\n async completeStage() {\n await this.log.wrap(\"SelectVerificationMethodStage.completeStage\", async (log) => {\n await this.findDeviceName(log);\n this.eventEmitter.emit(\"SelectVerificationStage\", this);\n const startMessage = this.channel.waitForEvent(VerificationEventType.Start);\n const acceptMessage = this.channel.waitForEvent(VerificationEventType.Accept);\n const { content } = await Promise.race([startMessage, acceptMessage]);\n if (content.method) {\n // We received the start message \n this.allowSelection = false;\n if (this.hasSentStartMessage) {\n await this.hasSentStartMessage;\n await this.resolveStartConflict(log);\n }\n else {\n this.channel.setStartMessage(this.channel.getReceivedMessage(VerificationEventType.Start));\n }\n }\n else {\n // We received the accept message\n this.channel.setStartMessage(this.channel.getSentMessage(VerificationEventType.Start));\n }\n if (this.channel.initiatedByUs) {\n await acceptMessage;\n this.setNextStage(new SendKeyStage(this.options));\n }\n else {\n // We need to send the accept message next\n this.setNextStage(new SendAcceptVerificationStage(this.options));\n }\n });\n }\n\n private async resolveStartConflict(log: ILogItem) {\n await log.wrap(\"resolveStartConflict\", async () => {\n const receivedStartMessage = this.channel.getReceivedMessage(VerificationEventType.Start);\n const sentStartMessage = this.channel.getSentMessage(VerificationEventType.Start);\n if (receivedStartMessage.content.method !== sentStartMessage.content.method) {\n /**\n * If the two m.key.verification.start messages do not specify the same verification method,\n * then the verification should be cancelled with a code of m.unexpected_message.\n */\n log.log({\n l: \"Methods don't match for the start messages\",\n received: receivedStartMessage.content.method,\n sent: sentStartMessage.content.method,\n });\n await this.channel.cancelVerification(CancelReason.UnexpectedMessage);\n return;\n }\n // In the case of conflict, the lexicographically smaller id wins \n const our = this.ourUserId === this.otherUserId ? this.ourUserDeviceId : this.ourUserId;\n const their = this.ourUserId === this.otherUserId ? this.otherUserDeviceId : this.otherUserId;\n const startMessageToUse = our < their ? sentStartMessage : receivedStartMessage;\n log.log({ l: \"Start message resolved\", message: startMessageToUse, our, their })\n this.channel.setStartMessage(startMessageToUse);\n });\n }\n\n private async findDeviceName(log: ILogItem) {\n await log.wrap(\"SelectVerificationMethodStage.findDeviceName\", async () => {\n const device = await this.options.deviceTracker.deviceForId(this.otherUserId, this.otherUserDeviceId, this.options.hsApi, log);\n if (!device) {\n log.log({ l: \"Cannot find device\", userId: this.otherUserId, deviceId: this.otherUserDeviceId });\n throw new Error(\"Cannot find device\");\n }\n this.otherDeviceName = device.unsigned.device_display_name ?? device.device_id;\n })\n }\n\n async selectEmojiMethod(log: ILogItem) {\n if (!this.allowSelection) { return; } \n const deferred = new Deferred();\n this.hasSentStartMessage = deferred.promise;\n const content = {\n method: \"m.sas.v1\",\n from_device: this.ourUserDeviceId,\n key_agreement_protocols: KEY_AGREEMENT_LIST,\n hashes: HASHES_LIST,\n message_authentication_codes: MAC_LIST,\n short_authentication_string: SAS_LIST,\n };\n /**\n * Once we send the start event, we should eventually receive the accept message.\n * This will cause the Promise.race in completeStage() to resolve and we'll move\n * to the next stage (where we will send the key).\n */\n await this.channel.send(VerificationEventType.Start, content, log);\n deferred.resolve();\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {SelectVerificationMethodStage} from \"./SelectVerificationMethodStage\";\nimport {VerificationEventType} from \"../channel/types\";\n\nexport class SendRequestVerificationStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"SendRequestVerificationStage.completeStage\", async (log) => {\n const content = {\n \"from_device\": this.ourUserDeviceId,\n \"methods\": [\"m.sas.v1\"],\n };\n await this.channel.send(VerificationEventType.Request, content, log);\n this.setNextStage(new SelectVerificationMethodStage(this.options));\n await this.channel.waitForEvent(VerificationEventType.Ready);\n });\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseSASVerificationStage} from \"./BaseSASVerificationStage\";\nimport {VerificationEventType} from \"../channel/types\";\nimport {SelectVerificationMethodStage} from \"./SelectVerificationMethodStage\";\n\nexport class SendReadyStage extends BaseSASVerificationStage {\n async completeStage() {\n await this.log.wrap(\"SendReadyStage.completeStage\", async (log) => {\n const content = {\n \"from_device\": this.ourUserDeviceId,\n \"methods\": [\"m.sas.v1\"],\n };\n await this.channel.send(VerificationEventType.Ready, content, log);\n this.setNextStage(new SelectVerificationMethodStage(this.options));\n });\n }\n}\n","export default {}","// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt Apache-2.0\n// @source: https://gitlab.matrix.org/matrix-org/olm/-/tree/3.2.15\n\nvar Olm = (function() {\nvar olm_exports = {};\nvar onInitSuccess;\nvar onInitFail;\n\nvar Module = (() => {\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;\n if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;\n return (\nfunction(Module) {\n Module = Module || {};\n\n\nvar a;a||(a=typeof Module !== 'undefined' ? Module : {});var aa,ca;a.ready=new Promise(function(b,c){aa=b;ca=c});var g;if(\"undefined\"!==typeof window)g=function(b){window.crypto.getRandomValues(b)};else if(module.exports){var da=require(\"crypto\");g=function(b){var c=da.randomBytes(b.length);b.set(c)}}else throw Error(\"Cannot find global to attach library to\");if(\"undefined\"!==typeof OLM_OPTIONS)for(var ea in OLM_OPTIONS)OLM_OPTIONS.hasOwnProperty(ea)&&(a[ea]=OLM_OPTIONS[ea]);\na.onRuntimeInitialized=function(){h=a._olm_error();olm_exports.PRIVATE_KEY_LENGTH=a._olm_pk_private_key_length();onInitSuccess&&onInitSuccess()};a.onAbort=function(b){onInitFail&&onInitFail(b)};var fa=Object.assign({},a),ha=\"object\"==typeof window,l=\"function\"==typeof importScripts,ia=\"object\"==typeof process&&\"object\"==typeof process.versions&&\"string\"==typeof process.versions.node,m=\"\",ja,ka,la,fs,ma,na;\nif(ia)m=l?require(\"path\").dirname(m)+\"/\":__dirname+\"/\",na=()=>{ma||(fs=require(\"fs\"),ma=require(\"path\"))},ja=function(b,c){na();b=ma.normalize(b);return fs.readFileSync(b,c?void 0:\"utf8\")},la=b=>{b=ja(b,!0);b.buffer||(b=new Uint8Array(b));return b},ka=(b,c,d)=>{na();b=ma.normalize(b);fs.readFile(b,function(e,f){e?d(e):c(f.buffer)})},1{var c=new XMLHttpRequest;c.open(\"GET\",b,!1);c.send(null);return c.responseText},l&&(la=b=>{var c=new XMLHttpRequest;c.open(\"GET\",b,!1);c.responseType=\"arraybuffer\";c.send(null);return new Uint8Array(c.response)}),\nka=(b,c,d)=>{var e=new XMLHttpRequest;e.open(\"GET\",b,!0);e.responseType=\"arraybuffer\";e.onload=()=>{200==e.status||0==e.status&&e.response?c(e.response):d()};e.onerror=d;e.send(null)};a.print||console.log.bind(console);var n=a.printErr||console.warn.bind(console);Object.assign(a,fa);fa=null;var q;a.wasmBinary&&(q=a.wasmBinary);var noExitRuntime=a.noExitRuntime||!0;\"object\"!=typeof WebAssembly&&r(\"no native wasm support detected\");\nvar oa,pa=!1,qa=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf8\"):void 0;\nfunction t(b,c){if(b){var d=u,e=b+c;for(c=b;d[c]&&!(c>=e);)++c;if(16f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}b=e}}else b=\"\";return b}\nfunction ra(b,c,d,e){if(!(0=p){var w=b.charCodeAt(++k);p=65536+((p&1023)<<10)|w&1023}if(127>=p){if(d>=e)break;c[d++]=p}else{if(2047>=p){if(d+1>=e)break;c[d++]=192|p>>6}else{if(65535>=p){if(d+2>=e)break;c[d++]=224|p>>12}else{if(d+3>=e)break;c[d++]=240|p>>18;c[d++]=128|p>>12&63}c[d++]=128|p>>6&63}c[d++]=128|p&63}}c[d]=0;return d-f}function v(b,c,d){return ra(b,u,c,d)}\nfunction x(b){for(var c=0,d=0;d=e?c++:2047>=e?c+=2:55296<=e&&57343>=e?(c+=4,++d):c+=3}return c}var sa,y,u,ta,z,ua,va,wa;function xa(){var b=oa.buffer;sa=b;a.HEAP8=y=new Int8Array(b);a.HEAP16=ta=new Int16Array(b);a.HEAP32=z=new Int32Array(b);a.HEAPU8=u=new Uint8Array(b);a.HEAPU16=new Uint16Array(b);a.HEAPU32=ua=new Uint32Array(b);a.HEAPF32=va=new Float32Array(b);a.HEAPF64=wa=new Float64Array(b)}var za=[],Aa=[],Ba=[];\nfunction Ca(){var b=a.preRun.shift();za.unshift(b)}var A=0,Da=null,B=null;function r(b){if(a.onAbort)a.onAbort(b);b=\"Aborted(\"+b+\")\";n(b);pa=!0;b=new WebAssembly.RuntimeError(b+\". Build with -sASSERTIONS for more info.\");ca(b);throw b;}function Ea(){return C.startsWith(\"data:application/octet-stream;base64,\")}var C;C=\"olm.wasm\";if(!Ea()){var Fa=C;C=a.locateFile?a.locateFile(Fa,m):m+Fa}\nfunction Ga(){var b=C;try{if(b==C&&q)return new Uint8Array(q);if(la)return la(b);throw\"both async and sync fetching of the wasm failed\";}catch(c){r(c)}}\nfunction Ha(){if(!q&&(ha||l)){if(\"function\"==typeof fetch&&!C.startsWith(\"file://\"))return fetch(C,{credentials:\"same-origin\"}).then(function(b){if(!b.ok)throw\"failed to load wasm binary file at '\"+C+\"'\";return b.arrayBuffer()}).catch(function(){return Ga()});if(ka)return new Promise(function(b,c){ka(C,function(d){b(new Uint8Array(d))},c)})}return Promise.resolve().then(function(){return Ga()})}var Ia;function Ja(b){for(;0>0];case \"i8\":return y[b>>0];case \"i16\":return ta[b>>1];case \"i32\":return z[b>>2];case \"i64\":return z[b>>2];case \"float\":return va[b>>2];case \"double\":return wa[b>>3];case \"*\":return ua[b>>2];default:r(\"invalid type for getValue: \"+c)}return null}\nfunction D(b){var c=\"i8\";c.endsWith(\"*\")&&(c=\"*\");switch(c){case \"i1\":y[b>>0]=0;break;case \"i8\":y[b>>0]=0;break;case \"i16\":ta[b>>1]=0;break;case \"i32\":z[b>>2]=0;break;case \"i64\":Ia=[0,0];z[b>>2]=Ia[0];z[b+4>>2]=Ia[1];break;case \"float\":va[b>>2]=0;break;case \"double\":wa[b>>3]=0;break;case \"*\":ua[b>>2]=0;break;default:r(\"invalid type for setValue: \"+c)}}function La(b,c,d){for(var e=0;e>0]=b.charCodeAt(e);d||(y[c>>0]=0)}\nfunction Ma(b,c,d){d=Array(0>>=0;if(2147483648=d;d*=2){var e=c*(1+.2/d);e=Math.min(e,b+100663296);var f=Math;e=Math.max(b,e);f=f.min.call(f,2147483648,e+(65536-e%65536)%65536);a:{try{oa.grow(f-sa.byteLength+65535>>>16);xa();var k=1;break a}catch(p){}k=void 0}if(k)return!0}return!1}};\n(function(){function b(f){a.asm=f.exports;oa=a.asm.c;xa();Aa.unshift(a.asm.d);A--;a.monitorRunDependencies&&a.monitorRunDependencies(A);0==A&&(null!==Da&&(clearInterval(Da),Da=null),B&&(f=B,B=null,f()))}function c(f){b(f.instance)}function d(f){return Ha().then(function(k){return WebAssembly.instantiate(k,e)}).then(function(k){return k}).then(f,function(k){n(\"failed to asynchronously prepare wasm: \"+k);r(k)})}var e={a:Na};A++;a.monitorRunDependencies&&a.monitorRunDependencies(A);if(a.instantiateWasm)try{return a.instantiateWasm(e,\nb)}catch(f){return n(\"Module.instantiateWasm callback failed with error: \"+f),!1}(function(){return q||\"function\"!=typeof WebAssembly.instantiateStreaming||Ea()||C.startsWith(\"file://\")||ia||\"function\"!=typeof fetch?d(c):fetch(C,{credentials:\"same-origin\"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(c,function(k){n(\"wasm streaming compile failed: \"+k);n(\"falling back to ArrayBuffer instantiation\");return d(c)})})})().catch(ca);return{}})();\na.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.d).apply(null,arguments)};a._olm_get_library_version=function(){return(a._olm_get_library_version=a.asm.f).apply(null,arguments)};a._olm_error=function(){return(a._olm_error=a.asm.g).apply(null,arguments)};a._olm_account_last_error=function(){return(a._olm_account_last_error=a.asm.h).apply(null,arguments)};a.__olm_error_to_string=function(){return(a.__olm_error_to_string=a.asm.i).apply(null,arguments)};\na._olm_account_last_error_code=function(){return(a._olm_account_last_error_code=a.asm.j).apply(null,arguments)};a._olm_session_last_error=function(){return(a._olm_session_last_error=a.asm.k).apply(null,arguments)};a._olm_session_last_error_code=function(){return(a._olm_session_last_error_code=a.asm.l).apply(null,arguments)};a._olm_utility_last_error=function(){return(a._olm_utility_last_error=a.asm.m).apply(null,arguments)};\na._olm_utility_last_error_code=function(){return(a._olm_utility_last_error_code=a.asm.n).apply(null,arguments)};a._olm_account_size=function(){return(a._olm_account_size=a.asm.o).apply(null,arguments)};a._olm_session_size=function(){return(a._olm_session_size=a.asm.p).apply(null,arguments)};a._olm_utility_size=function(){return(a._olm_utility_size=a.asm.q).apply(null,arguments)};a._olm_account=function(){return(a._olm_account=a.asm.r).apply(null,arguments)};\na._olm_session=function(){return(a._olm_session=a.asm.s).apply(null,arguments)};a._olm_utility=function(){return(a._olm_utility=a.asm.t).apply(null,arguments)};a._olm_clear_account=function(){return(a._olm_clear_account=a.asm.u).apply(null,arguments)};a._olm_clear_session=function(){return(a._olm_clear_session=a.asm.v).apply(null,arguments)};a._olm_clear_utility=function(){return(a._olm_clear_utility=a.asm.w).apply(null,arguments)};\na._olm_pickle_account_length=function(){return(a._olm_pickle_account_length=a.asm.x).apply(null,arguments)};a._olm_pickle_session_length=function(){return(a._olm_pickle_session_length=a.asm.y).apply(null,arguments)};a._olm_pickle_account=function(){return(a._olm_pickle_account=a.asm.z).apply(null,arguments)};a._olm_pickle_session=function(){return(a._olm_pickle_session=a.asm.A).apply(null,arguments)};a._olm_unpickle_account=function(){return(a._olm_unpickle_account=a.asm.B).apply(null,arguments)};\na._olm_unpickle_session=function(){return(a._olm_unpickle_session=a.asm.C).apply(null,arguments)};a._olm_create_account_random_length=function(){return(a._olm_create_account_random_length=a.asm.D).apply(null,arguments)};a._olm_create_account=function(){return(a._olm_create_account=a.asm.E).apply(null,arguments)};a._olm_account_identity_keys_length=function(){return(a._olm_account_identity_keys_length=a.asm.F).apply(null,arguments)};\na._olm_account_identity_keys=function(){return(a._olm_account_identity_keys=a.asm.G).apply(null,arguments)};a._olm_account_signature_length=function(){return(a._olm_account_signature_length=a.asm.H).apply(null,arguments)};a._olm_account_sign=function(){return(a._olm_account_sign=a.asm.I).apply(null,arguments)};a._olm_account_one_time_keys_length=function(){return(a._olm_account_one_time_keys_length=a.asm.J).apply(null,arguments)};\na._olm_account_one_time_keys=function(){return(a._olm_account_one_time_keys=a.asm.K).apply(null,arguments)};a._olm_account_mark_keys_as_published=function(){return(a._olm_account_mark_keys_as_published=a.asm.L).apply(null,arguments)};a._olm_account_max_number_of_one_time_keys=function(){return(a._olm_account_max_number_of_one_time_keys=a.asm.M).apply(null,arguments)};\na._olm_account_generate_one_time_keys_random_length=function(){return(a._olm_account_generate_one_time_keys_random_length=a.asm.N).apply(null,arguments)};a._olm_account_generate_one_time_keys=function(){return(a._olm_account_generate_one_time_keys=a.asm.O).apply(null,arguments)};a._olm_account_generate_fallback_key_random_length=function(){return(a._olm_account_generate_fallback_key_random_length=a.asm.P).apply(null,arguments)};\na._olm_account_generate_fallback_key=function(){return(a._olm_account_generate_fallback_key=a.asm.Q).apply(null,arguments)};a._olm_account_fallback_key_length=function(){return(a._olm_account_fallback_key_length=a.asm.R).apply(null,arguments)};a._olm_account_fallback_key=function(){return(a._olm_account_fallback_key=a.asm.S).apply(null,arguments)};a._olm_account_unpublished_fallback_key_length=function(){return(a._olm_account_unpublished_fallback_key_length=a.asm.T).apply(null,arguments)};\na._olm_account_unpublished_fallback_key=function(){return(a._olm_account_unpublished_fallback_key=a.asm.U).apply(null,arguments)};a._olm_account_forget_old_fallback_key=function(){return(a._olm_account_forget_old_fallback_key=a.asm.V).apply(null,arguments)};a._olm_create_outbound_session_random_length=function(){return(a._olm_create_outbound_session_random_length=a.asm.W).apply(null,arguments)};a._olm_create_outbound_session=function(){return(a._olm_create_outbound_session=a.asm.X).apply(null,arguments)};\na._olm_create_inbound_session=function(){return(a._olm_create_inbound_session=a.asm.Y).apply(null,arguments)};a._olm_create_inbound_session_from=function(){return(a._olm_create_inbound_session_from=a.asm.Z).apply(null,arguments)};a._olm_session_id_length=function(){return(a._olm_session_id_length=a.asm._).apply(null,arguments)};a._olm_session_id=function(){return(a._olm_session_id=a.asm.$).apply(null,arguments)};\na._olm_session_has_received_message=function(){return(a._olm_session_has_received_message=a.asm.aa).apply(null,arguments)};a._olm_session_describe=function(){return(a._olm_session_describe=a.asm.ba).apply(null,arguments)};a._olm_matches_inbound_session=function(){return(a._olm_matches_inbound_session=a.asm.ca).apply(null,arguments)};a._olm_matches_inbound_session_from=function(){return(a._olm_matches_inbound_session_from=a.asm.da).apply(null,arguments)};\na._olm_remove_one_time_keys=function(){return(a._olm_remove_one_time_keys=a.asm.ea).apply(null,arguments)};a._olm_encrypt_message_type=function(){return(a._olm_encrypt_message_type=a.asm.fa).apply(null,arguments)};a._olm_encrypt_random_length=function(){return(a._olm_encrypt_random_length=a.asm.ga).apply(null,arguments)};a._olm_encrypt_message_length=function(){return(a._olm_encrypt_message_length=a.asm.ha).apply(null,arguments)};\na._olm_encrypt=function(){return(a._olm_encrypt=a.asm.ia).apply(null,arguments)};a._olm_decrypt_max_plaintext_length=function(){return(a._olm_decrypt_max_plaintext_length=a.asm.ja).apply(null,arguments)};a._olm_decrypt=function(){return(a._olm_decrypt=a.asm.ka).apply(null,arguments)};a._olm_sha256_length=function(){return(a._olm_sha256_length=a.asm.la).apply(null,arguments)};a._olm_sha256=function(){return(a._olm_sha256=a.asm.ma).apply(null,arguments)};\na._olm_ed25519_verify=function(){return(a._olm_ed25519_verify=a.asm.na).apply(null,arguments)};a._olm_pk_encryption_last_error=function(){return(a._olm_pk_encryption_last_error=a.asm.oa).apply(null,arguments)};a._olm_pk_encryption_last_error_code=function(){return(a._olm_pk_encryption_last_error_code=a.asm.pa).apply(null,arguments)};a._olm_pk_encryption_size=function(){return(a._olm_pk_encryption_size=a.asm.qa).apply(null,arguments)};\na._olm_pk_encryption=function(){return(a._olm_pk_encryption=a.asm.ra).apply(null,arguments)};a._olm_clear_pk_encryption=function(){return(a._olm_clear_pk_encryption=a.asm.sa).apply(null,arguments)};a._olm_pk_encryption_set_recipient_key=function(){return(a._olm_pk_encryption_set_recipient_key=a.asm.ta).apply(null,arguments)};a._olm_pk_key_length=function(){return(a._olm_pk_key_length=a.asm.ua).apply(null,arguments)};\na._olm_pk_ciphertext_length=function(){return(a._olm_pk_ciphertext_length=a.asm.va).apply(null,arguments)};a._olm_pk_mac_length=function(){return(a._olm_pk_mac_length=a.asm.wa).apply(null,arguments)};a._olm_pk_encrypt_random_length=function(){return(a._olm_pk_encrypt_random_length=a.asm.xa).apply(null,arguments)};a._olm_pk_encrypt=function(){return(a._olm_pk_encrypt=a.asm.ya).apply(null,arguments)};\na._olm_pk_decryption_last_error=function(){return(a._olm_pk_decryption_last_error=a.asm.za).apply(null,arguments)};a._olm_pk_decryption_last_error_code=function(){return(a._olm_pk_decryption_last_error_code=a.asm.Aa).apply(null,arguments)};a._olm_pk_decryption_size=function(){return(a._olm_pk_decryption_size=a.asm.Ba).apply(null,arguments)};a._olm_pk_decryption=function(){return(a._olm_pk_decryption=a.asm.Ca).apply(null,arguments)};\na._olm_clear_pk_decryption=function(){return(a._olm_clear_pk_decryption=a.asm.Da).apply(null,arguments)};a._olm_pk_private_key_length=function(){return(a._olm_pk_private_key_length=a.asm.Ea).apply(null,arguments)};a._olm_pk_generate_key_random_length=function(){return(a._olm_pk_generate_key_random_length=a.asm.Fa).apply(null,arguments)};a._olm_pk_key_from_private=function(){return(a._olm_pk_key_from_private=a.asm.Ga).apply(null,arguments)};\na._olm_pk_generate_key=function(){return(a._olm_pk_generate_key=a.asm.Ha).apply(null,arguments)};a._olm_pickle_pk_decryption_length=function(){return(a._olm_pickle_pk_decryption_length=a.asm.Ia).apply(null,arguments)};a._olm_pickle_pk_decryption=function(){return(a._olm_pickle_pk_decryption=a.asm.Ja).apply(null,arguments)};a._olm_unpickle_pk_decryption=function(){return(a._olm_unpickle_pk_decryption=a.asm.Ka).apply(null,arguments)};\na._olm_pk_max_plaintext_length=function(){return(a._olm_pk_max_plaintext_length=a.asm.La).apply(null,arguments)};a._olm_pk_decrypt=function(){return(a._olm_pk_decrypt=a.asm.Ma).apply(null,arguments)};a._olm_pk_get_private_key=function(){return(a._olm_pk_get_private_key=a.asm.Na).apply(null,arguments)};a._olm_pk_signing_size=function(){return(a._olm_pk_signing_size=a.asm.Oa).apply(null,arguments)};a._olm_pk_signing=function(){return(a._olm_pk_signing=a.asm.Pa).apply(null,arguments)};\na._olm_pk_signing_last_error=function(){return(a._olm_pk_signing_last_error=a.asm.Qa).apply(null,arguments)};a._olm_pk_signing_last_error_code=function(){return(a._olm_pk_signing_last_error_code=a.asm.Ra).apply(null,arguments)};a._olm_clear_pk_signing=function(){return(a._olm_clear_pk_signing=a.asm.Sa).apply(null,arguments)};a._olm_pk_signing_seed_length=function(){return(a._olm_pk_signing_seed_length=a.asm.Ta).apply(null,arguments)};\na._olm_pk_signing_public_key_length=function(){return(a._olm_pk_signing_public_key_length=a.asm.Ua).apply(null,arguments)};a._olm_pk_signing_key_from_seed=function(){return(a._olm_pk_signing_key_from_seed=a.asm.Va).apply(null,arguments)};a._olm_pk_signature_length=function(){return(a._olm_pk_signature_length=a.asm.Wa).apply(null,arguments)};a._olm_pk_sign=function(){return(a._olm_pk_sign=a.asm.Xa).apply(null,arguments)};\na._olm_inbound_group_session_size=function(){return(a._olm_inbound_group_session_size=a.asm.Ya).apply(null,arguments)};a._olm_inbound_group_session=function(){return(a._olm_inbound_group_session=a.asm.Za).apply(null,arguments)};a._olm_clear_inbound_group_session=function(){return(a._olm_clear_inbound_group_session=a.asm._a).apply(null,arguments)};a._olm_inbound_group_session_last_error=function(){return(a._olm_inbound_group_session_last_error=a.asm.$a).apply(null,arguments)};\na._olm_inbound_group_session_last_error_code=function(){return(a._olm_inbound_group_session_last_error_code=a.asm.ab).apply(null,arguments)};a._olm_init_inbound_group_session=function(){return(a._olm_init_inbound_group_session=a.asm.bb).apply(null,arguments)};a._olm_import_inbound_group_session=function(){return(a._olm_import_inbound_group_session=a.asm.cb).apply(null,arguments)};\na._olm_pickle_inbound_group_session_length=function(){return(a._olm_pickle_inbound_group_session_length=a.asm.db).apply(null,arguments)};a._olm_pickle_inbound_group_session=function(){return(a._olm_pickle_inbound_group_session=a.asm.eb).apply(null,arguments)};a._olm_unpickle_inbound_group_session=function(){return(a._olm_unpickle_inbound_group_session=a.asm.fb).apply(null,arguments)};\na._olm_group_decrypt_max_plaintext_length=function(){return(a._olm_group_decrypt_max_plaintext_length=a.asm.gb).apply(null,arguments)};a._olm_group_decrypt=function(){return(a._olm_group_decrypt=a.asm.hb).apply(null,arguments)};a._olm_inbound_group_session_id_length=function(){return(a._olm_inbound_group_session_id_length=a.asm.ib).apply(null,arguments)};a._olm_inbound_group_session_id=function(){return(a._olm_inbound_group_session_id=a.asm.jb).apply(null,arguments)};\na._olm_inbound_group_session_first_known_index=function(){return(a._olm_inbound_group_session_first_known_index=a.asm.kb).apply(null,arguments)};a._olm_inbound_group_session_is_verified=function(){return(a._olm_inbound_group_session_is_verified=a.asm.lb).apply(null,arguments)};a._olm_export_inbound_group_session_length=function(){return(a._olm_export_inbound_group_session_length=a.asm.mb).apply(null,arguments)};\na._olm_export_inbound_group_session=function(){return(a._olm_export_inbound_group_session=a.asm.nb).apply(null,arguments)};a._olm_outbound_group_session_size=function(){return(a._olm_outbound_group_session_size=a.asm.ob).apply(null,arguments)};a._olm_outbound_group_session=function(){return(a._olm_outbound_group_session=a.asm.pb).apply(null,arguments)};a._olm_clear_outbound_group_session=function(){return(a._olm_clear_outbound_group_session=a.asm.qb).apply(null,arguments)};\na._olm_outbound_group_session_last_error=function(){return(a._olm_outbound_group_session_last_error=a.asm.rb).apply(null,arguments)};a._olm_outbound_group_session_last_error_code=function(){return(a._olm_outbound_group_session_last_error_code=a.asm.sb).apply(null,arguments)};a._olm_pickle_outbound_group_session_length=function(){return(a._olm_pickle_outbound_group_session_length=a.asm.tb).apply(null,arguments)};\na._olm_pickle_outbound_group_session=function(){return(a._olm_pickle_outbound_group_session=a.asm.ub).apply(null,arguments)};a._olm_unpickle_outbound_group_session=function(){return(a._olm_unpickle_outbound_group_session=a.asm.vb).apply(null,arguments)};a._olm_init_outbound_group_session_random_length=function(){return(a._olm_init_outbound_group_session_random_length=a.asm.wb).apply(null,arguments)};\na._olm_init_outbound_group_session=function(){return(a._olm_init_outbound_group_session=a.asm.xb).apply(null,arguments)};a._olm_group_encrypt_message_length=function(){return(a._olm_group_encrypt_message_length=a.asm.yb).apply(null,arguments)};a._olm_group_encrypt=function(){return(a._olm_group_encrypt=a.asm.zb).apply(null,arguments)};a._olm_outbound_group_session_id_length=function(){return(a._olm_outbound_group_session_id_length=a.asm.Ab).apply(null,arguments)};\na._olm_outbound_group_session_id=function(){return(a._olm_outbound_group_session_id=a.asm.Bb).apply(null,arguments)};a._olm_outbound_group_session_message_index=function(){return(a._olm_outbound_group_session_message_index=a.asm.Cb).apply(null,arguments)};a._olm_outbound_group_session_key_length=function(){return(a._olm_outbound_group_session_key_length=a.asm.Db).apply(null,arguments)};a._olm_outbound_group_session_key=function(){return(a._olm_outbound_group_session_key=a.asm.Eb).apply(null,arguments)};\na._olm_sas_last_error=function(){return(a._olm_sas_last_error=a.asm.Fb).apply(null,arguments)};a._olm_sas_last_error_code=function(){return(a._olm_sas_last_error_code=a.asm.Gb).apply(null,arguments)};a._olm_sas_size=function(){return(a._olm_sas_size=a.asm.Hb).apply(null,arguments)};a._olm_sas=function(){return(a._olm_sas=a.asm.Ib).apply(null,arguments)};a._olm_clear_sas=function(){return(a._olm_clear_sas=a.asm.Jb).apply(null,arguments)};\na._olm_create_sas_random_length=function(){return(a._olm_create_sas_random_length=a.asm.Kb).apply(null,arguments)};a._olm_create_sas=function(){return(a._olm_create_sas=a.asm.Lb).apply(null,arguments)};a._olm_sas_pubkey_length=function(){return(a._olm_sas_pubkey_length=a.asm.Mb).apply(null,arguments)};a._olm_sas_get_pubkey=function(){return(a._olm_sas_get_pubkey=a.asm.Nb).apply(null,arguments)};a._olm_sas_set_their_key=function(){return(a._olm_sas_set_their_key=a.asm.Ob).apply(null,arguments)};\na._olm_sas_is_their_key_set=function(){return(a._olm_sas_is_their_key_set=a.asm.Pb).apply(null,arguments)};a._olm_sas_generate_bytes=function(){return(a._olm_sas_generate_bytes=a.asm.Qb).apply(null,arguments)};a._olm_sas_mac_length=function(){return(a._olm_sas_mac_length=a.asm.Rb).apply(null,arguments)};a._olm_sas_calculate_mac_fixed_base64=function(){return(a._olm_sas_calculate_mac_fixed_base64=a.asm.Sb).apply(null,arguments)};\na._olm_sas_calculate_mac=function(){return(a._olm_sas_calculate_mac=a.asm.Tb).apply(null,arguments)};a._olm_sas_calculate_mac_long_kdf=function(){return(a._olm_sas_calculate_mac_long_kdf=a.asm.Ub).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Vb).apply(null,arguments)};a._free=function(){return(a._free=a.asm.Wb).apply(null,arguments)};\nvar Oa=a.stackSave=function(){return(Oa=a.stackSave=a.asm.Xb).apply(null,arguments)},Pa=a.stackRestore=function(){return(Pa=a.stackRestore=a.asm.Yb).apply(null,arguments)},Qa=a.stackAlloc=function(){return(Qa=a.stackAlloc=a.asm.Zb).apply(null,arguments)};a.UTF8ToString=t;a.stringToUTF8=v;a.intArrayFromString=Ma;a.writeAsciiToMemory=La;a.ALLOC_STACK=1;var Ra;B=function Sa(){Ra||Ta();Ra||(B=Sa)};\nfunction Ta(){function b(){if(!Ra&&(Ra=!0,a.calledRun=!0,!pa)){Ja(Aa);aa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for(\"function\"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;){var c=a.postRun.shift();Ba.unshift(c)}Ja(Ba)}}if(!(0 implements IVerificationMethod {\n private startStage: BaseSASVerificationStage;\n private olmSas: Olm.SAS;\n public finished: boolean = false;\n public readonly channel: IChannel;\n private timeout: Timeout;\n public otherUserId: string;\n private ourUserId: string;\n \n constructor(options: Options) {\n super();\n const { olm, channel, clock } = options;\n const olmSas = new olm.SAS();\n this.olmSas = olmSas;\n this.channel = channel;\n this.otherUserId = options.otherUserId;\n this.ourUserId = options.ourUserId;\n this.setupCancelAfterTimeout(clock);\n const stageOptions = {...options, olmSas, eventEmitter: this};\n if (channel.getReceivedMessage(VerificationEventType.Start)) {\n this.startStage = new SelectVerificationMethodStage(stageOptions);\n }\n else if (channel.getReceivedMessage(VerificationEventType.Request)) {\n this.startStage = new SendReadyStage(stageOptions);\n }\n else {\n this.startStage = new SendRequestVerificationStage(stageOptions);\n }\n }\n\n private async setupCancelAfterTimeout(clock: Clock): Promise {\n try {\n const tenMinutes = 10 * 60 * 1000;\n this.timeout = clock.createTimeout(tenMinutes);\n await this.timeout.elapsed();\n await this.channel.cancelVerification(CancelReason.TimedOut);\n }\n catch {\n // Ignore errors\n }\n }\n\n async abort(): Promise {\n await this.channel.cancelVerification(CancelReason.UserCancelled);\n this.finished = true;\n }\n\n async verify(): Promise {\n let success = true;\n try {\n let stage = this.startStage;\n do {\n await stage.completeStage();\n stage = stage.nextStage;\n } while (stage);\n }\n catch (e) {\n if (!(e instanceof VerificationCancelledError)) {\n throw e; \n }\n success = false;\n }\n finally {\n if (this.channel.isCancelled) {\n this.emit(\"VerificationCancelled\", this.channel.cancellation);\n }\n this.olmSas.free();\n this.timeout.abort();\n this.finished = true;\n }\n return success;\n }\n\n get otherDeviceId(): string {\n return this.channel.otherUserDeviceId;\n }\n\n get isCrossSigningAnotherUser(): boolean {\n return !(this.otherUserId === this.ourUserId);\n }\n}\n\nimport {HomeServer} from \"../../../mocks/HomeServer.js\";\nimport Olm from \"@matrix-org/olm/olm.js\";\nimport {MockChannel} from \"./channel/MockChannel\";\nimport {Clock as MockClock} from \"../../../mocks/Clock.js\";\nimport {NullLogger} from \"../../../logging/NullLogger\";\nimport {SASFixtures} from \"../../../fixtures/matrix/sas/events\";\nimport {SendKeyStage} from \"./stages/SendKeyStage\";\nimport {CalculateSASStage} from \"./stages/CalculateSASStage\";\nimport {SendMacStage} from \"./stages/SendMacStage\";\nimport {VerifyMacStage} from \"./stages/VerifyMacStage\";\nimport {SendDoneStage} from \"./stages/SendDoneStage\";\nimport {SendAcceptVerificationStage} from \"./stages/SendAcceptVerificationStage\";\n\nexport function tests() {\n async function createSASRequest(\n ourUserId: string,\n ourDeviceId: string,\n theirUserId: string,\n theirDeviceId: string,\n txnId: string,\n receivedMessages,\n startingMessage?: any\n ) {\n const homeserverMock = new HomeServer();\n const hsApi = homeserverMock.api;\n const olm = Olm;\n await olm.init();\n const olmUtil = new Olm.Utility();\n const e2eeAccount = {\n getUnsignedDeviceKey: () => {\n return {\n keys: {\n [`ed25519:${ourDeviceId}`]:\n \"srsWWbrnQFIOmUSdrt3cS/unm03qAIgXcWwQg9BegKs\",\n },\n };\n },\n };\n const deviceTracker = {\n getCrossSigningKeyForUser: (userId, __, _hsApi, _) => {\n let masterKey =\n userId === ourUserId\n ? \"5HIrEawRiiQioViNfezPDWfPWH2pdaw3pbQNHEVN2jM\"\n : \"Ot8Y58PueQ7hJVpYWAJkg2qaREJAY/UhGZYOrsd52oo\";\n return {\n user_id: userId,\n usage: [\"master\"],\n keys: {\n [`ed25519:${masterKey}`]: masterKey,\n }\n };\n },\n deviceForId: (_userId, deviceId, _hsApi, _log) => {\n return {\n device_id: deviceId,\n keys: {\n [`ed25519:${deviceId}`]: \"D8w9mrokGdEZPdPgrU0kQkYi4vZyzKEBfvGyZsGK7+Q\",\n },\n unsigned: {\n device_display_name: \"lala10\",\n }\n };\n },\n };\n const channel = new MockChannel(\n theirDeviceId,\n theirUserId,\n ourUserId,\n ourDeviceId,\n receivedMessages,\n deviceTracker,\n txnId,\n olm,\n startingMessage,\n );\n const clock = new MockClock();\n const logger = new NullLogger();\n return logger.run(\"log\", (log) => {\n // @ts-ignore\n const sas = new SASVerification({\n channel,\n clock,\n hsApi,\n // @ts-ignore\n deviceTracker,\n e2eeAccount,\n olm,\n olmUtil,\n otherUserId: theirUserId!,\n ourUserId,\n ourUserDeviceId: ourDeviceId,\n log,\n });\n // @ts-ignore\n channel.setOlmSas(sas.olmSas);\n sas.on(\"EmojiGenerated\", async (stage) => {\n await stage?.setEmojiMatch(true);\n });\n return { sas, clock, logger };\n });\n }\n\n return {\n \"Order of stages created matches expected order when I sent request, they sent start\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .fixtures();\n const { sas } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n await sas.verify();\n const expectedOrder = [\n SendRequestVerificationStage,\n SelectVerificationMethodStage,\n SendAcceptVerificationStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when I sent request, I sent start\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .youSentStart()\n .fixtures();\n const { sas, logger } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n sas.on(\"SelectVerificationStage\", (stage) => {\n logger.run(\"send start\", async (log) => {\n await stage?.selectEmojiMethod(log);\n });\n });\n await sas.verify();\n const expectedOrder = [\n SendRequestVerificationStage,\n SelectVerificationMethodStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is received\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .theySentStart()\n .fixtures();\n const startingMessage = receivedMessages.get(VerificationEventType.Start);\n const { sas } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages,\n startingMessage,\n );\n await sas.verify();\n const expectedOrder = [\n SelectVerificationMethodStage,\n SendAcceptVerificationStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is sent with start conflict (they win)\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .youSentStart()\n .theyWinConflict()\n .fixtures();\n const { sas } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n await sas.verify();\n const expectedOrder = [\n SendRequestVerificationStage,\n SelectVerificationMethodStage,\n SendAcceptVerificationStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is sent with start conflict (I win)\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount3:matrix.org\";\n const theirUserId = \"@foobaraccount:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .youSentStart()\n .youWinConflict()\n .fixtures();\n const { sas, logger } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n sas.on(\"SelectVerificationStage\", (stage) => {\n logger.run(\"send start\", async (log) => {\n await stage?.selectEmojiMethod(log);\n });\n });\n await sas.verify();\n const expectedOrder = [\n SendRequestVerificationStage,\n SelectVerificationMethodStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is received with start conflict (they win)\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .theySentStart()\n .youSentStart()\n .theyWinConflict()\n .fixtures();\n const startingMessage = receivedMessages.get(VerificationEventType.Start);\n const { sas } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages,\n startingMessage,\n );\n await sas.verify();\n const expectedOrder = [\n SelectVerificationMethodStage,\n SendAcceptVerificationStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is received with start conflict (I win)\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount3:matrix.org\";\n const theirUserId = \"@foobaraccount:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .theySentStart()\n .youSentStart()\n .youWinConflict()\n .fixtures();\n const startingMessage = receivedMessages.get(VerificationEventType.Start);\n const { sas, logger } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages,\n startingMessage,\n );\n sas.on(\"SelectVerificationStage\", (stage) => {\n logger.run(\"send start\", async (log) => {\n await stage?.selectEmojiMethod(log);\n });\n });\n await sas.verify();\n const expectedOrder = [\n SelectVerificationMethodStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is sent with start conflict (I win), same user\": async (assert) => {\n const ourDeviceId = \"FWKXUYUHTF\";\n const ourUserId = \"@foobaraccount3:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"ILQHOACESQ\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .youSentStart()\n .youWinConflict()\n .fixtures();\n const { sas, logger } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n sas.on(\"SelectVerificationStage\", (stage) => {\n logger.run(\"send start\", async (log) => {\n await stage?.selectEmojiMethod(log);\n });\n });\n await sas.verify();\n const expectedOrder = [\n SendRequestVerificationStage,\n SelectVerificationMethodStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Order of stages created matches expected order when request is sent with start conflict (they win), same user\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount3:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .youSentStart()\n .theyWinConflict()\n .fixtures();\n const { sas } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n await sas.verify();\n const expectedOrder = [\n SendRequestVerificationStage,\n SelectVerificationMethodStage,\n SendAcceptVerificationStage,\n SendKeyStage,\n CalculateSASStage,\n SendMacStage,\n VerifyMacStage,\n SendDoneStage\n ]\n //@ts-ignore\n let stage = sas.startStage;\n for (const stageClass of expectedOrder) {\n assert.strictEqual(stage instanceof stageClass, true);\n stage = stage.nextStage;\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Verification is cancelled after 10 minutes\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .fixtures();\n const { sas, clock } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n const promise = sas.verify();\n clock.elapse(10 * 60 * 1000);\n try {\n await promise;\n }\n catch (e) {\n assert.strictEqual(e instanceof VerificationCancelledError, true);\n }\n assert.strictEqual(sas.finished, true);\n },\n \"Verification is cancelled when there's no common hash algorithm\": async (assert) => {\n const ourDeviceId = \"ILQHOACESQ\";\n const ourUserId = \"@foobaraccount:matrix.org\";\n const theirUserId = \"@foobaraccount3:matrix.org\";\n const theirDeviceId = \"FWKXUYUHTF\";\n const txnId = \"t150836b91a7bed\";\n const receivedMessages = new SASFixtures(theirUserId, theirDeviceId, txnId)\n .youSentRequest()\n .theySentStart()\n .fixtures();\n receivedMessages.get(VerificationEventType.Start).content.key_agreement_protocols = [\"foo\"];\n const { sas } = await createSASRequest(\n ourUserId,\n ourDeviceId,\n theirUserId,\n theirDeviceId,\n txnId, \n receivedMessages\n );\n try {\n await sas.verify()\n }\n catch (e) {\n assert.strictEqual(e instanceof VerificationCancelledError, true);\n }\n assert.strictEqual(sas.finished, true);\n },\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {ILogItem} from \"../../../../logging/types\";\nimport {CancelReason, VerificationEventType} from \"./types\";\n\nexport const messageFromErrorType = {\n [CancelReason.UserCancelled]: \"User declined\",\n [CancelReason.InvalidMessage]: \"Invalid Message.\",\n [CancelReason.KeyMismatch]: \"Key Mismatch.\",\n [CancelReason.OtherDeviceAccepted]: \"Another device has accepted this request.\",\n [CancelReason.TimedOut]: \"Timed Out\",\n [CancelReason.UnexpectedMessage]: \"Unexpected Message.\",\n [CancelReason.UnknownMethod]: \"Unknown method.\",\n [CancelReason.UnknownTransaction]: \"Unknown Transaction.\",\n [CancelReason.UserMismatch]: \"User Mismatch\",\n [CancelReason.MismatchedCommitment]: \"Hash commitment does not match.\",\n [CancelReason.MismatchedSAS]: \"Emoji/decimal does not match.\",\n}\n\nexport interface IChannel {\n send(eventType: VerificationEventType, content: any, log: ILogItem): Promise;\n waitForEvent(eventType: VerificationEventType): Promise;\n getSentMessage(event: VerificationEventType): any;\n getReceivedMessage(event: VerificationEventType): any;\n setStartMessage(content: any): void;\n cancelVerification(cancellationType: CancelReason): Promise;\n acceptMessage: any;\n startMessage: any;\n initiatedByUs: boolean;\n isCancelled: boolean;\n cancellation?: { code: CancelReason, cancelledByUs: boolean };\n id: string;\n otherUserDeviceId: string;\n} \n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function groupBy(array: V[], groupFn: (V) => K): Map {\n return groupByWithCreator(array, groupFn,\n () => {return [];},\n (array, value) => array.push(value)\n );\n}\n\nexport function groupByWithCreator(array: V[], groupFn: (V) => K, createCollectionFn: () => C, addCollectionFn: (C, V) => void): Map {\n return array.reduce((map, value) => {\n const key = groupFn(value);\n let collection = map.get(key);\n if (!collection) {\n collection = createCollectionFn();\n map.set(key, collection);\n }\n addCollectionFn(collection, value);\n return map;\n }, new Map());\n}\n\nexport function countBy(events: V[], mapper: (V) => string | number): { [key: string]: number } {\n return events.reduce((counts, event) => {\n const mappedValue = mapper(event);\n if (!counts[mappedValue]) {\n counts[mappedValue] = 1;\n } else {\n counts[mappedValue] += 1;\n }\n return counts;\n }, {});\n}\n\nexport function tests() {\n return {\n countBy: assert => {\n const counts = countBy([{type: \"foo\"}, {type: \"bar\"}, {type: \"foo\"}], o => o.type);\n assert.equal(Object.keys(counts).length, 2);\n assert.equal(counts.foo, 2);\n assert.equal(counts.bar, 1);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {groupBy} from \"../utils/groupBy\";\n\n\nexport function makeTxnId() {\n return makeId(\"t\");\n}\n\nexport function makeId(prefix) {\n const n = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);\n const str = n.toString(16);\n return prefix + \"0\".repeat(14 - str.length) + str;\n}\n\nexport function isTxnId(txnId) {\n\treturn txnId.startsWith(\"t\") && txnId.length === 15;\n}\n\nexport function formatToDeviceMessagesPayload(messages) {\n const messagesByUser = groupBy(messages, message => message.device.user_id);\n const payload = {\n messages: Array.from(messagesByUser.entries()).reduce((userMap, [userId, messages]) => {\n userMap[userId] = messages.reduce((deviceMap, message) => {\n deviceMap[message.device.device_id] = message.content;\n return deviceMap;\n }, {});\n return userMap;\n }, {})\n };\n return payload;\n}\n\nexport function tests() {\n\treturn {\n\t\t\"isTxnId succeeds on result of makeTxnId\": assert => {\n\t\t\tassert(isTxnId(makeTxnId()));\n\t\t},\n\t\t\"isTxnId fails on event id\": assert => {\n\t\t\tassert(!isTxnId(\"$yS_n5n3cIO2aTtek0_2ZSlv-7g4YYR2zKrk2mFCW_rm\"));\n\t\t},\n\t}\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport type Disposable = IDisposable | (() => void);\n\nfunction disposeValue(value: Disposable): void {\n if (typeof value === \"function\") {\n value();\n } else {\n value.dispose();\n }\n}\n\nfunction isDisposable(value: Disposable): boolean {\n return value && (typeof value === \"function\" || typeof value.dispose === \"function\");\n}\n\nexport class Disposables {\n private _disposables?: Disposable[] = [];\n\n track(disposable: D): D {\n if (!isDisposable(disposable)) {\n throw new Error(\"Not a disposable\");\n }\n if (this.isDisposed) {\n console.warn(\"Disposables already disposed, disposing new value\");\n disposeValue(disposable);\n return disposable;\n }\n this._disposables!.push(disposable);\n return disposable;\n }\n\n untrack(disposable: Disposable): undefined {\n // already disposed\n if (!this._disposables) {\n return undefined;\n }\n const idx = this._disposables!.indexOf(disposable);\n if (idx >= 0) {\n this._disposables!.splice(idx, 1);\n }\n return undefined;\n }\n\n dispose(): void {\n if (this._disposables) {\n for (const d of this._disposables) {\n disposeValue(d);\n }\n this._disposables = undefined;\n }\n }\n\n get isDisposed(): boolean {\n return this._disposables === undefined;\n }\n\n disposeTracked(value: Disposable | undefined): undefined {\n if (value === undefined || value === null || this.isDisposed) {\n return undefined;\n }\n const idx = this._disposables!.indexOf(value);\n if (idx !== -1) {\n const [foundValue] = this._disposables!.splice(idx, 1);\n disposeValue(foundValue);\n } else {\n console.warn(\"disposable not found, did it leak?\", value);\n }\n return undefined;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {HomeServerApi} from \"../../../net/HomeServerApi\";\nimport type {DeviceTracker} from \"../../../e2ee/DeviceTracker.js\";\nimport type {ILogItem} from \"../../../../logging/types\";\nimport type {Clock} from \"../../../../platform/web/dom/Clock.js\";\nimport type {DeviceMessageHandler} from \"../../../DeviceMessageHandler.js\";\nimport type {IChannel} from \"./IChannel\";\nimport {messageFromErrorType} from \"./IChannel\";\nimport {makeTxnId} from \"../../../common.js\";\nimport {CancelReason, VerificationEventType} from \"./types\";\nimport {Disposables} from \"../../../../utils/Disposables\";\nimport {VerificationCancelledError} from \"../VerificationCancelledError\";\nimport {Deferred} from \"../../../../utils/Deferred\";\n\ntype Options = {\n hsApi: HomeServerApi;\n deviceTracker: DeviceTracker;\n otherUserId: string;\n clock: Clock;\n deviceMessageHandler: DeviceMessageHandler;\n log: ILogItem;\n ourUserDeviceId: string;\n}\n\nexport class ToDeviceChannel extends Disposables implements IChannel {\n private readonly hsApi: HomeServerApi;\n private readonly deviceTracker: DeviceTracker;\n private ourDeviceId: string;\n private readonly otherUserId: string;\n private readonly clock: Clock;\n private readonly deviceMessageHandler: DeviceMessageHandler;\n private readonly sentMessages: Map = new Map();\n private readonly receivedMessages: Map = new Map();\n private readonly waitMap: Map> = new Map();\n private readonly log: ILogItem;\n public otherUserDeviceId: string;\n public startMessage: any;\n public id: string;\n private _initiatedByUs: boolean;\n private _cancellation?: { code: CancelReason, cancelledByUs: boolean };\n\n /**\n * \n * @param startingMessage Create the channel with existing message in the receivedMessage buffer\n */\n constructor(options: Options, startingMessage?: any) {\n super();\n this.hsApi = options.hsApi;\n this.deviceTracker = options.deviceTracker;\n this.otherUserId = options.otherUserId;\n this.ourDeviceId = options.ourUserDeviceId;\n this.clock = options.clock;\n this.log = options.log;\n this.deviceMessageHandler = options.deviceMessageHandler;\n this.track(\n this.deviceMessageHandler.disposableOn(\n \"message\",\n async ({ unencrypted }) => {\n if (!unencrypted) {\n return;\n }\n await this.handleDeviceMessage(unencrypted);\n }\n )\n );\n this.track(() => {\n this.waitMap.forEach((value) => {\n value.reject(new VerificationCancelledError());\n });\n });\n // Copy over request message\n if (startingMessage) {\n /**\n * startingMessage may be the ready message or the start message.\n */\n this.id = startingMessage.content.transaction_id;\n this.receivedMessages.set(startingMessage.type, startingMessage);\n this.otherUserDeviceId = startingMessage.content.from_device;\n }\n }\n\n get cancellation(): IChannel[\"cancellation\"] {\n return this._cancellation;\n };\n\n get isCancelled(): boolean {\n return !!this._cancellation;\n }\n\n async send(eventType: VerificationEventType, content: any, log: ILogItem): Promise {\n await log.wrap(\"ToDeviceChannel.send\", async () => {\n if (this.isCancelled) {\n throw new VerificationCancelledError();\n }\n if (eventType === VerificationEventType.Request) {\n // Handle this case specially\n await this.handleRequestEventSpecially(eventType, content, log);\n return;\n }\n Object.assign(content, { transaction_id: this.id });\n const payload = {\n messages: {\n [this.otherUserId]: {\n [this.otherUserDeviceId]: content\n }\n }\n }\n await this.hsApi.sendToDevice(eventType, payload, makeTxnId(), { log }).response();\n this.sentMessages.set(eventType, {content});\n });\n }\n\n private async handleRequestEventSpecially(eventType: VerificationEventType, content: any, log: ILogItem) {\n await log.wrap(\"ToDeviceChannel.handleRequestEventSpecially\", async () => {\n const timestamp = this.clock.now();\n const txnId = makeTxnId();\n this.id = txnId;\n Object.assign(content, { timestamp, transaction_id: txnId });\n const payload = {\n messages: {\n [this.otherUserId]: {\n \"*\": content\n }\n }\n }\n await this.hsApi.sendToDevice(eventType, payload, makeTxnId(), { log }).response();\n this.sentMessages.set(eventType, {content});\n });\n }\n\n getReceivedMessage(event: VerificationEventType) {\n return this.receivedMessages.get(event);\n }\n\n getSentMessage(event: VerificationEventType) {\n return this.sentMessages.get(event);\n }\n\n get acceptMessage(): any {\n return this.receivedMessages.get(VerificationEventType.Accept) ??\n this.sentMessages.get(VerificationEventType.Accept);\n }\n\n\n private async handleDeviceMessage(event) {\n await this.log.wrap(\"ToDeviceChannel.handleDeviceMessage\", async (log) => {\n if (!event.type.startsWith(\"m.key.verification.\")) {\n return;\n }\n if (event.content.transaction_id !== this.id) {\n /**\n * When a device receives an unknown transaction_id, it should send an appropriate\n * m.key.verification.cancel message to the other device indicating as such.\n * This does not apply for inbound m.key.verification.start or m.key.verification.cancel messages.\n */\n await this.cancelVerification(CancelReason.UnknownTransaction);\n return;\n }\n this.resolveAnyWaits(event);\n this.receivedMessages.set(event.type, event);\n if (event.type === VerificationEventType.Ready) {\n this.handleReadyMessage(event, log);\n return;\n }\n if (event.type === VerificationEventType.Cancel) {\n this._cancellation = { code: event.content.code, cancelledByUs: false };\n this.dispose();\n return;\n }\n });\n }\n\n private async handleReadyMessage(event, log: ILogItem) {\n const fromDevice = event.content.from_device;\n this.otherUserDeviceId = fromDevice;\n // We need to send cancel messages to all other devices\n const devices = await this.deviceTracker.devicesForUsers([this.otherUserId], this.hsApi, log);\n const otherDevices = devices.filter(device => device.device_id !== fromDevice && device.device_id !== this.ourDeviceId);\n const cancelMessage = {\n code: CancelReason.OtherDeviceAccepted,\n reason: messageFromErrorType[CancelReason.OtherDeviceAccepted],\n transaction_id: this.id,\n };\n const deviceMessages = otherDevices.reduce((acc, device) => { acc[device.device_id] = cancelMessage; return acc; }, {});\n const payload = {\n messages: {\n [this.otherUserId]: deviceMessages\n }\n }\n await this.hsApi.sendToDevice(VerificationEventType.Cancel, payload, makeTxnId(), { log }).response();\n }\n\n async cancelVerification(cancellationType: CancelReason) {\n await this.log.wrap(\"Channel.cancelVerification\", async log => {\n if (this.isCancelled) {\n throw new VerificationCancelledError();\n }\n const payload = {\n messages: {\n [this.otherUserId]: {\n [this.otherUserDeviceId ?? \"*\"]: {\n code: cancellationType,\n reason: messageFromErrorType[cancellationType],\n transaction_id: this.id,\n }\n }\n }\n }\n await this.hsApi.sendToDevice(VerificationEventType.Cancel, payload, makeTxnId(), { log }).response();\n this._cancellation = { code: cancellationType, cancelledByUs: true };\n this.dispose();\n });\n }\n\n private resolveAnyWaits(event) {\n const { type } = event;\n const wait = this.waitMap.get(type);\n if (wait) {\n wait.resolve(event);\n this.waitMap.delete(type);\n }\n }\n\n waitForEvent(eventType: VerificationEventType): Promise {\n if (this.isCancelled) {\n throw new VerificationCancelledError();\n }\n // Check if we already received the message\n const receivedMessage = this.receivedMessages.get(eventType);\n if (receivedMessage) {\n return Promise.resolve(receivedMessage);\n }\n // Check if we're already waiting for this message\n const existingWait = this.waitMap.get(eventType);\n if (existingWait) {\n return existingWait.promise;\n }\n const deferred = new Deferred(); \n this.waitMap.set(eventType, deferred);\n return deferred.promise;\n }\n\n setStartMessage(event) {\n this.startMessage = event;\n this._initiatedByUs = event.content.from_device === this.ourDeviceId;\n }\n\n get initiatedByUs(): boolean {\n return this._initiatedByUs;\n };\n} \n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {ILogItem} from \"../../../../logging/types\";\nimport type {IChannel} from \"./IChannel\";\nimport type {Room} from \"../../../room/Room.js\";\nimport type {EventEntry} from \"../../../room/timeline/entries/EventEntry.js\";\nimport {messageFromErrorType} from \"./IChannel\";\nimport {CancelReason, VerificationEventType} from \"./types\";\nimport {Disposables} from \"../../../../utils/Disposables\";\nimport {VerificationCancelledError} from \"../VerificationCancelledError\";\nimport {Deferred} from \"../../../../utils/Deferred\";\nimport {getRelatedEventId, createReference} from \"../../../room/timeline/relations.js\";\n\ntype Options = {\n otherUserId: string;\n ourUserId: string;\n log: ILogItem;\n ourUserDeviceId: string;\n room: Room;\n}\n\nexport class RoomChannel extends Disposables implements IChannel {\n private ourDeviceId: string;\n private readonly otherUserId: string;\n private readonly sentMessages: Map = new Map();\n private readonly receivedMessages: Map = new Map();\n private readonly waitMap: Map> = new Map();\n private readonly log: ILogItem;\n private readonly room: Room;\n private readonly ourUserId: string;\n public otherUserDeviceId: string;\n public startMessage: any;\n /**\n * This is the event-id of the starting message (request/start)\n */\n public id: string;\n private _initiatedByUs: boolean;\n private _cancellation?: { code: CancelReason, cancelledByUs: boolean };\n\n /**\n * \n * @param startingMessage Create the channel with existing message in the receivedMessage buffer\n */\n constructor(options: Options, startingMessage?: any) {\n super();\n this.otherUserId = options.otherUserId;\n this.ourUserId = options.ourUserId;\n this.ourDeviceId = options.ourUserDeviceId;\n this.log = options.log;\n this.room = options.room;\n this.subscribeToTimeline();\n this.track(() => {\n this.waitMap.forEach((value) => {\n value.reject(new VerificationCancelledError());\n });\n });\n // Copy over request message\n if (startingMessage) {\n /**\n * startingMessage may be the ready message or the start message.\n */\n this.id = startingMessage.id;\n const type = startingMessage.content?.msgtype ?? startingMessage.eventType;\n this.receivedMessages.set(type, startingMessage);\n this.otherUserDeviceId = startingMessage.content.from_device;\n }\n }\n\n private async subscribeToTimeline() {\n const timeline = await this.room.openTimeline();\n this.track(() => timeline.release());\n this.track(\n timeline.entries.subscribe({\n onAdd: async (_, entry: EventEntry) => {\n this.handleRoomMessage(entry);\n },\n onRemove: () => { /** noop */ },\n onUpdate: () => { /** noop */ },\n })\n );\n }\n\n get cancellation(): IChannel[\"cancellation\"] {\n return this._cancellation;\n };\n\n get isCancelled(): boolean {\n return !!this._cancellation;\n }\n\n async send(eventType: VerificationEventType, content: any, log: ILogItem): Promise {\n await log.wrap(\"RoomChannel.send\", async (_log) => {\n if (this.isCancelled) {\n throw new VerificationCancelledError();\n }\n if (eventType === VerificationEventType.Request) {\n // Handle this case specially\n await this.handleRequestEventSpecially(eventType, content, log);\n return;\n }\n if (!this.id) {\n /**\n * This might happen if the user cancelled the verification from the UI,\n * but no verification messages were yet sent (maybe because the keys are\n * missing etc..).\n */\n return;\n }\n await this.room.ensureMessageKeyIsShared(_log);\n Object.assign(content, createReference(this.id));\n await this.room.sendEvent(eventType, content, undefined, log);\n this.sentMessages.set(eventType, {content});\n });\n }\n\n private async handleRequestEventSpecially(eventType: VerificationEventType, content: any, log: ILogItem) {\n await log.wrap(\"RoomChannel.handleRequestEventSpecially\", async () => {\n Object.assign(content, {\n body: `${this.otherUserId} 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.`,\n msgtype: VerificationEventType.Request,\n to: this.otherUserId,\n });\n const pendingEvent = await this.room.sendEvent(\"m.room.message\", content, undefined, log);\n this.id = await pendingEvent.getRemoteId();\n this.sentMessages.set(eventType, {content});\n });\n }\n\n getReceivedMessage(event: VerificationEventType) {\n return this.receivedMessages.get(event);\n }\n\n getSentMessage(event: VerificationEventType) {\n return this.sentMessages.get(event);\n }\n\n get acceptMessage(): any {\n return this.receivedMessages.get(VerificationEventType.Accept) ??\n this.sentMessages.get(VerificationEventType.Accept);\n }\n\n private async handleRoomMessage(entry: EventEntry) {\n const type = entry.content?.msgtype ?? entry.eventType;\n if (!type?.startsWith(\"m.key.verification\") ||\n entry.sender === this.ourUserId ||\n entry.isLoadedFromStorage) {\n return; \n }\n await this.log.wrap(\"RoomChannel.handleRoomMessage\", async (log) => {\n if (!this.id) {\n throw new Error(\"Couldn't find event-id of request message!\");\n }\n if (getRelatedEventId(entry.event) !== this.id) {\n /**\n * When a device receives an unknown transaction_id, it should send an appropriate\n * m.key.verification.cancel message to the other device indicating as such.\n * This does not apply for inbound m.key.verification.start or m.key.verification.cancel messages.\n */\n await this.cancelVerification(CancelReason.UnknownTransaction);\n return;\n }\n this.resolveAnyWaits(entry);\n this.receivedMessages.set(entry.eventType, entry);\n if (entry.eventType === VerificationEventType.Ready) {\n const fromDevice = entry.content.from_device;\n this.otherUserDeviceId = fromDevice;\n return;\n }\n if (entry.eventType === VerificationEventType.Cancel) {\n this._cancellation = { code: entry.content.code, cancelledByUs: false };\n this.dispose();\n return;\n }\n });\n }\n\n async cancelVerification(cancellationType: CancelReason) {\n await this.log.wrap(\"RoomChannel.cancelVerification\", async log => {\n log.log({ reason: messageFromErrorType[cancellationType] });\n if (this.isCancelled) {\n throw new VerificationCancelledError();\n }\n const content = {\n code: cancellationType,\n reason: messageFromErrorType[cancellationType],\n }\n await this.send(VerificationEventType.Cancel, content, log);\n this._cancellation = { code: cancellationType, cancelledByUs: true };\n this.dispose();\n });\n }\n\n private resolveAnyWaits(entry: EventEntry) {\n const { eventType } = entry;\n const wait = this.waitMap.get(eventType);\n if (wait) {\n wait.resolve(entry);\n this.waitMap.delete(eventType);\n }\n }\n\n waitForEvent(eventType: VerificationEventType): Promise {\n if (this.isCancelled) {\n throw new VerificationCancelledError();\n }\n // Check if we already received the message\n const receivedMessage = this.receivedMessages.get(eventType);\n if (receivedMessage) {\n return Promise.resolve(receivedMessage);\n }\n // Check if we're already waiting for this message\n const existingWait = this.waitMap.get(eventType);\n if (existingWait) {\n return existingWait.promise;\n }\n const deferred = new Deferred(); \n this.waitMap.set(eventType, deferred);\n return deferred.promise;\n }\n\n setStartMessage(entry) {\n if (!entry.content[\"m.relates_to\"]) {\n const clone = entry.clone();\n clone.content[\"m.relates_to\"] = clone.event.content[\"m.relates_to\"];\n this.startMessage = clone;\n }\n else {\n this.startMessage = entry;\n }\n this._initiatedByUs = entry.content.from_device === this.ourDeviceId;\n }\n\n get initiatedByUs(): boolean {\n return this._initiatedByUs;\n };\n} \n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {CrossSigning} from \"../CrossSigning\";\nimport type {Room} from \"../../room/Room.js\";\nimport type {ILogItem} from \"../../../logging/types\";\n\nexport class SASRequest {\n constructor(public readonly startingMessage: any) {}\n\n get deviceId(): string {\n return this.startingMessage.content.from_device;\n }\n\n get sender(): string {\n return this.startingMessage.sender;\n }\n\n get id(): string {\n return this.startingMessage.content.transaction_id ?? this.startingMessage.eventId;\n }\n\n async reject(crossSigning: CrossSigning, room: Room, log: ILogItem): Promise {\n const sas = crossSigning.startVerification(this, room, log);\n await sas?.abort();\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {verifyEd25519Signature, SignatureVerification} from \"../e2ee/common\";\nimport {BaseObservableValue, RetainedObservableValue} from \"../../observable/value\";\nimport {pkSign} from \"./common\";\nimport {SASVerification} from \"./SAS/SASVerification\";\nimport {ToDeviceChannel} from \"./SAS/channel/ToDeviceChannel\";\nimport {RoomChannel} from \"./SAS/channel/RoomChannel\";\nimport {VerificationEventType} from \"./SAS/channel/types\";\nimport {ObservableMap} from \"../../observable/map\";\nimport {SASRequest} from \"./SAS/SASRequest\";\nimport {SecretFetcher} from \"../ssss\";\nimport type {Storage} from \"../storage/idb/Storage\";\nimport type {Platform} from \"../../platform/web/Platform\";\nimport type {DeviceTracker} from \"../e2ee/DeviceTracker\";\nimport type {HomeServerApi} from \"../net/HomeServerApi\";\nimport type {Account} from \"../e2ee/Account\";\nimport type {ILogItem} from \"../../logging/types\";\nimport type {DeviceMessageHandler} from \"../DeviceMessageHandler.js\";\nimport type {SignedValue, DeviceKey} from \"../e2ee/common\";\nimport type {Room} from \"../room/Room.js\";\nimport type {IChannel} from \"./SAS/channel/IChannel\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\n\ntype Olm = typeof OlmNamespace;\n\n// we store cross-signing (and device) keys in the format we get them from the server\n// as that is what the signature is calculated on, so to verify and sign, we need\n// it in this format anyway.\nexport type CrossSigningKey = SignedValue & {\n readonly user_id: string;\n readonly usage: ReadonlyArray;\n readonly keys: {[keyId: string]: string};\n}\n\nexport enum KeyUsage {\n Master = \"master\",\n SelfSigning = \"self_signing\",\n UserSigning = \"user_signing\"\n};\n\nexport enum UserTrust {\n /** We trust the user, the whole signature chain checks out from our MSK to all of their device keys. */\n Trusted = 1,\n /** We haven't signed this user's identity yet. Verify this user first to sign it. */\n UserNotSigned,\n /** We have signed the user already, but the signature isn't valid.\n One possible cause could be that an attacker is uploading signatures in our name. */\n UserSignatureMismatch,\n /** We trust the user, but they don't trust one of their devices. */\n UserDeviceNotSigned,\n /** We trust the user, but the signatures of one of their devices is invalid.\n * One possible cause could be that an attacker is uploading signatures in their name. */\n UserDeviceSignatureMismatch,\n /** The user doesn't have a valid signature for the SSK with their MSK, or the SSK is missing.\n * This likely means bootstrapping cross-signing on their end didn't finish correctly. */\n UserSetupError,\n /** We don't have a valid signature for our SSK with our MSK, the SSK is missing, or we don't trust our own MSK.\n * This likely means bootstrapping cross-signing on our end didn't finish correctly. */\n OwnSetupError\n}\n\nenum MSKVerification {\n NoPrivKey,\n NoPubKey,\n DerivedPubKeyMismatch,\n Valid\n}\n\nexport interface IVerificationMethod {\n verify(): Promise;\n otherDeviceId: string;\n otherUserId: string;\n}\n\nexport class CrossSigning {\n private readonly storage: Storage;\n private readonly secretFetcher: SecretFetcher;\n private readonly platform: Platform;\n private readonly deviceTracker: DeviceTracker;\n private readonly olm: Olm;\n private readonly olmUtil: Olm.Utility;\n private readonly hsApi: HomeServerApi;\n private readonly ownUserId: string;\n private readonly e2eeAccount: Account;\n private readonly deviceMessageHandler: DeviceMessageHandler;\n private _isMasterKeyTrusted: boolean = false;\n private readonly observedUsers: Map> = new Map();\n private readonly deviceId: string;\n private sasVerificationInProgress?: SASVerification;\n public receivedSASVerifications: ObservableMap = new ObservableMap();\n\n constructor(options: {\n storage: Storage,\n secretFetcher: SecretFetcher,\n deviceTracker: DeviceTracker,\n platform: Platform,\n olm: Olm,\n olmUtil: Olm.Utility,\n ownUserId: string,\n deviceId: string,\n hsApi: HomeServerApi,\n e2eeAccount: Account,\n deviceMessageHandler: DeviceMessageHandler,\n }) {\n this.storage = options.storage;\n this.secretFetcher = options.secretFetcher;\n this.platform = options.platform;\n this.deviceTracker = options.deviceTracker;\n this.olm = options.olm;\n this.olmUtil = options.olmUtil;\n this.hsApi = options.hsApi;\n this.ownUserId = options.ownUserId;\n this.deviceId = options.deviceId;\n this.e2eeAccount = options.e2eeAccount\n this.deviceMessageHandler = options.deviceMessageHandler;\n this.handleSASDeviceMessage = this.handleSASDeviceMessage.bind(this);\n this.deviceMessageHandler.on(\"message\", this.handleSASDeviceMessage);\n }\n\n /** @return {boolean} whether cross signing has been enabled on this account */\n async load(log: ILogItem): Promise {\n // try to verify the msk without accessing the network\n const verification = await this.verifyMSKFrom4S(false, log);\n return verification !== MSKVerification.NoPrivKey;\n }\n\n async start(log: ILogItem): Promise {\n if (!this.isMasterKeyTrusted) {\n // try to verify the msk _with_ access to the network\n await this.verifyMSKFrom4S(true, log);\n }\n }\n\n private async verifyMSKFrom4S(allowNetwork: boolean, log: ILogItem): Promise {\n return await log.wrap(\"CrossSigning.verifyMSKFrom4S\", async log => {\n // TODO: use errorboundary here\n const privateMasterKey = await this.getSigningKey(KeyUsage.Master);\n if (!privateMasterKey) {\n log.set(\"failure\", \"no_priv_msk\");\n return MSKVerification.NoPrivKey;\n }\n const signing = new this.olm.PkSigning();\n let derivedPublicKey;\n try {\n derivedPublicKey = signing.init_with_seed(privateMasterKey); \n } finally {\n signing.free();\n }\n const publishedMasterKey = await this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId, KeyUsage.Master, allowNetwork ? this.hsApi : undefined, log);\n if (!publishedMasterKey) {\n log.set(\"failure\", \"no_pub_msk\");\n return MSKVerification.NoPubKey;\n }\n const publisedEd25519Key = publishedMasterKey && getKeyEd25519Key(publishedMasterKey);\n log.set({publishedMasterKey: publisedEd25519Key, derivedPublicKey});\n this._isMasterKeyTrusted = !!publisedEd25519Key && publisedEd25519Key === derivedPublicKey;\n if (!this._isMasterKeyTrusted) {\n log.set(\"failure\", \"mismatch\");\n return MSKVerification.DerivedPubKeyMismatch;\n }\n return MSKVerification.Valid;\n });\n }\n\n get isMasterKeyTrusted(): boolean {\n return this._isMasterKeyTrusted;\n }\n\n startVerification(requestOrUserId: SASRequest, logOrRoom: ILogItem): SASVerification | undefined;\n startVerification(requestOrUserId: string, logOrRoom: ILogItem): SASVerification | undefined;\n startVerification(requestOrUserId: SASRequest, logOrRoom: Room, _log: ILogItem): SASVerification | undefined;\n startVerification(requestOrUserId: string, logOrRoom: Room, _log: ILogItem): SASVerification | undefined;\n startVerification(requestOrUserId: string | SASRequest, logOrRoom: Room | ILogItem, _log?: ILogItem): SASVerification | undefined {\n const log: ILogItem = _log ?? logOrRoom;\n if (this.sasVerificationInProgress && !this.sasVerificationInProgress.finished) {\n log.log({ sasVerificationAlreadyInProgress: true });\n return;\n }\n const otherUserId = requestOrUserId instanceof SASRequest ? requestOrUserId.sender : requestOrUserId;\n const startingMessage = requestOrUserId instanceof SASRequest ? requestOrUserId.startingMessage : undefined;\n let channel: IChannel;\n if (otherUserId === this.ownUserId) {\n channel = new ToDeviceChannel({\n deviceTracker: this.deviceTracker,\n hsApi: this.hsApi,\n otherUserId,\n clock: this.platform.clock,\n deviceMessageHandler: this.deviceMessageHandler,\n ourUserDeviceId: this.deviceId,\n log\n }, startingMessage);\n }\n else {\n channel = new RoomChannel({\n room: logOrRoom,\n otherUserId,\n ourUserId: this.ownUserId,\n ourUserDeviceId: this.deviceId,\n log,\n }, startingMessage);\n }\n\n this.sasVerificationInProgress = new SASVerification({\n olm: this.olm,\n olmUtil: this.olmUtil,\n ourUserId: this.ownUserId,\n ourUserDeviceId: this.deviceId,\n otherUserId,\n log,\n channel,\n e2eeAccount: this.e2eeAccount,\n deviceTracker: this.deviceTracker,\n hsApi: this.hsApi,\n clock: this.platform.clock,\n });\n return this.sasVerificationInProgress;\n }\n\n private async handleSASDeviceMessage({ unencrypted: event }) {\n if (!event ||\n (event.type !== VerificationEventType.Request && event.type !== VerificationEventType.Start)\n ) {\n return;\n }\n await this.platform.logger.run(\"CrossSigning.handleSASDeviceMessage\", async log => {\n const txnId = event.content.transaction_id;\n const fromDevice = event.content.from_device;\n const fromUser = event.sender;\n if (!fromDevice || fromUser !== this.ownUserId) {\n /**\n * SAS verification may be started with a request or a start message but\n * both should contain a from_device.\n */\n return;\n }\n if (!await this.areWeVerified(log)) {\n /**\n * If we're not verified, then the other device MUST be verified.\n * We check this so that verification between two unverified devices\n * never happen!\n */\n const device = await this.deviceTracker.deviceForId(this.ownUserId, fromDevice, this.hsApi, log);\n if (!device || !await this.isOurUserDeviceTrusted(device!, log)) {\n return;\n }\n }\n /**\n * If we receive an event for the current/previously finished \n * SAS verification, we should ignore it because the device channel\n * object (who also listens for to_device messages) will take care of it (if needed).\n */\n const shouldIgnoreEvent = this.sasVerificationInProgress?.channel.id === txnId;\n if (shouldIgnoreEvent) { return; }\n /**\n * 1. If we receive the cancel message, we need to update the requests map.\n * 2. If we receive an starting message (viz request/start), we need to create the SASRequest from it.\n */\n switch (event.type) {\n case VerificationEventType.Cancel: \n this.receivedSASVerifications.remove(txnId);\n return;\n case VerificationEventType.Request:\n case VerificationEventType.Start:\n this.platform.logger.run(\"Create SASRequest\", () => {\n this.receivedSASVerifications.set(txnId, new SASRequest(event));\n });\n return;\n default:\n // we don't care about this event!\n return;\n }\n });\n }\n\n /** returns our own device key signed by our self-signing key. Other signatures will be missing. */\n async signOwnDevice(log: ILogItem): Promise {\n return log.wrap(\"CrossSigning.signOwnDevice\", async log => {\n if (!this._isMasterKeyTrusted) {\n log.set(\"mskNotTrusted\", true);\n return;\n }\n const ownDeviceKey = this.e2eeAccount.getUnsignedDeviceKey() as DeviceKey;\n return this.signDeviceKey(ownDeviceKey, log);\n });\n }\n\n /** @return the signed device key for the given device id */\n async signDevice(verification: IVerificationMethod, log: ILogItem): Promise {\n return log.wrap(\"CrossSigning.signDevice\", async log => {\n if (!this._isMasterKeyTrusted) {\n /**\n * If we're the unverified device that is participating in\n * the verification process, it is expected that we do not\n * have access to the private part of MSK and thus\n * cannot determine if the MSK is trusted. In this case, we\n * do not need to sign anything because the other (verified)\n * device will sign our device key with the SSK.\n */\n log.set(\"mskNotTrusted\", true);\n }\n const shouldSign = await verification.verify() && this._isMasterKeyTrusted;\n log.set(\"shouldSign\", shouldSign);\n if (!shouldSign) {\n return; \n }\n const deviceId = verification.otherDeviceId;\n log.set(\"id\", deviceId);\n const keyToSign = await this.deviceTracker.deviceForId(this.ownUserId, deviceId, this.hsApi, log);\n if (!keyToSign) {\n return undefined;\n }\n delete keyToSign.signatures;\n return this.signDeviceKey(keyToSign, log);\n });\n }\n\n /** @return the signed MSK for the given user id */\n async signUser(verification: IVerificationMethod, log: ILogItem): Promise {\n return log.wrap(\"CrossSigning.signUser\", async log => {\n const userId = verification.otherUserId;\n log.set(\"id\", userId);\n if (!this._isMasterKeyTrusted) {\n log.set(\"mskNotTrusted\", true);\n return;\n }\n // can't sign own user\n if (userId === this.ownUserId) {\n return;\n }\n const shouldSign = await verification.verify();\n log.set(\"shouldSign\", shouldSign);\n if (!shouldSign) {\n return; \n }\n const keyToSign = await this.deviceTracker.getCrossSigningKeyForUser(userId, KeyUsage.Master, this.hsApi, log);\n if (!keyToSign) {\n return;\n }\n const signingKey = await this.getSigningKey(KeyUsage.UserSigning);\n if (!signingKey) {\n return;\n }\n delete keyToSign.signatures;\n // add signature to keyToSign\n this.signKey(keyToSign, signingKey);\n const payload = {\n [keyToSign.user_id]: {\n [getKeyEd25519Key(keyToSign)!]: keyToSign\n }\n };\n const request = this.hsApi.uploadSignatures(payload, {log});\n await request.response();\n // we don't write the signatures to storage, as we don't want to have too many special\n // cases in the trust algorithm, so instead we just clear the cross signing keys\n // so that they will be refetched when trust is recalculated\n await this.deviceTracker.invalidateUserKeys(userId);\n this.emitUserTrustUpdate(userId, log);\n return keyToSign;\n });\n }\n\n async isOurUserDeviceTrusted(device: DeviceKey, log?: ILogItem): Promise {\n return await this.platform.logger.wrapOrRun(log, \"CrossSigning.isOurUserDeviceTrusted\", async (_log) => {\n const ourSSK = await this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId, KeyUsage.SelfSigning, this.hsApi, _log);\n if (!ourSSK) {\n return false;\n }\n const verification = this.hasValidSignatureFrom(device, ourSSK, _log);\n if (verification === SignatureVerification.Valid) {\n return true;\n }\n return false;\n });\n }\n\n areWeVerified(log?: ILogItem): Promise {\n return this.platform.logger.wrapOrRun(log, \"CrossSigning.areWeVerified\", async (_log) => {\n const device = await this.deviceTracker.deviceForId(this.ownUserId, this.deviceId, this.hsApi, _log);\n return this.isOurUserDeviceTrusted(device!, log);\n }); \n }\n\n getUserTrust(userId: string, log: ILogItem): Promise {\n return log.wrap(\"CrossSigning.getUserTrust\", async log => {\n log.set(\"id\", userId);\n const logResult = (trust: UserTrust): UserTrust => {\n log.set(\"result\", trust);\n return trust;\n };\n if (!this.isMasterKeyTrusted) {\n return logResult(UserTrust.OwnSetupError);\n }\n const ourMSK = await log.wrap(\"get our msk\", log => this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId, KeyUsage.Master, this.hsApi, log));\n if (!ourMSK) {\n return logResult(UserTrust.OwnSetupError);\n }\n const ourUSK = await log.wrap(\"get our usk\", log => this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId, KeyUsage.UserSigning, this.hsApi, log));\n if (!ourUSK) {\n return logResult(UserTrust.OwnSetupError);\n }\n const ourUSKVerification = log.wrap(\"verify our usk\", log => this.hasValidSignatureFrom(ourUSK, ourMSK, log));\n if (ourUSKVerification !== SignatureVerification.Valid) {\n return logResult(UserTrust.OwnSetupError);\n }\n const theirMSK = await log.wrap(\"get their msk\", log => this.deviceTracker.getCrossSigningKeyForUser(userId, KeyUsage.Master, this.hsApi, log));\n if (!theirMSK) {\n /* assume that when they don't have an MSK, they've never enabled cross-signing on their client\n (or it's not supported) rather than assuming a setup error on their side.\n Later on, for their SSK, we _do_ assume it's a setup error as it doesn't make sense to have an MSK without a SSK */\n return logResult(UserTrust.UserNotSigned);\n }\n const theirMSKVerification = log.wrap(\"verify their msk\", log => this.hasValidSignatureFrom(theirMSK, ourUSK, log));\n if (theirMSKVerification !== SignatureVerification.Valid) {\n if (theirMSKVerification === SignatureVerification.NotSigned) {\n return logResult(UserTrust.UserNotSigned);\n } else { /* SignatureVerification.Invalid */\n return logResult(UserTrust.UserSignatureMismatch);\n }\n }\n const theirSSK = await log.wrap(\"get their ssk\", log => this.deviceTracker.getCrossSigningKeyForUser(userId, KeyUsage.SelfSigning, this.hsApi, log));\n if (!theirSSK) {\n return logResult(UserTrust.UserSetupError);\n }\n const theirSSKVerification = log.wrap(\"verify their ssk\", log => this.hasValidSignatureFrom(theirSSK, theirMSK, log));\n if (theirSSKVerification !== SignatureVerification.Valid) {\n return logResult(UserTrust.UserSetupError);\n }\n const theirDeviceKeys = await log.wrap(\"get their devices\", log => this.deviceTracker.devicesForUsers([userId], this.hsApi, log));\n const lowestDeviceVerification = theirDeviceKeys.reduce((lowest, dk) => log.wrap({l: \"verify device\", id: dk.device_id}, log => {\n const verification = this.hasValidSignatureFrom(dk, theirSSK, log);\n // first Invalid, then NotSigned, then Valid\n if (lowest === SignatureVerification.Invalid || verification === SignatureVerification.Invalid) {\n return SignatureVerification.Invalid;\n } else if (lowest === SignatureVerification.NotSigned || verification === SignatureVerification.NotSigned) {\n return SignatureVerification.NotSigned;\n } else if (lowest === SignatureVerification.Valid || verification === SignatureVerification.Valid) {\n return SignatureVerification.Valid;\n }\n // should never happen as we went over all the enum options\n return SignatureVerification.Invalid;\n }), SignatureVerification.Valid);\n if (lowestDeviceVerification !== SignatureVerification.Valid) {\n if (lowestDeviceVerification === SignatureVerification.NotSigned) {\n return logResult(UserTrust.UserDeviceNotSigned);\n } else { /* SignatureVerification.Invalid */\n return logResult(UserTrust.UserDeviceSignatureMismatch);\n }\n }\n return logResult(UserTrust.Trusted);\n });\n }\n\n dispose(): void {\n this.deviceMessageHandler.off(\"message\", this.handleSASDeviceMessage);\n }\n\n observeUserTrust(userId: string, log: ILogItem): BaseObservableValue {\n const existingValue = this.observedUsers.get(userId);\n if (existingValue) {\n return existingValue;\n }\n const observable = new RetainedObservableValue(undefined, () => {\n this.observedUsers.delete(userId);\n });\n this.observedUsers.set(userId, observable);\n log.wrapDetached(\"get user trust\", async log => {\n if (observable.get() === undefined) {\n observable.set(await this.getUserTrust(userId, log));\n }\n });\n return observable;\n }\n\n private async signDeviceKey(keyToSign: DeviceKey, log: ILogItem): Promise {\n const signingKey = await this.getSigningKey(KeyUsage.SelfSigning);\n if (!signingKey) {\n return undefined;\n }\n // add signature to keyToSign\n this.signKey(keyToSign, signingKey);\n // so the payload format of a signature is a map from userid to key id of the signed key\n // (without the algoritm prefix though according to example, e.g. just device id or base 64 public key)\n // to the complete signed key with the signature of the signing key in the signatures section.\n const payload = {\n [keyToSign.user_id]: {\n [keyToSign.device_id]: keyToSign\n }\n };\n const request = this.hsApi.uploadSignatures(payload, {log});\n await request.response();\n // we don't write the signatures to storage, as we don't want to have too many special\n // cases in the trust algorithm, so instead we just clear the device keys\n // so that they will be refetched when trust is recalculated\n await this.deviceTracker.invalidateUserKeys(this.ownUserId);\n this.emitUserTrustUpdate(this.ownUserId, log);\n return keyToSign;\n }\n\n private async getSigningKey(usage: KeyUsage): Promise {\n const seedStr = await this.secretFetcher.getSecret(`m.cross_signing.${usage}`);\n if (seedStr) {\n return new Uint8Array(this.platform.encoding.base64.decode(seedStr));\n }\n }\n\n private signKey(keyToSign: DeviceKey | CrossSigningKey, signingKey: Uint8Array) {\n pkSign(this.olm, keyToSign, signingKey, this.ownUserId, \"\");\n }\n\n private hasValidSignatureFrom(key: DeviceKey | CrossSigningKey, signingKey: CrossSigningKey, log: ILogItem): SignatureVerification {\n const pubKey = getKeyEd25519Key(signingKey);\n if (!pubKey) {\n return SignatureVerification.NotSigned;\n }\n return verifyEd25519Signature(this.olmUtil, signingKey.user_id, pubKey, pubKey, key, log);\n }\n\n private emitUserTrustUpdate(userId: string, log: ILogItem) {\n const observable = this.observedUsers.get(userId);\n if (observable && observable.get() !== undefined) {\n observable.set(undefined);\n log.wrapDetached(\"update user trust\", async log => {\n observable.set(await this.getUserTrust(userId, log));\n });\n }\n }\n}\n\nexport function getKeyUsage(keyInfo: CrossSigningKey): KeyUsage | undefined {\n if (!Array.isArray(keyInfo.usage) || keyInfo.usage.length !== 1) {\n return undefined;\n }\n const usage = keyInfo.usage[0];\n if (usage !== KeyUsage.Master && usage !== KeyUsage.SelfSigning && usage !== KeyUsage.UserSigning) {\n return undefined;\n }\n return usage;\n}\n\nconst algorithm = \"ed25519\";\nconst prefix = `${algorithm}:`;\n\nexport function getKeyEd25519Key(keyInfo: CrossSigningKey): string | undefined {\n const ed25519KeyIds = Object.keys(keyInfo.keys).filter(keyId => keyId.startsWith(prefix));\n if (ed25519KeyIds.length !== 1) {\n return undefined;\n }\n const keyId = ed25519KeyIds[0];\n const publicKey = keyInfo.keys[keyId];\n return publicKey;\n}\n\nexport function getKeyUserId(keyInfo: CrossSigningKey): string | undefined {\n return keyInfo[\"user_id\"];\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {verifyEd25519Signature, getEd25519Signature, SIGNATURE_ALGORITHM, SignatureVerification} from \"./common\";\nimport {HistoryVisibility, shouldShareKey, DeviceKey, getDeviceEd25519Key, getDeviceCurve25519Key} from \"./common\";\nimport {RoomMember} from \"../room/members/RoomMember.js\";\nimport {getKeyUsage, getKeyEd25519Key, getKeyUserId, KeyUsage} from \"../verification/CrossSigning\";\nimport {MemberChange} from \"../room/members/RoomMember\";\nimport type {CrossSigningKey} from \"../verification/CrossSigning\";\nimport type {HomeServerApi} from \"../net/HomeServerApi\";\nimport type {ObservableMap} from \"../../observable/map\";\nimport type {Room} from \"../room/Room\";\nimport type {ILogItem} from \"../../logging/types\";\nimport type {Storage} from \"../storage/idb/Storage\";\nimport type {Transaction} from \"../storage/idb/Transaction\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\n// tracking status for cross-signing and device keys\nexport enum KeysTrackingStatus {\n Outdated = 0,\n UpToDate = 1\n}\n\nexport type UserIdentity = {\n userId: string,\n roomIds: string[],\n keysTrackingStatus: KeysTrackingStatus,\n}\n\nfunction createUserIdentity(userId: string, initialRoomId?: string): UserIdentity {\n return {\n userId: userId,\n roomIds: initialRoomId ? [initialRoomId] : [],\n keysTrackingStatus: KeysTrackingStatus.Outdated,\n };\n}\n\nfunction addRoomToIdentity(identity: UserIdentity | undefined, userId: string, roomId: string): UserIdentity | undefined {\n if (!identity) {\n identity = createUserIdentity(userId, roomId);\n return identity;\n } else {\n if (!identity.roomIds.includes(roomId)) {\n identity.roomIds.push(roomId);\n return identity;\n }\n }\n}\n\nexport class DeviceTracker {\n private readonly _storage: Storage;\n private readonly _getSyncToken: () => string;\n private readonly _olmUtil: Olm.Utility;\n private readonly _ownUserId: string;\n private readonly _ownDeviceId: string;\n\n constructor(options: {storage: Storage, getSyncToken: () => string, olmUtil: Olm.Utility, ownUserId: string, ownDeviceId: string}) {\n this._storage = options.storage;\n this._getSyncToken = options.getSyncToken;\n this._olmUtil = options.olmUtil;\n this._ownUserId = options.ownUserId;\n this._ownDeviceId = options.ownDeviceId;\n }\n\n async writeDeviceChanges(changedUserIds: ReadonlyArray, txn: Transaction, log: ILogItem): Promise {\n const {userIdentities} = txn;\n // TODO: should we also look at left here to handle this?:\n // the usual problem here is that you share a room with a user,\n // go offline, the remote user leaves the room, changes their devices,\n // then rejoins the room you share (or another room).\n // At which point you come online, all of this happens in the gap, \n // and you don't notice that they ever left, \n // and so the client doesn't invalidate their device cache for the user\n log.set(\"changed\", changedUserIds.length);\n await Promise.all(changedUserIds.map(async userId => {\n const user = await userIdentities.get(userId);\n if (user) {\n log.log({l: \"outdated\", id: userId});\n user.keysTrackingStatus = KeysTrackingStatus.Outdated;\n userIdentities.set(user);\n }\n }));\n }\n\n /** @return Promise<{added: string[], removed: string[]}> the user ids for who the room was added or removed to the userIdentity,\n * and with who a key should be now be shared\n **/\n async writeMemberChanges(room: Room, memberChanges: Map, historyVisibility: HistoryVisibility, txn: Transaction): Promise<{added: string[], removed: string[]}> {\n const added: string[] = [];\n const removed: string[] = [];\n await Promise.all(Array.from(memberChanges.values()).map(async memberChange => {\n // keys should now be shared with this member?\n // add the room to the userIdentity if so\n if (shouldShareKey(memberChange.membership, historyVisibility)) {\n if (await this._addRoomToUserIdentity(memberChange.roomId, memberChange.userId, txn)) {\n added.push(memberChange.userId);\n }\n } else if (shouldShareKey(memberChange.previousMembership, historyVisibility)) {\n // try to remove room we were previously sharing the key with the member but not anymore\n const {roomId} = memberChange;\n // if we left the room, remove room from all user identities in the room\n if (memberChange.userId === this._ownUserId) {\n const userIds = await txn.roomMembers.getAllUserIds(roomId);\n await Promise.all(userIds.map(userId => {\n return this._removeRoomFromUserIdentity(roomId, userId, txn);\n }));\n } else {\n await this._removeRoomFromUserIdentity(roomId, memberChange.userId, txn);\n }\n removed.push(memberChange.userId);\n }\n }));\n return {added, removed};\n }\n\n async trackRoom(room: Room, historyVisibility: HistoryVisibility, log: ILogItem): Promise {\n if (room.isTrackingMembers || !room.isEncrypted) {\n return;\n }\n const memberList = await room.loadMemberList(undefined, log);\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.roomSummary,\n this._storage.storeNames.userIdentities,\n this._storage.storeNames.deviceKeys, // to remove all devices in _removeRoomFromUserIdentity\n ]);\n try {\n let isTrackingChanges;\n try {\n isTrackingChanges = room.writeIsTrackingMembers(true, txn);\n const members = Array.from((memberList.members as ObservableMap).values());\n log.set(\"members\", members.length);\n // TODO: should we remove any userIdentities we should not share the key with??\n // e.g. as an extra security measure if we had a mistake in other code?\n await Promise.all(members.map(async member => {\n if (shouldShareKey(member.membership, historyVisibility)) {\n await this._addRoomToUserIdentity(member.roomId, member.userId, txn);\n } else {\n await this._removeRoomFromUserIdentity(member.roomId, member.userId, txn);\n }\n }));\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n room.applyIsTrackingMembersChanges(isTrackingChanges);\n } finally {\n memberList.release();\n }\n }\n\n async invalidateUserKeys(userId: string): Promise {\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.userIdentities]);\n const userIdentity = await txn.userIdentities.get(userId);\n if (userIdentity) {\n userIdentity.keysTrackingStatus = KeysTrackingStatus.Outdated;\n txn.userIdentities.set(userIdentity);\n }\n await txn.complete();\n }\n\n async getCrossSigningKeyForUser(userId: string, usage: KeyUsage, hsApi: HomeServerApi | undefined, log: ILogItem): Promise {\n return await log.wrap({l: \"DeviceTracker.getCrossSigningKeyForUser\", id: userId, usage}, async log => {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.userIdentities,\n this._storage.storeNames.crossSigningKeys,\n ]);\n const userIdentity = await txn.userIdentities.get(userId);\n if (userIdentity && userIdentity.keysTrackingStatus !== KeysTrackingStatus.Outdated) {\n return await txn.crossSigningKeys.get(userId, usage);\n }\n // not allowed to access the network, bail out\n if (!hsApi) {\n return undefined;\n }\n // fetch from hs\n const keys = await this._queryKeys([userId], hsApi, log);\n switch (usage) {\n case KeyUsage.Master:\n return keys.masterKeys.get(userId);\n case KeyUsage.SelfSigning:\n return keys.selfSigningKeys.get(userId);\n case KeyUsage.UserSigning:\n return keys.userSigningKeys.get(userId);\n }\n });\n }\n\n async writeHistoryVisibility(room: Room, historyVisibility: HistoryVisibility, syncTxn: Transaction, log: ILogItem): Promise<{added: string[], removed: string[]}> {\n const added: string[] = [];\n const removed: string[] = [];\n if (room.isTrackingMembers && room.isEncrypted) {\n await log.wrap(\"rewriting userIdentities\", async log => {\n // TODO: how do we know that we won't fetch the members from the server here and hence close the syncTxn?\n const memberList = await room.loadMemberList(syncTxn, log);\n try {\n const members = Array.from((memberList.members as ObservableMap).values());\n log.set(\"members\", members.length);\n await Promise.all(members.map(async member => {\n if (shouldShareKey(member.membership, historyVisibility)) {\n if (await this._addRoomToUserIdentity(member.roomId, member.userId, syncTxn)) {\n added.push(member.userId);\n }\n } else {\n if (await this._removeRoomFromUserIdentity(member.roomId, member.userId, syncTxn)) {\n removed.push(member.userId);\n }\n }\n }));\n } finally {\n memberList.release();\n }\n });\n }\n return {added, removed};\n }\n\n async _addRoomToUserIdentity(roomId: string, userId: string, txn: Transaction): Promise {\n const {userIdentities} = txn;\n const identity = await userIdentities.get(userId);\n const updatedIdentity = addRoomToIdentity(identity, userId, roomId);\n if (updatedIdentity) {\n userIdentities.set(updatedIdentity);\n return true;\n }\n return false;\n }\n\n async _removeRoomFromUserIdentity(roomId: string, userId: string, txn: Transaction): Promise {\n const {userIdentities, deviceKeys} = txn;\n const identity = await userIdentities.get(userId);\n if (identity) {\n identity.roomIds = identity.roomIds.filter(id => id !== roomId);\n // no more encrypted rooms with this user, remove\n if (identity.roomIds.length === 0) {\n userIdentities.remove(userId);\n deviceKeys.removeAllForUser(userId);\n } else {\n userIdentities.set(identity);\n }\n return true;\n }\n return false;\n }\n\n async _queryKeys(userIds: string[], hsApi: HomeServerApi, log: ILogItem): Promise<{\n deviceKeys: Map,\n masterKeys: Map,\n selfSigningKeys: Map,\n userSigningKeys: Map\n }> {\n // TODO: we need to handle the race here between /sync and /keys/query just like we need to do for the member list ...\n // there are multiple requests going out for /keys/query though and only one for /members\n // So, while doing /keys/query, writeDeviceChanges should add userIds marked as outdated to a list\n // when /keys/query returns, we should check that list and requery if we queried for a given user.\n // and then remove the list.\n\n const deviceKeyResponse = await hsApi.queryKeys({\n \"timeout\": 10000,\n \"device_keys\": userIds.reduce((deviceKeysMap, userId) => {\n deviceKeysMap[userId] = [];\n return deviceKeysMap;\n }, {}),\n \"token\": this._getSyncToken()\n }, {log}).response();\n\n const masterKeys = log.wrap(\"master keys\", log => this._filterVerifiedCrossSigningKeys(deviceKeyResponse[\"master_keys\"], KeyUsage.Master, log));\n const selfSigningKeys = log.wrap(\"self-signing keys\", log => this._filterVerifiedCrossSigningKeys(deviceKeyResponse[\"self_signing_keys\"], KeyUsage.SelfSigning, log));\n const userSigningKeys = log.wrap(\"user-signing keys\", log => this._filterVerifiedCrossSigningKeys(deviceKeyResponse[\"user_signing_keys\"], KeyUsage.UserSigning, log));\n const deviceKeys = log.wrap(\"device keys\", log => this._filterVerifiedDeviceKeys(deviceKeyResponse[\"device_keys\"], log));\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.userIdentities,\n this._storage.storeNames.deviceKeys,\n this._storage.storeNames.crossSigningKeys,\n ]);\n let deviceIdentities;\n try {\n for (const key of masterKeys.values()) {\n txn.crossSigningKeys.set(key);\n }\n for (const key of selfSigningKeys.values()) {\n txn.crossSigningKeys.set(key);\n }\n for (const key of userSigningKeys.values()) {\n txn.crossSigningKeys.set(key);\n }\n let totalCount = 0;\n await Promise.all(Array.from(deviceKeys.keys()).map(async (userId) => {\n let deviceKeysForUser = deviceKeys.get(userId)!;\n totalCount += deviceKeysForUser.length;\n // check for devices that changed their keys and keep the old key\n deviceKeysForUser = await this._storeQueriedDevicesForUserId(userId, deviceKeysForUser, txn);\n deviceKeys.set(userId, deviceKeysForUser);\n }));\n log.set(\"devices\", totalCount);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n return {\n deviceKeys,\n masterKeys,\n selfSigningKeys,\n userSigningKeys\n };\n }\n\n async _storeQueriedDevicesForUserId(userId: string, deviceKeys: DeviceKey[], txn: Transaction): Promise {\n // TODO: we should obsolete (flag) the device keys that have been removed,\n // but keep them to verify messages encrypted with it?\n const knownDeviceIds = await txn.deviceKeys.getAllDeviceIds(userId);\n // delete any devices that we know off but are not in the response anymore.\n // important this happens before checking if the ed25519 key changed,\n // otherwise we would end up deleting existing devices with changed keys.\n for (const deviceId of knownDeviceIds) {\n if (deviceKeys.every(di => di.device_id !== deviceId)) {\n txn.deviceKeys.remove(userId, deviceId);\n }\n }\n\n // all the device identities as we will have them in storage\n const allDeviceKeys: DeviceKey[] = [];\n const deviceKeysToStore: DeviceKey[] = [];\n // filter out devices that have changed their ed25519 key since last time we queried them\n await Promise.all(deviceKeys.map(async deviceKey => {\n if (knownDeviceIds.includes(deviceKey.device_id)) {\n const existingDevice = await txn.deviceKeys.get(deviceKey.user_id, deviceKey.device_id);\n if (existingDevice && getDeviceEd25519Key(existingDevice) !== getDeviceEd25519Key(deviceKey)) {\n allDeviceKeys.push(existingDevice);\n return;\n }\n }\n allDeviceKeys.push(deviceKey);\n deviceKeysToStore.push(deviceKey);\n }));\n // store devices\n for (const deviceKey of deviceKeysToStore) {\n txn.deviceKeys.set(deviceKey);\n }\n // mark user identities as up to date\n let identity = await txn.userIdentities.get(userId);\n if (!identity) {\n // create the identity if it doesn't exist, which can happen if\n // we request devices before tracking the room.\n // IMPORTANT here that the identity gets created without any roomId!\n // if we claim that we share and e2ee room with the user without having\n // checked, we could share keys with that user without them being in the room\n identity = createUserIdentity(userId);\n }\n identity.keysTrackingStatus = KeysTrackingStatus.UpToDate;\n txn.userIdentities.set(identity);\n\n return allDeviceKeys;\n }\n\n _filterVerifiedCrossSigningKeys(crossSigningKeysResponse: {[userId: string]: CrossSigningKey}, usage: KeyUsage, log: ILogItem): Map {\n const keys: Map = new Map();\n if (!crossSigningKeysResponse) {\n return keys;\n }\n for (const [userId, keyInfo] of Object.entries(crossSigningKeysResponse)) {\n log.wrap({l: userId}, log => {\n if (this._validateCrossSigningKey(userId, keyInfo, usage, log)) {\n keys.set(getKeyUserId(keyInfo)!, keyInfo);\n }\n });\n }\n return keys;\n }\n\n _validateCrossSigningKey(userId: string, keyInfo: CrossSigningKey, usage: KeyUsage, log: ILogItem): boolean {\n if (getKeyUserId(keyInfo) !== userId) {\n log.log({l: \"user_id mismatch\", userId: keyInfo[\"user_id\"]});\n return false;\n }\n if (getKeyUsage(keyInfo) !== usage) {\n log.log({l: \"usage mismatch\", usage: keyInfo.usage});\n return false;\n }\n const publicKey = getKeyEd25519Key(keyInfo);\n if (!publicKey) {\n log.log({l: \"no ed25519 key\", keys: keyInfo.keys});\n return false;\n }\n return true;\n }\n\n /**\n * @return {Array<{userId, verifiedKeys: Array>}\n */\n _filterVerifiedDeviceKeys(\n keyQueryDeviceKeysResponse: {[userId: string]: {[deviceId: string]: DeviceKey}},\n parentLog: ILogItem\n ): Map {\n const curve25519Keys: Set = new Set();\n const keys: Map = new Map();\n if (!keyQueryDeviceKeysResponse) {\n return keys;\n }\n for (const [userId, keysByDevice] of Object.entries(keyQueryDeviceKeysResponse)) {\n parentLog.wrap(userId, log => {\n const verifiedEntries = Object.entries(keysByDevice).filter(([deviceId, deviceKey]) => {\n return log.wrap(deviceId, log => {\n if (this._validateDeviceKey(userId, deviceId, deviceKey, log)) {\n const curve25519Key = getDeviceCurve25519Key(deviceKey);\n if (curve25519Keys.has(curve25519Key)) {\n parentLog.log({\n l: \"ignore device with duplicate curve25519 key\",\n keys: deviceKey\n }, parentLog.level.Warn);\n return false;\n }\n curve25519Keys.add(curve25519Key);\n return true;\n } else {\n return false;\n }\n });\n });\n const verifiedKeys = verifiedEntries.map(([, deviceKeys]) => deviceKeys);\n keys.set(userId, verifiedKeys);\n });\n }\n return keys;\n }\n\n _validateDeviceKey(userIdFromServer: string, deviceIdFromServer: string, deviceKey: DeviceKey, log: ILogItem): boolean {\n const deviceId = deviceKey[\"device_id\"];\n const userId = deviceKey[\"user_id\"];\n if (userId !== userIdFromServer) {\n log.log(\"user_id mismatch\");\n return false;\n }\n if (deviceId !== deviceIdFromServer) {\n log.log(\"device_id mismatch\");\n return false;\n }\n const ed25519Key = getDeviceEd25519Key(deviceKey);\n const curve25519Key = getDeviceCurve25519Key(deviceKey);\n if (typeof ed25519Key !== \"string\" || typeof curve25519Key !== \"string\") {\n log.log(\"ed25519 and/or curve25519 key invalid\").set({deviceKey});\n return false;\n }\n const isValid = verifyEd25519Signature(this._olmUtil, userId, deviceId, ed25519Key, deviceKey, log) === SignatureVerification.Valid;\n if (!isValid) {\n log.log({\n l: \"ignore device with invalid signature\",\n keys: deviceKey\n }, log.level.Warn);\n }\n return isValid;\n }\n\n /**\n * Gives all the device identities for a room that is already tracked.\n * Can be used to decide which users to share keys with.\n * Assumes room is already tracked. Call `trackRoom` first if unsure.\n * @param {String} roomId [description]\n * @return {[type]} [description]\n */\n async devicesForTrackedRoom(roomId: string, hsApi: HomeServerApi, log: ILogItem): Promise {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.roomMembers,\n this._storage.storeNames.userIdentities,\n ]);\n\n // because we don't have multiEntry support in IE11, we get a set of userIds that is pretty close to what we\n // need as a good first filter (given that non-join memberships will be in there). After fetching the identities,\n // we check which ones have the roomId for the room we're looking at.\n \n // So, this will also contain non-joined memberships\n const userIds = await txn.roomMembers.getAllUserIds(roomId);\n // TODO: check here if userIds is safe? yes it is\n return await this._devicesForUserIdsInTrackedRoom(roomId, userIds, txn, hsApi, log);\n }\n\n /** \n * Can be used to decide which users to share keys with.\n * Assumes room is already tracked. Call `trackRoom` first if unsure.\n * This will not return the device key for our own user, as we don't need to share keys with ourselves.\n */\n async devicesForRoomMembers(roomId: string, userIds: string[], hsApi: HomeServerApi, log: ILogItem): Promise {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.userIdentities,\n ]);\n return await this._devicesForUserIdsInTrackedRoom(roomId, userIds, txn, hsApi, log);\n }\n\n /** \n * Cannot be used to decide which users to share keys with.\n * Does not assume membership to any room or whether any room is tracked.\n * This will return device keys for our own user, including our own device.\n */\n async devicesForUsers(userIds: string[], hsApi: HomeServerApi, log: ILogItem): Promise {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.userIdentities,\n ]);\n\n const upToDateIdentities: UserIdentity[] = [];\n const outdatedUserIds: string[] = [];\n await Promise.all(userIds.map(async userId => {\n const i = await txn.userIdentities.get(userId);\n if (i && i.keysTrackingStatus === KeysTrackingStatus.UpToDate) {\n upToDateIdentities.push(i);\n } else if (!i || i.keysTrackingStatus === KeysTrackingStatus.Outdated) {\n // allow fetching for userIdentities we don't know about yet,\n // as we don't assume the room is tracked here.\n outdatedUserIds.push(userId);\n }\n }));\n return this._devicesForUserIdentities(upToDateIdentities, outdatedUserIds, hsApi, log);\n }\n\n /** Gets a single device */\n async deviceForId(userId: string, deviceId: string, hsApi: HomeServerApi, log: ILogItem): Promise {\n /**\n * 1. If the device keys are outdated, we will fetch all the keys and update them.\n */\n const userIdentityTxn = await this._storage.readTxn([this._storage.storeNames.userIdentities]);\n const userIdentity = await userIdentityTxn.userIdentities.get(userId);\n if (userIdentity?.keysTrackingStatus !== KeysTrackingStatus.UpToDate) {\n const {deviceKeys} = await this._queryKeys([userId], hsApi, log);\n const keyList = deviceKeys.get(userId);\n const device = keyList!.find(device => device.device_id === deviceId);\n return device;\n }\n\n /**\n * 2. If keys are up to date, return from storage.\n */\n const txn = await this._storage.readTxn([\n this._storage.storeNames.deviceKeys,\n ]);\n let deviceKey = await txn.deviceKeys.get(userId, deviceId);\n if (deviceKey) {\n log.set(\"existingDevice\", true);\n } else {\n //// BEGIN EXTRACT (deviceKeysMap)\n const deviceKeyResponse = await hsApi.queryKeys({\n \"timeout\": 10000,\n \"device_keys\": {\n [userId]: [deviceId]\n },\n \"token\": this._getSyncToken()\n }, {log}).response();\n // verify signature\n const verifiedKeysPerUser = log.wrap(\"verify\", log => this._filterVerifiedDeviceKeys(deviceKeyResponse[\"device_keys\"], log));\n //// END EXTRACT\n const verifiedKey = verifiedKeysPerUser.get(userId)?.find(d => d.device_id === deviceId);\n // user hasn't uploaded keys for device?\n if (!verifiedKey) {\n return undefined;\n }\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.deviceKeys,\n ]);\n // todo: the following comment states what the code does\n // but it fails to explain why it does what it does...\n\n // check again we don't have the device already.\n // when updating all keys for a user we allow updating the\n // device when the key hasn't changed so the device display name\n // can be updated, but here we don't.\n const existingDevice = await txn.deviceKeys.get(userId, deviceId);\n if (existingDevice) {\n deviceKey = existingDevice;\n log.set(\"existingDeviceAfterFetch\", true);\n } else {\n try {\n txn.deviceKeys.set(verifiedKey);\n deviceKey = verifiedKey;\n log.set(\"newDevice\", true);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n }\n }\n return deviceKey;\n }\n\n async deviceForCurveKey(userId: string, key: string, hsApi: HomeServerApi, log: ILogItem): Promise {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.deviceKeys,\n this._storage.storeNames.userIdentities,\n ]);\n const userIdentity = await txn.userIdentities.get(userId);\n if (userIdentity?.keysTrackingStatus !== KeysTrackingStatus.UpToDate) {\n const {deviceKeys} = await this._queryKeys([userId], hsApi, log);\n const keyList = deviceKeys.get(userId);\n const device = keyList!.find(device => getDeviceCurve25519Key(device) === key);\n return device;\n }\n const device = await txn.deviceKeys.getByCurve25519Key(key);\n return device;\n }\n\n /**\n * Gets all the device identities with which keys should be shared for a set of users in a tracked room.\n * If any userIdentities are outdated, it will fetch them from the homeserver.\n * @param {string} roomId the id of the tracked room to filter users by.\n * @param {Array} userIds a set of user ids to try and find the identity for.\n * @param {Transaction} userIdentityTxn to read the user identities\n * @param {HomeServerApi} hsApi\n * @return {Array} all devices identities for the given users we should share keys with.\n */\n async _devicesForUserIdsInTrackedRoom(roomId: string, userIds: string[], userIdentityTxn: Transaction, hsApi: HomeServerApi, log: ILogItem): Promise {\n const allMemberIdentities = await Promise.all(userIds.map(userId => userIdentityTxn.userIdentities.get(userId)));\n const identities = allMemberIdentities.filter(identity => {\n // we use roomIds to decide with whom we should share keys for a given room,\n // taking into account the membership and room history visibility.\n // so filter out anyone who we shouldn't share keys with.\n // Given we assume the room is tracked,\n // also exclude any userId which doesn't have a userIdentity yet.\n return identity && identity.roomIds.includes(roomId);\n }) as UserIdentity[]; // undefined has been filter out\n const upToDateIdentities = identities.filter(i => i.keysTrackingStatus === KeysTrackingStatus.UpToDate);\n const outdatedUserIds = identities\n .filter(i => i.keysTrackingStatus === KeysTrackingStatus.Outdated)\n .map(i => i.userId);\n let devices = await this._devicesForUserIdentities(upToDateIdentities, outdatedUserIds, hsApi, log);\n // filter out our own device as we should never share keys with it.\n devices = devices.filter(device => {\n const isOwnDevice = device.user_id === this._ownUserId && device.device_id === this._ownDeviceId;\n return !isOwnDevice;\n });\n return devices;\n }\n\n /** Gets the device identites for a set of user identities that\n * are known to be up to date, and a set of userIds that are known\n * to be absent from our store or are outdated. The outdated user ids\n * will have their keys fetched from the homeserver. */\n async _devicesForUserIdentities(upToDateIdentities: UserIdentity[], outdatedUserIds: string[], hsApi: HomeServerApi, log: ILogItem): Promise {\n log.set(\"uptodate\", upToDateIdentities.length);\n log.set(\"outdated\", outdatedUserIds.length);\n let queriedDeviceKeys: Map | undefined;\n if (outdatedUserIds.length) {\n // TODO: ignore the race between /sync and /keys/query for now,\n // where users could get marked as outdated or added/removed from the room while\n // querying keys\n const {deviceKeys} = await this._queryKeys(outdatedUserIds, hsApi, log);\n queriedDeviceKeys = deviceKeys;\n }\n\n const deviceTxn = await this._storage.readTxn([\n this._storage.storeNames.deviceKeys,\n ]);\n const devicesPerUser = await Promise.all(upToDateIdentities.map(identity => {\n return deviceTxn.deviceKeys.getAllForUserId(identity.userId);\n }));\n let flattenedDevices = devicesPerUser.reduce((all, devicesForUser) => all.concat(devicesForUser), []);\n if (queriedDeviceKeys && queriedDeviceKeys.size) {\n for (const deviceKeysForUser of queriedDeviceKeys.values()) {\n flattenedDevices = flattenedDevices.concat(deviceKeysForUser);\n }\n }\n return flattenedDevices;\n }\n\n async getDeviceByCurve25519Key(curve25519Key, txn: Transaction): Promise {\n return await txn.deviceKeys.getByCurve25519Key(curve25519Key);\n }\n\n get ownDeviceId(): string {\n return this._ownDeviceId;\n }\n}\n\nimport {createMockStorage} from \"../../mocks/Storage\";\nimport {Instance as NullLoggerInstance} from \"../../logging/NullLogger\";\n\nexport function tests() {\n\n function createUntrackedRoomMock(roomId: string, joinedUserIds: string[], invitedUserIds: string[] = []) {\n return {\n id: roomId,\n isTrackingMembers: false,\n isEncrypted: true,\n loadMemberList: () => {\n const joinedMembers = joinedUserIds.map(userId => {return RoomMember.fromUserId(roomId, userId, \"join\");});\n const invitedMembers = invitedUserIds.map(userId => {return RoomMember.fromUserId(roomId, userId, \"invite\");});\n const members = joinedMembers.concat(invitedMembers);\n const memberMap = members.reduce((map, member) => {\n map.set(member.userId, member);\n return map;\n }, new Map());\n return {members: memberMap, release() {}}\n },\n writeIsTrackingMembers(isTrackingMembers) {\n if (this.isTrackingMembers !== isTrackingMembers) {\n return isTrackingMembers;\n }\n return undefined;\n },\n applyIsTrackingMembersChanges(isTrackingMembers) {\n if (isTrackingMembers !== undefined) {\n this.isTrackingMembers = isTrackingMembers;\n }\n },\n }\n }\n\n function createQueryKeysHSApiMock(createKey = (algorithm, userId, deviceId) => `${algorithm}:${userId}:${deviceId}:key`): HomeServerApi {\n return {\n queryKeys(payload) {\n const {device_keys: deviceKeys} = payload;\n const userKeys = Object.entries(deviceKeys as {[userId: string]: string[]}).reduce((userKeys, [userId, deviceIds]) => {\n if (deviceIds.length === 0) {\n deviceIds = [\"device1\"];\n }\n userKeys[userId] = deviceIds.filter(d => d === \"device1\").reduce((deviceKeys, deviceId) => {\n deviceKeys[deviceId] = {\n \"algorithms\": [\n \"m.olm.v1.curve25519-aes-sha2\",\n \"m.megolm.v1.aes-sha2\"\n ],\n \"device_id\": deviceId,\n \"keys\": {\n [`curve25519:${deviceId}`]: createKey(\"curve25519\", userId, deviceId),\n [`ed25519:${deviceId}`]: createKey(\"ed25519\", userId, deviceId),\n },\n \"signatures\": {\n [userId]: {\n [`ed25519:${deviceId}`]: `ed25519:${userId}:${deviceId}:signature`\n }\n },\n \"unsigned\": {\n \"device_display_name\": `${userId} Phone`\n },\n \"user_id\": userId\n };\n return deviceKeys;\n }, {});\n return userKeys;\n }, {});\n const response = {device_keys: userKeys};\n return {\n async response() {\n return response;\n }\n };\n }\n } as unknown as HomeServerApi;\n }\n\n async function writeMemberListToStorage(room, storage) {\n const txn = await storage.readWriteTxn([\n storage.storeNames.roomMembers,\n ]);\n const memberList = await room.loadMemberList(txn);\n try {\n for (const member of memberList.members.values()) {\n txn.roomMembers.set(member.serialize());\n }\n } catch (err) {\n txn.abort();\n throw err;\n } finally {\n memberList.release();\n }\n await txn.complete();\n }\n\n const roomId = \"!abc:hs.tld\";\n\n return {\n \"trackRoom only writes joined members with history visibility of joined\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const room = createUntrackedRoomMock(roomId, [\"@alice:hs.tld\", \"@bob:hs.tld\"], [\"@charly:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Joined, NullLoggerInstance.item);\n const txn = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual(await txn.userIdentities.get(\"@alice:hs.tld\"), {\n userId: \"@alice:hs.tld\",\n roomIds: [roomId],\n keysTrackingStatus: KeysTrackingStatus.Outdated\n });\n assert.deepEqual(await txn.userIdentities.get(\"@bob:hs.tld\"), {\n userId: \"@bob:hs.tld\",\n roomIds: [roomId],\n keysTrackingStatus: KeysTrackingStatus.Outdated\n });\n assert.equal(await txn.userIdentities.get(\"@charly:hs.tld\"), undefined);\n },\n \"getting devices for tracked room yields correct keys\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const room = createUntrackedRoomMock(roomId, [\"@alice:hs.tld\", \"@bob:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Joined, NullLoggerInstance.item);\n const hsApi = createQueryKeysHSApiMock();\n const devices = await tracker.devicesForRoomMembers(roomId, [\"@alice:hs.tld\", \"@bob:hs.tld\"], hsApi, NullLoggerInstance.item);\n assert.equal(devices.length, 2);\n assert.equal(getDeviceEd25519Key(devices.find(d => d.user_id === \"@alice:hs.tld\")!), \"ed25519:@alice:hs.tld:device1:key\");\n assert.equal(getDeviceEd25519Key(devices.find(d => d.user_id === \"@bob:hs.tld\")!), \"ed25519:@bob:hs.tld:device1:key\");\n },\n \"device with changed key is ignored\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const room = createUntrackedRoomMock(roomId, [\"@alice:hs.tld\", \"@bob:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Joined, NullLoggerInstance.item);\n const hsApi = createQueryKeysHSApiMock();\n // query devices first time\n await tracker.devicesForRoomMembers(roomId, [\"@alice:hs.tld\", \"@bob:hs.tld\"], hsApi, NullLoggerInstance.item);\n const txn = await storage.readWriteTxn([storage.storeNames.userIdentities]);\n // mark alice as outdated, so keys will be fetched again\n tracker.writeDeviceChanges([\"@alice:hs.tld\"], txn, NullLoggerInstance.item);\n await txn.complete();\n const hsApiWithChangedAliceKey = createQueryKeysHSApiMock((algo, userId, deviceId) => {\n return `${algo}:${userId}:${deviceId}:${userId === \"@alice:hs.tld\" ? \"newKey\" : \"key\"}`;\n });\n const devices = await tracker.devicesForRoomMembers(roomId, [\"@alice:hs.tld\", \"@bob:hs.tld\"], hsApiWithChangedAliceKey, NullLoggerInstance.item);\n assert.equal(devices.length, 2);\n assert.equal(getDeviceEd25519Key(devices.find(d => d.user_id === \"@alice:hs.tld\")!), \"ed25519:@alice:hs.tld:device1:key\");\n assert.equal(getDeviceEd25519Key(devices.find(d => d.user_id === \"@bob:hs.tld\")!), \"ed25519:@bob:hs.tld:device1:key\");\n const txn2 = await storage.readTxn([storage.storeNames.deviceKeys]);\n // also check the modified key was not stored\n assert.equal(getDeviceEd25519Key((await txn2.deviceKeys.get(\"@alice:hs.tld\", \"device1\"))!), \"ed25519:@alice:hs.tld:device1:key\");\n },\n \"change history visibility from joined to invited adds invitees\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n // alice is joined, bob is invited\n const room = await createUntrackedRoomMock(roomId, \n [\"@alice:hs.tld\"], [\"@bob:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Joined, NullLoggerInstance.item);\n const txn = await storage.readWriteTxn([storage.storeNames.userIdentities, storage.storeNames.deviceKeys]);\n assert.equal(await txn.userIdentities.get(\"@bob:hs.tld\"), undefined);\n const {added, removed} = await tracker.writeHistoryVisibility(room, HistoryVisibility.Invited, txn, NullLoggerInstance.item);\n assert.equal((await txn.userIdentities.get(\"@bob:hs.tld\"))!.userId, \"@bob:hs.tld\");\n assert.deepEqual(added, [\"@bob:hs.tld\"]);\n assert.deepEqual(removed, []);\n },\n \"change history visibility from invited to joined removes invitees\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n // alice is joined, bob is invited\n const room = await createUntrackedRoomMock(roomId, \n [\"@alice:hs.tld\"], [\"@bob:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Invited, NullLoggerInstance.item);\n const txn = await storage.readWriteTxn([storage.storeNames.userIdentities, storage.storeNames.deviceKeys]);\n assert.equal((await txn.userIdentities.get(\"@bob:hs.tld\"))!.userId, \"@bob:hs.tld\");\n const {added, removed} = await tracker.writeHistoryVisibility(room, HistoryVisibility.Joined, txn, NullLoggerInstance.item);\n assert.equal(await txn.userIdentities.get(\"@bob:hs.tld\"), undefined);\n assert.deepEqual(added, []);\n assert.deepEqual(removed, [\"@bob:hs.tld\"]);\n },\n \"adding invitee with history visibility of invited adds room to userIdentities\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const room = await createUntrackedRoomMock(roomId, [\"@alice:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Invited, NullLoggerInstance.item);\n const txn = await storage.readWriteTxn([storage.storeNames.userIdentities, storage.storeNames.deviceKeys]);\n // inviting a new member\n const inviteChange = new MemberChange(RoomMember.fromUserId(roomId, \"@bob:hs.tld\", \"invite\"));\n const {added, removed} = await tracker.writeMemberChanges(room, new Map([[inviteChange.userId, inviteChange]]), HistoryVisibility.Invited, txn);\n assert.deepEqual(added, [\"@bob:hs.tld\"]);\n assert.deepEqual(removed, []);\n assert.equal((await txn.userIdentities.get(\"@bob:hs.tld\"))!.userId, \"@bob:hs.tld\");\n },\n \"adding invitee with history visibility of joined doesn't add room\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const room = await createUntrackedRoomMock(roomId, [\"@alice:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Joined, NullLoggerInstance.item);\n const txn = await storage.readWriteTxn([storage.storeNames.userIdentities, storage.storeNames.deviceKeys]);\n // inviting a new member\n const inviteChange = new MemberChange(RoomMember.fromUserId(roomId, \"@bob:hs.tld\", \"invite\"));\n const memberChanges = new Map([[inviteChange.userId, inviteChange]]);\n const {added, removed} = await tracker.writeMemberChanges(room, memberChanges, HistoryVisibility.Joined, txn);\n assert.deepEqual(added, []);\n assert.deepEqual(removed, []);\n assert.equal(await txn.userIdentities.get(\"@bob:hs.tld\"), undefined);\n },\n \"getting all devices after changing history visibility now includes invitees\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const room = createUntrackedRoomMock(roomId, [\"@alice:hs.tld\"], [\"@bob:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Invited, NullLoggerInstance.item);\n const hsApi = createQueryKeysHSApiMock();\n // write memberlist from room mock to mock storage,\n // as devicesForTrackedRoom reads directly from roomMembers store.\n await writeMemberListToStorage(room, storage);\n const devices = await tracker.devicesForTrackedRoom(roomId, hsApi, NullLoggerInstance.item);\n assert.equal(devices.length, 2);\n assert.equal(getDeviceEd25519Key(devices.find(d => d.user_id === \"@alice:hs.tld\")!), \"ed25519:@alice:hs.tld:device1:key\");\n assert.equal(getDeviceEd25519Key(devices.find(d => d.user_id === \"@bob:hs.tld\")!), \"ed25519:@bob:hs.tld:device1:key\");\n },\n \"rejecting invite with history visibility of invited removes room from user identity\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n // alice is joined, bob is invited\n const room = await createUntrackedRoomMock(roomId, [\"@alice:hs.tld\"], [\"@bob:hs.tld\"]);\n await tracker.trackRoom(room, HistoryVisibility.Invited, NullLoggerInstance.item);\n const txn = await storage.readWriteTxn([storage.storeNames.userIdentities, storage.storeNames.deviceKeys]);\n // reject invite\n const inviteChange = new MemberChange(RoomMember.fromUserId(roomId, \"@bob:hs.tld\", \"leave\"), \"invite\");\n const memberChanges = new Map([[inviteChange.userId, inviteChange]]);\n const {added, removed} = await tracker.writeMemberChanges(room, memberChanges, HistoryVisibility.Invited, txn);\n assert.deepEqual(added, []);\n assert.deepEqual(removed, [\"@bob:hs.tld\"]);\n assert.equal(await txn.userIdentities.get(\"@bob:hs.tld\"), undefined);\n },\n \"remove room from user identity sharing multiple rooms with us preserves other room\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n // alice is joined, bob is invited\n const room1 = await createUntrackedRoomMock(\"!abc:hs.tld\", [\"@alice:hs.tld\", \"@bob:hs.tld\"]);\n const room2 = await createUntrackedRoomMock(\"!def:hs.tld\", [\"@alice:hs.tld\", \"@bob:hs.tld\"]);\n await tracker.trackRoom(room1, HistoryVisibility.Joined, NullLoggerInstance.item);\n await tracker.trackRoom(room2, HistoryVisibility.Joined, NullLoggerInstance.item);\n const txn1 = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual((await txn1.userIdentities.get(\"@bob:hs.tld\"))!.roomIds, [\"!abc:hs.tld\", \"!def:hs.tld\"]);\n const leaveChange = new MemberChange(RoomMember.fromUserId(room2.id, \"@bob:hs.tld\", \"leave\"), \"join\");\n const memberChanges = new Map([[leaveChange.userId, leaveChange]]);\n const txn2 = await storage.readWriteTxn([storage.storeNames.userIdentities, storage.storeNames.deviceKeys]);\n await tracker.writeMemberChanges(room2, memberChanges, HistoryVisibility.Joined, txn2);\n await txn2.complete();\n const txn3 = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual((await txn3.userIdentities.get(\"@bob:hs.tld\"))!.roomIds, [\"!abc:hs.tld\"]);\n },\n \"add room to user identity sharing multiple rooms with us preserves other room\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n // alice is joined, bob is invited\n const room1 = await createUntrackedRoomMock(\"!abc:hs.tld\", [\"@alice:hs.tld\", \"@bob:hs.tld\"]);\n const room2 = await createUntrackedRoomMock(\"!def:hs.tld\", [\"@alice:hs.tld\", \"@bob:hs.tld\"]);\n await tracker.trackRoom(room1, HistoryVisibility.Joined, NullLoggerInstance.item);\n const txn1 = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual((await txn1.userIdentities.get(\"@bob:hs.tld\"))!.roomIds, [\"!abc:hs.tld\"]);\n await tracker.trackRoom(room2, HistoryVisibility.Joined, NullLoggerInstance.item);\n const txn2 = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual((await txn2.userIdentities.get(\"@bob:hs.tld\"))!.roomIds, [\"!abc:hs.tld\", \"!def:hs.tld\"]);\n },\n \"devicesForUsers fetches users even though they aren't in any tracked room\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const hsApi = createQueryKeysHSApiMock();\n const devices = await tracker.devicesForUsers([\"@bob:hs.tld\"], hsApi, NullLoggerInstance.item);\n assert.equal(devices.length, 1);\n assert.equal(getDeviceCurve25519Key(devices[0]), \"curve25519:@bob:hs.tld:device1:key\");\n const txn1 = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual((await txn1.userIdentities.get(\"@bob:hs.tld\"))!.roomIds, []);\n },\n \"devicesForUsers doesn't add any roomId when creating userIdentity\": async assert => {\n const storage = await createMockStorage();\n const tracker = new DeviceTracker({\n storage,\n getSyncToken: () => \"token\",\n olmUtil: {ed25519_verify: () => {}} as unknown as Olm.Utility, // valid if it does not throw\n ownUserId: \"@alice:hs.tld\",\n ownDeviceId: \"ABCD\",\n });\n const hsApi = createQueryKeysHSApiMock();\n await tracker.devicesForUsers([\"@bob:hs.tld\"], hsApi, NullLoggerInstance.item);\n const txn1 = await storage.readTxn([storage.storeNames.userIdentities]);\n assert.deepEqual((await txn1.userIdentities.get(\"@bob:hs.tld\"))!.roomIds, []);\n }\n }\n}\n","import {IDOMStorage} from \"./types\";\nimport {ITransaction} from \"./QueryTarget\";\nimport {iterateCursor, NOT_DONE, reqAsPromise} from \"./utils\";\nimport {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from \"../../room/members/RoomMember.js\";\nimport {SESSION_E2EE_KEY_PREFIX} from \"../../e2ee/common\";\nimport {SummaryData} from \"../../room/RoomSummary\";\nimport {RoomMemberStore, MemberData} from \"./stores/RoomMemberStore\";\nimport {InboundGroupSessionStore, InboundGroupSessionEntry, BackupStatus, KeySource} from \"./stores/InboundGroupSessionStore\";\nimport {RoomStateEntry} from \"./stores/RoomStateStore\";\nimport {SessionStore} from \"./stores/SessionStore\";\nimport {Store} from \"./Store\";\nimport {encodeScopeTypeKey} from \"./stores/OperationStore\";\nimport {MAX_UNICODE} from \"./stores/common\";\nimport {ILogItem} from \"../../../logging/types\";\n\nimport type {UserIdentity} from \"../../e2ee/DeviceTracker\";\nimport {KeysTrackingStatus} from \"../../e2ee/DeviceTracker\";\n\nexport type MigrationFunc = (db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) => Promise | void;\n// FUNCTIONS SHOULD ONLY BE APPENDED!!\n// the index in the array is the database version\nexport const schema: MigrationFunc[] = [\n createInitialStores,\n createMemberStore,\n migrateSession,\n createE2EEStores,\n migrateEncryptionFlag,\n createAccountDataStore,\n createInviteStore,\n createArchivedRoomSummaryStore,\n migrateOperationScopeIndex,\n createTimelineRelationsStore,\n fixMissingRoomsInUserIdentities,\n changeSSSSKeyPrefix,\n backupAndRestoreE2EEAccountToLocalStorage,\n clearAllStores,\n addInboundSessionBackupIndex,\n migrateBackupStatus,\n createCallStore,\n applyCrossSigningChanges,\n createSharedSecretStore,\n];\n// TODO: how to deal with git merge conflicts of this array?\n\n// TypeScript note: for now, do not bother introducing interfaces / alias\n// for old schemas. Just take them as `any`. \n\nfunction createDatabaseNameHelper(db: IDBDatabase): ITransaction {\n // the Store object gets passed in several things through the Transaction class (a wrapper around IDBTransaction),\n // the only thing we should need here is the databaseName though, so we mock it out.\n // ideally we should have an easier way to go from the idb primitive layer to the specific store classes where\n // we implement logic, but for now we need this.\n const databaseNameHelper: ITransaction = {\n databaseName: db.name,\n get idbFactory(): IDBFactory { throw new Error(\"unused\");},\n get IDBKeyRange(): typeof IDBKeyRange { throw new Error(\"unused\");},\n addWriteError() {},\n };\n return databaseNameHelper;\n}\n\n\n// how do we deal with schema updates vs existing data migration in a way that \n//v1\nfunction createInitialStores(db: IDBDatabase): void {\n db.createObjectStore(\"session\", {keyPath: \"key\"});\n // any way to make keys unique here? (just use put?)\n db.createObjectStore(\"roomSummary\", {keyPath: \"roomId\"});\n\n // need index to find live fragment? prooobably ok without for now\n //key = room_id | fragment_id\n db.createObjectStore(\"timelineFragments\", {keyPath: \"key\"});\n //key = room_id | fragment_id | event_index\n const timelineEvents = db.createObjectStore(\"timelineEvents\", {keyPath: \"key\"});\n //eventIdKey = room_id | event_id\n timelineEvents.createIndex(\"byEventId\", \"eventIdKey\", {unique: true});\n //key = room_id | event.type | event.state_key,\n db.createObjectStore(\"roomState\", {keyPath: \"key\"});\n db.createObjectStore(\"pendingEvents\", {keyPath: \"key\"});\n}\n//v2\nasync function createMemberStore(db: IDBDatabase, txn: IDBTransaction): Promise {\n // Cast ok here because only \"set\" is used\n const roomMembers = new RoomMemberStore(db.createObjectStore(\"roomMembers\", {keyPath: \"key\"}) as any);\n // migrate existing member state events over\n const roomState = txn.objectStore(\"roomState\");\n await iterateCursor(roomState.openCursor(), entry => {\n if (entry.event.type === MEMBER_EVENT_TYPE) {\n roomState.delete(entry.key);\n const member = RoomMember.fromMemberEvent(entry.roomId, entry.event);\n if (member) {\n roomMembers.set(member.serialize());\n }\n }\n return NOT_DONE;\n });\n}\n//v3\nasync function migrateSession(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage): Promise {\n const session = txn.objectStore(\"session\");\n try {\n const PRE_MIGRATION_KEY = 1;\n const entry = await reqAsPromise(session.get(PRE_MIGRATION_KEY));\n if (entry) {\n session.delete(PRE_MIGRATION_KEY);\n const {syncToken, syncFilterId, serverVersions} = entry.value;\n // Cast ok here because only \"set\" is used and we don't look into return\n const store = new SessionStore(session as any, localStorage);\n store.set(\"sync\", {token: syncToken, filterId: syncFilterId});\n store.set(\"serverVersions\", serverVersions);\n }\n } catch (err) {\n txn.abort();\n console.error(\"could not migrate session\", err.stack);\n }\n}\n//v4\nfunction createE2EEStores(db: IDBDatabase): void {\n db.createObjectStore(\"userIdentities\", {keyPath: \"userId\"});\n const deviceIdentities = db.createObjectStore(\"deviceIdentities\", {keyPath: \"key\"});\n deviceIdentities.createIndex(\"byCurve25519Key\", \"curve25519Key\", {unique: true});\n db.createObjectStore(\"olmSessions\", {keyPath: \"key\"});\n db.createObjectStore(\"inboundGroupSessions\", {keyPath: \"key\"});\n db.createObjectStore(\"outboundGroupSessions\", {keyPath: \"roomId\"});\n db.createObjectStore(\"groupSessionDecryptions\", {keyPath: \"key\"});\n const operations = db.createObjectStore(\"operations\", {keyPath: \"id\"});\n operations.createIndex(\"byTypeAndScope\", \"typeScopeKey\", {unique: false});\n}\n\n// v5\nasync function migrateEncryptionFlag(db: IDBDatabase, txn: IDBTransaction): Promise {\n // migrate room summary isEncrypted -> encryption prop\n const roomSummary = txn.objectStore(\"roomSummary\");\n const roomState = txn.objectStore(\"roomState\");\n const summaries: any[] = [];\n await iterateCursor(roomSummary.openCursor(), summary => {\n summaries.push(summary);\n return NOT_DONE;\n });\n for (const summary of summaries) {\n const encryptionEntry = await reqAsPromise(roomState.get(`${summary.roomId}|m.room.encryption|`));\n if (encryptionEntry) {\n summary.encryption = encryptionEntry?.event?.content;\n delete summary.isEncrypted;\n roomSummary.put(summary);\n }\n }\n}\n\n// v6\nfunction createAccountDataStore(db: IDBDatabase): void {\n db.createObjectStore(\"accountData\", {keyPath: \"type\"});\n}\n\n// v7\nfunction createInviteStore(db: IDBDatabase): void {\n db.createObjectStore(\"invites\", {keyPath: \"roomId\"});\n}\n\n// v8\nfunction createArchivedRoomSummaryStore(db: IDBDatabase): void {\n db.createObjectStore(\"archivedRoomSummary\", {keyPath: \"summary.roomId\"});\n}\n\n// v9\nasync function migrateOperationScopeIndex(db: IDBDatabase, txn: IDBTransaction): Promise {\n try {\n const operations = txn.objectStore(\"operations\");\n operations.deleteIndex(\"byTypeAndScope\");\n await iterateCursor(operations.openCursor(), (op, key, cur) => {\n const {typeScopeKey} = op;\n delete op.typeScopeKey;\n const [type, scope] = typeScopeKey.split(\"|\");\n op.scopeTypeKey = encodeScopeTypeKey(scope, type);\n cur.update(op);\n return NOT_DONE;\n });\n operations.createIndex(\"byScopeAndType\", \"scopeTypeKey\", {unique: false});\n } catch (err) {\n txn.abort();\n console.error(\"could not migrate operations\", err.stack);\n }\n}\n\n//v10\nfunction createTimelineRelationsStore(db: IDBDatabase) : void {\n db.createObjectStore(\"timelineRelations\", {keyPath: \"key\"});\n}\n\n//v11 doesn't change the schema,\n// but ensured all userIdentities have all the roomIds they should (see #470)\n\n// 2022-07-20: The fix dated from August 2021, and have removed it now because of a\n// refactoring needed in the device tracker, which made it inconvenient to expose addRoomToIdentity\nfunction fixMissingRoomsInUserIdentities() {}\n\n// v12 move ssssKey to e2ee:ssssKey so it will get backed up in the next step\nasync function changeSSSSKeyPrefix(db: IDBDatabase, txn: IDBTransaction) {\n const session = txn.objectStore(\"session\");\n const ssssKey = await reqAsPromise(session.get(\"ssssKey\"));\n if (ssssKey) {\n session.put({key: `${SESSION_E2EE_KEY_PREFIX}ssssKey`, value: ssssKey.value});\n }\n}\n// v13\nasync function backupAndRestoreE2EEAccountToLocalStorage(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) {\n const session = txn.objectStore(\"session\");\n const sessionStore = new SessionStore(new Store(session, createDatabaseNameHelper(db)), localStorage);\n // if we already have an e2ee identity, write a backup to local storage.\n // further updates to e2ee keys in the session store will also write to local storage from 0.2.15 on,\n // but here we make sure a backup is immediately created after installing the update and we don't wait until\n // the olm account needs to change\n sessionStore.writeE2EEIdentityToLocalStorage();\n // and if we already have a backup, restore it now for any missing key in idb.\n // this will restore the backup every time the idb database is dropped as it will\n // run through all the migration steps when recreating it.\n const restored = await sessionStore.tryRestoreE2EEIdentityFromLocalStorage(log);\n log.set(\"restored\", restored);\n}\n// v14 clear all stores apart from e2ee keys because of possible timeline corruption in #515, will trigger initial sync\nasync function clearAllStores(db: IDBDatabase, txn: IDBTransaction) {\n for (const storeName of db.objectStoreNames) {\n const store = txn.objectStore(storeName);\n switch (storeName) {\n case \"inboundGroupSessions\":\n case \"outboundGroupSessions\":\n case \"olmSessions\":\n case \"operations\":\n continue;\n case \"session\": {\n await iterateCursor(store.openCursor(), (value, key, cursor) => {\n if (!(key as string).startsWith(SESSION_E2EE_KEY_PREFIX)) {\n cursor.delete();\n }\n return NOT_DONE;\n })\n break;\n }\n default: {\n store.clear();\n break;\n }\n }\n }\n}\n\n// v15 add backup index to inboundGroupSessions\nasync function addInboundSessionBackupIndex(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem): Promise {\n const inboundGroupSessions = txn.objectStore(\"inboundGroupSessions\");\n inboundGroupSessions.createIndex(\"byBackup\", \"backup\", {unique: false});\n}\n\n\n// v16 migrates the backup and source fields of inbound group sessions\nasync function migrateBackupStatus(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem): Promise {\n const inboundGroupSessions = txn.objectStore(\"inboundGroupSessions\");\n let countWithSession = 0;\n let countWithoutSession = 0;\n await iterateCursor(inboundGroupSessions.openCursor(), (value, key, cursor) => {\n if (value.session) {\n value.backup = BackupStatus.NotBackedUp;\n // we'll also have backup keys in here, we can't tell,\n // but the worst thing that can happen is that we try\n // to backup keys that were already in backup, which\n // the server will ignore\n value.source = KeySource.DeviceMessage;\n cursor.update(value);\n countWithSession += 1;\n } else {\n countWithoutSession += 1;\n }\n return NOT_DONE;\n });\n log.set(\"countWithoutSession\", countWithoutSession);\n log.set(\"countWithSession\", countWithSession);\n}\n\n//v17 create calls store\nfunction createCallStore(db: IDBDatabase) : void {\n db.createObjectStore(\"calls\", {keyPath: \"key\"});\n}\n\n//v18 add crossSigningKeys store, rename deviceIdentities to deviceKeys and empties userIdentities \nasync function applyCrossSigningChanges(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) : Promise {\n db.createObjectStore(\"crossSigningKeys\", {keyPath: \"key\"});\n db.deleteObjectStore(\"deviceIdentities\");\n const deviceKeys = db.createObjectStore(\"deviceKeys\", {keyPath: \"key\"});\n deviceKeys.createIndex(\"byCurve25519Key\", \"curve25519Key\", {unique: true});\n // mark all userIdentities as outdated as cross-signing keys won't be stored\n // also rename the deviceTrackingStatus field to keysTrackingStatus\n const userIdentities = txn.objectStore(\"userIdentities\");\n let counter = 0;\n await iterateCursor(userIdentities.openCursor(), (value, key, cursor) => {\n delete value[\"deviceTrackingStatus\"];\n delete value[\"crossSigningKeys\"];\n value.keysTrackingStatus = KeysTrackingStatus.Outdated;\n cursor.update(value);\n counter += 1;\n return NOT_DONE;\n });\n log.set(\"marked_outdated\", counter);\n}\n\n//v19 create shared secrets store\nfunction createSharedSecretStore(db: IDBDatabase) : void {\n db.createObjectStore(\"sharedSecrets\", {keyPath: \"key\"});\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n\nimport {openDatabase, txnAsPromise, reqAsPromise} from \"./utils\";\n\n// filed as https://bugs.webkit.org/show_bug.cgi?id=222746\nexport async function detectWebkitEarlyCloseTxnBug(idbFactory: IDBFactory): Promise {\n const dbName = \"hydrogen_webkit_test_inactive_txn_bug\";\n try {\n const db = await openDatabase(dbName, db => {\n db.createObjectStore(\"test\", {keyPath: \"key\"});\n }, 1, idbFactory);\n const readTxn = db.transaction([\"test\"], \"readonly\");\n await reqAsPromise(readTxn.objectStore(\"test\").get(\"somekey\"));\n // schedule a macro task in between the two txns\n await new Promise(r => setTimeout(r, 0));\n const writeTxn = db.transaction([\"test\"], \"readwrite\");\n await Promise.resolve();\n writeTxn.objectStore(\"test\").add({key: \"somekey\", value: \"foo\"});\n await txnAsPromise(writeTxn);\n db.close();\n } catch (err) {\n if (err.name === \"TransactionInactiveError\") {\n return true;\n }\n }\n return false;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {IDOMStorage} from \"./types\";\nimport {Storage} from \"./Storage\";\nimport {openDatabase, reqAsPromise} from \"./utils\";\nimport {exportSession, importSession, Export} from \"./export\";\nimport {schema} from \"./schema\";\nimport {detectWebkitEarlyCloseTxnBug} from \"./quirks\";\nimport {ILogItem} from \"../../../logging/types\";\nimport {clearKeysFromLocalStorage} from \"./stores/SessionStore\";\n\nconst sessionName = (sessionId: string) => `hydrogen_session_${sessionId}`;\nconst openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory, localStorage: IDOMStorage, log: ILogItem) {\n const create = (db, txn, oldVersion, version) => createStores(db, txn, oldVersion, version, localStorage, log);\n return openDatabase(sessionName(sessionId), create, schema.length, idbFactory);\n}\n\ninterface ServiceWorkerHandler {\n preventConcurrentSessionAccess: (sessionId: string) => Promise;\n}\n\nasync function requestPersistedStorage(): Promise {\n // don't assume browser so we can run in node with fake-idb\n const glob = this;\n if (glob?.navigator?.storage?.persist) {\n return await glob.navigator.storage.persist();\n } else if (glob?.document.requestStorageAccess) {\n try {\n await glob.document.requestStorageAccess();\n return true;\n } catch (err) {\n console.warn(\"requestStorageAccess threw an error:\", err);\n return false;\n }\n } else {\n return false;\n }\n}\n\nexport class StorageFactory {\n private _serviceWorkerHandler: ServiceWorkerHandler;\n private _idbFactory: IDBFactory;\n private _IDBKeyRange: typeof IDBKeyRange;\n private _localStorage: IDOMStorage;\n\n constructor(serviceWorkerHandler: ServiceWorkerHandler, idbFactory: IDBFactory = window.indexedDB, _IDBKeyRange = window.IDBKeyRange, localStorage: IDOMStorage = window.localStorage) {\n this._serviceWorkerHandler = serviceWorkerHandler;\n this._idbFactory = idbFactory;\n this._IDBKeyRange = _IDBKeyRange;\n this._localStorage = localStorage;\n }\n\n async create(sessionId: string, log: ILogItem): Promise {\n await this._serviceWorkerHandler?.preventConcurrentSessionAccess(sessionId);\n requestPersistedStorage().then(persisted => {\n // Firefox lies here though, and returns true even if the user denied the request\n if (!persisted) {\n log.log(\"no persisted storage, database can be evicted by browser\", log.level.Warn);\n }\n });\n\n const hasWebkitEarlyCloseTxnBug = await detectWebkitEarlyCloseTxnBug(this._idbFactory);\n const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);\n return new Storage(db, this._idbFactory, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug, this._localStorage, log.logger);\n }\n\n async delete(sessionId: string): Promise {\n const databaseName = sessionName(sessionId);\n try {\n clearKeysFromLocalStorage(this._localStorage, databaseName);\n } catch (e) {}\n try {\n const req = this._idbFactory.deleteDatabase(databaseName);\n await reqAsPromise(req);\n } catch (e) {}\n }\n\n async export(sessionId: string, log: ILogItem): Promise {\n const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);\n return await exportSession(db);\n }\n\n async import(sessionId: string, data: Export, log: ILogItem): Promise {\n const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);\n return await importSession(db, data);\n }\n}\n\nasync function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number, localStorage: IDOMStorage, log: ILogItem): Promise {\n const startIdx = oldVersion || 0;\n return log.wrap(\n { l: \"storage migration\", oldVersion, version },\n async (log) => {\n for (let i = startIdx; i < version; ++i) {\n const migrationFunc = schema[i];\n await log.wrap(`v${i + 1}`, (log) => migrationFunc(db, txn, localStorage, log));\n }\n });\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventEntry} from \"../entries/EventEntry.js\";\nimport {REDACTION_TYPE, isRedacted} from \"../../common\";\nimport {ANNOTATION_RELATION_TYPE, getRelation} from \"../relations.js\";\nimport {redactEvent} from \"../common.js\";\n\nexport class RelationWriter {\n constructor({roomId, ownUserId, fragmentIdComparer}) {\n this._roomId = roomId;\n this._ownUserId = ownUserId;\n this._fragmentIdComparer = fragmentIdComparer;\n }\n\n // this needs to happen again after decryption too for edits\n async writeRelation(sourceEntry, txn, log) {\n const {relatedEventId} = sourceEntry;\n if (relatedEventId) {\n const relation = getRelation(sourceEntry.event);\n if (relation && relation.rel_type) {\n // we don't consider replies (which aren't relations in the MSC2674 sense)\n txn.timelineRelations.add(this._roomId, relation.event_id, relation.rel_type, sourceEntry.id);\n }\n const target = await txn.timelineEvents.getByEventId(this._roomId, relatedEventId);\n if (target) {\n const updatedStorageEntries = await this._applyRelation(sourceEntry, target, txn, log);\n if (updatedStorageEntries) {\n return updatedStorageEntries.map(e => {\n txn.timelineEvents.update(e);\n return new EventEntry(e, this._fragmentIdComparer);\n });\n }\n }\n }\n return null;\n }\n\n /**\n * @param {Object} storageEntry the event object, as it will be stored in storage.\n * Will be modified (but not written to storage) in case this event is\n * a relation target for which we've previously received relations.\n * @param {Direction} direction of the gap fill\n * */\n async writeGapRelation(storageEntry, direction, txn, log) {\n const sourceEntry = new EventEntry(storageEntry, this._fragmentIdComparer);\n const result = await this.writeRelation(sourceEntry, txn, log);\n // when back-paginating, it can also happen that we've received relations\n // for this event before, which now upon receiving the target need to be aggregated.\n if (direction.isBackward && !isRedacted(storageEntry.event)) {\n const relations = await txn.timelineRelations.getAllForTarget(this._roomId, sourceEntry.id);\n if (relations.length) {\n for (const r of relations) {\n const relationStorageEntry = await txn.timelineEvents.getByEventId(this._roomId, r.sourceEventId);\n if (relationStorageEntry) {\n const relationEntry = new EventEntry(relationStorageEntry, this._fragmentIdComparer);\n await this._applyRelation(relationEntry, storageEntry, txn, log);\n }\n }\n }\n }\n\n return result;\n }\n\n /**\n * @param {EventEntry} sourceEntry\n * @param {Object} targetStorageEntry event entry as stored in the timelineEvents store\n * @return {[Object]} array of event storage entries that have been updated\n * */\n async _applyRelation(sourceEntry, targetStorageEntry, txn, log) {\n if (sourceEntry.eventType === REDACTION_TYPE) {\n return log.wrap(\"redact\", async log => {\n const redactedEvent = targetStorageEntry.event;\n const relation = getRelation(redactedEvent); // get this before redacting\n const redacted = this._applyRedaction(sourceEntry.event, targetStorageEntry, txn, log);\n if (redacted) {\n const updated = [targetStorageEntry];\n if (relation) {\n const relationTargetStorageEntry = await this._reaggregateRelation(redactedEvent, relation, txn, log);\n if (relationTargetStorageEntry) {\n updated.push(relationTargetStorageEntry);\n }\n }\n return updated;\n }\n return null;\n });\n } else {\n const relation = getRelation(sourceEntry.event);\n if (relation && !isRedacted(targetStorageEntry.event)) {\n const relType = relation.rel_type;\n if (relType === ANNOTATION_RELATION_TYPE) {\n const aggregated = log.wrap(\"react\", log => {\n return this._aggregateAnnotation(sourceEntry.event, targetStorageEntry, log);\n });\n if (aggregated) {\n return [targetStorageEntry];\n }\n }\n }\n }\n return null;\n }\n\n _applyRedaction(redactionEvent, redactedStorageEntry, txn, log) {\n const redactedEvent = redactedStorageEntry.event;\n log.set(\"redactionId\", redactionEvent.event_id);\n log.set(\"id\", redactedEvent.event_id);\n\n const relation = getRelation(redactedEvent);\n if (relation && relation.rel_type) {\n txn.timelineRelations.remove(this._roomId, relation.event_id, relation.rel_type, redactedEvent.event_id);\n }\n // check if we're the target of a relation and remove all relations then as well\n txn.timelineRelations.removeAllForTarget(this._roomId, redactedEvent.event_id);\n\n redactEvent(redactionEvent, redactedEvent);\n delete redactedStorageEntry.annotations;\n\n return true;\n }\n\n _aggregateAnnotation(annotationEvent, targetStorageEntry/*, log*/) {\n // TODO: do we want to verify it is a m.reaction event somehow?\n const relation = getRelation(annotationEvent);\n if (!relation) {\n return false;\n }\n\n let {annotations} = targetStorageEntry;\n if (!annotations) {\n targetStorageEntry.annotations = annotations = {};\n }\n let annotation = annotations[relation.key];\n if (!annotation) {\n annotations[relation.key] = annotation = {\n count: 0,\n me: false,\n firstTimestamp: Number.MAX_SAFE_INTEGER\n };\n }\n const sentByMe = annotationEvent.sender === this._ownUserId;\n\n annotation.me = annotation.me || sentByMe;\n annotation.count += 1;\n annotation.firstTimestamp = Math.min(\n annotation.firstTimestamp,\n annotationEvent.origin_server_ts\n );\n\n return true;\n }\n\n async _reaggregateRelation(redactedRelationEvent, redactedRelation, txn, log) {\n if (redactedRelation.rel_type === ANNOTATION_RELATION_TYPE) {\n return log.wrap(\"reaggregate annotations\", log => this._reaggregateAnnotation(\n redactedRelation.event_id,\n redactedRelation.key,\n txn, log\n ));\n }\n return null;\n }\n\n async _reaggregateAnnotation(targetId, key, txn, log) {\n const target = await txn.timelineEvents.getByEventId(this._roomId, targetId);\n if (!target || !target.annotations) { // unknown or redacted event\n return null;\n }\n log.set(\"id\", targetId);\n const relations = await txn.timelineRelations.getForTargetAndType(this._roomId, targetId, ANNOTATION_RELATION_TYPE);\n log.set(\"relations\", relations.length);\n delete target.annotations[key];\n if (isObjectEmpty(target.annotations)) {\n delete target.annotations;\n }\n await Promise.all(relations.map(async relation => {\n const annotation = await txn.timelineEvents.getByEventId(this._roomId, relation.sourceEventId);\n if (!annotation) {\n log.log({l: \"missing annotation\", id: relation.sourceEventId});\n }\n if (getRelation(annotation.event).key === key) {\n this._aggregateAnnotation(annotation.event, target, log);\n }\n }));\n return target;\n }\n}\n\nfunction isObjectEmpty(obj) {\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n return false;\n }\n }\n return true;\n}\n\n\nimport {createMockStorage} from \"../../../../mocks/Storage\";\nimport {createEvent, withTextBody, withRedacts, withContent} from \"../../../../mocks/event.js\";\nimport {createAnnotation} from \"../relations.js\";\nimport {FragmentIdComparer} from \"../FragmentIdComparer.js\";\nimport {NullLogItem} from \"../../../../logging/NullLogger\";\n\nexport function tests() {\n const fragmentIdComparer = new FragmentIdComparer([]);\n const roomId = \"$abc\";\n const alice = \"@alice:hs.tld\";\n const bob = \"@bob:hs.tld\";\n\n return {\n \"apply redaction\": async assert => {\n const event = withTextBody(\"Dogs > Cats\", createEvent(\"m.room.message\", \"!abc\", bob));\n const reason = \"nonsense, cats are the best!\";\n const redaction = withRedacts(event.event_id, reason, createEvent(\"m.room.redaction\", \"!def\", alice));\n const redactionEntry = new EventEntry({fragmentId: 1, eventIndex: 3, event: redaction, roomId}, fragmentIdComparer);\n const relationWriter = new RelationWriter({roomId, ownUserId: bob, fragmentIdComparer});\n\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 2, event, roomId}, new NullLogItem());\n const updatedEntries = await relationWriter.writeRelation(redactionEntry, txn, new NullLogItem());\n await txn.complete();\n\n assert.equal(updatedEntries.length, 1);\n const redactedMessage = updatedEntries[0];\n assert.equal(redactedMessage.id, \"!abc\");\n assert.equal(redactedMessage.content.body, undefined);\n assert.equal(redactedMessage.redactionReason, reason);\n \n const readTxn = await storage.readTxn([storage.storeNames.timelineEvents]);\n const storedMessage = await readTxn.timelineEvents.getByEventId(roomId, \"!abc\");\n await readTxn.complete();\n assert.equal(storedMessage.event.content.body, undefined);\n assert.equal(storedMessage.event.unsigned.redacted_because.content.reason, reason);\n },\n \"aggregate reaction\": async assert => {\n const event = withTextBody(\"Dogs > Cats\", createEvent(\"m.room.message\", \"!abc\", bob));\n const reaction = withContent(createAnnotation(event.event_id, \"🐶\"), createEvent(\"m.reaction\", \"!def\", alice));\n reaction.origin_server_ts = 5;\n const reactionEntry = new EventEntry({event: reaction, roomId}, fragmentIdComparer);\n const relationWriter = new RelationWriter({roomId, ownUserId: alice, fragmentIdComparer});\n\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 2, event, roomId}, new NullLogItem());\n const updatedEntries = await relationWriter.writeRelation(reactionEntry, txn, new NullLogItem());\n await txn.complete();\n\n assert.equal(updatedEntries.length, 1);\n const reactedMessage = updatedEntries[0];\n assert.equal(reactedMessage.id, \"!abc\");\n const annotation = reactedMessage.annotations[\"🐶\"];\n assert.equal(annotation.me, true);\n assert.equal(annotation.count, 1);\n assert.equal(annotation.firstTimestamp, 5);\n \n const readTxn = await storage.readTxn([storage.storeNames.timelineEvents]);\n const storedMessage = await readTxn.timelineEvents.getByEventId(roomId, \"!abc\");\n await readTxn.complete();\n assert(storedMessage.annotations[\"🐶\"]);\n },\n \"aggregate second reaction\": async assert => {\n const event = withTextBody(\"Dogs > Cats\", createEvent(\"m.room.message\", \"!abc\", bob));\n const reaction1 = withContent(createAnnotation(event.event_id, \"🐶\"), createEvent(\"m.reaction\", \"!def\", alice));\n reaction1.origin_server_ts = 5;\n const reaction1Entry = new EventEntry({event: reaction1, roomId}, fragmentIdComparer);\n const reaction2 = withContent(createAnnotation(event.event_id, \"🐶\"), createEvent(\"m.reaction\", \"!hij\", bob));\n reaction2.origin_server_ts = 10;\n const reaction2Entry = new EventEntry({event: reaction2, roomId}, fragmentIdComparer);\n const relationWriter = new RelationWriter({roomId, ownUserId: alice, fragmentIdComparer});\n\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 2, event, roomId}, new NullLogItem());\n await relationWriter.writeRelation(reaction1Entry, txn, new NullLogItem());\n const updatedEntries = await relationWriter.writeRelation(reaction2Entry, txn, new NullLogItem());\n await txn.complete();\n\n assert.equal(updatedEntries.length, 1);\n\n const reactedMessage = updatedEntries[0];\n assert.equal(reactedMessage.id, \"!abc\");\n const annotation = reactedMessage.annotations[\"🐶\"];\n assert.equal(annotation.me, true);\n assert.equal(annotation.count, 2);\n assert.equal(annotation.firstTimestamp, 5);\n },\n \"redact second reaction\": async assert => {\n const event = withTextBody(\"Dogs > Cats\", createEvent(\"m.room.message\", \"!abc\", bob));\n const myReaction = withContent(createAnnotation(event.event_id, \"🐶\"), createEvent(\"m.reaction\", \"!def\", alice));\n myReaction.origin_server_ts = 5;\n const bobReaction = withContent(createAnnotation(event.event_id, \"🐶\"), createEvent(\"m.reaction\", \"!hij\", bob));\n bobReaction.origin_server_ts = 10;\n const myReactionRedaction = withRedacts(myReaction.event_id, \"\", createEvent(\"m.room.redaction\", \"!pol\", alice));\n\n const myReactionEntry = new EventEntry({event: myReaction, roomId}, fragmentIdComparer);\n const bobReactionEntry = new EventEntry({event: bobReaction, roomId}, fragmentIdComparer);\n const myReactionRedactionEntry = new EventEntry({event: myReactionRedaction, roomId}, fragmentIdComparer);\n const relationWriter = new RelationWriter({roomId, ownUserId: alice, fragmentIdComparer});\n\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 2, event, roomId}, new NullLogItem());\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 3, event: myReaction, roomId}, new NullLogItem());\n await relationWriter.writeRelation(myReactionEntry, txn, new NullLogItem());\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 4, event: bobReaction, roomId}, new NullLogItem());\n await relationWriter.writeRelation(bobReactionEntry, txn, new NullLogItem());\n const updatedEntries = await relationWriter.writeRelation(myReactionRedactionEntry, txn, new NullLogItem());\n await txn.complete();\n\n assert.equal(updatedEntries.length, 2);\n\n const redactedReaction = updatedEntries[0];\n assert.equal(redactedReaction.id, \"!def\");\n const reaggregatedMessage = updatedEntries[1];\n assert.equal(reaggregatedMessage.id, \"!abc\");\n const annotation = reaggregatedMessage.annotations[\"🐶\"];\n assert.equal(annotation.me, false);\n assert.equal(annotation.count, 1);\n assert.equal(annotation.firstTimestamp, 10);\n\n const readTxn = await storage.readTxn([storage.storeNames.timelineEvents]);\n const storedMessage = await readTxn.timelineEvents.getByEventId(roomId, \"!abc\");\n await readTxn.complete();\n assert.equal(storedMessage.annotations[\"🐶\"].count, 1);\n },\n \n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class Direction {\n constructor(public readonly isForward: boolean) {\n }\n\n get isBackward(): boolean {\n return !this.isForward;\n }\n\n asApiString(): string {\n return this.isForward ? \"f\" : \"b\";\n }\n\n reverse(): Direction {\n return this.isForward ? Direction.Backward : Direction.Forward\n }\n\n static get Forward(): Direction {\n return _forward;\n }\n\n static get Backward(): Direction {\n return _backward;\n }\n}\n\nconst _forward = new Direction(true);\nconst _backward = new Direction(false);\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseEntry} from \"./BaseEntry\";\nimport {Direction} from \"../Direction\";\nimport {isValidFragmentId} from \"../common.js\";\nimport {KeyLimits} from \"../../../storage/common\";\n\nexport class FragmentBoundaryEntry extends BaseEntry {\n constructor(fragment, isFragmentStart, fragmentIdComparer) {\n super(fragmentIdComparer);\n this._fragment = fragment;\n // TODO: should isFragmentStart be Direction instead of bool?\n this._isFragmentStart = isFragmentStart;\n }\n\n static start(fragment, fragmentIdComparer) {\n return new FragmentBoundaryEntry(fragment, true, fragmentIdComparer);\n }\n\n static end(fragment, fragmentIdComparer) {\n return new FragmentBoundaryEntry(fragment, false, fragmentIdComparer);\n }\n \n get started() {\n return this._isFragmentStart;\n }\n\n get hasEnded() {\n return !this.started;\n }\n\n get fragment() {\n return this._fragment;\n }\n\n get fragmentId() {\n return this._fragment.id;\n }\n\n get entryIndex() {\n if (this.started) {\n return KeyLimits.minStorageKey;\n } else {\n return KeyLimits.maxStorageKey;\n }\n }\n\n get isGap() {\n return !!this.token && !this.edgeReached;\n }\n\n get token() {\n if (this.started) {\n return this.fragment.previousToken;\n } else {\n return this.fragment.nextToken;\n }\n }\n\n set token(token) {\n if (this.started) {\n this.fragment.previousToken = token;\n } else {\n this.fragment.nextToken = token;\n }\n }\n\n get edgeReached() {\n if (this.started) {\n return this.fragment.startReached;\n } else {\n return this.fragment.endReached;\n }\n }\n\n set edgeReached(reached) {\n \n if (this.started) {\n this.fragment.startReached = reached;\n } else {\n this.fragment.endReached = reached;\n }\n }\n\n \n\n get linkedFragmentId() {\n if (this.started) {\n return this.fragment.previousId;\n } else {\n return this.fragment.nextId;\n }\n }\n\n set linkedFragmentId(id) {\n if (this.started) {\n this.fragment.previousId = id;\n } else {\n this.fragment.nextId = id;\n }\n }\n\n get hasLinkedFragment() {\n return isValidFragmentId(this.linkedFragmentId);\n }\n\n get direction() {\n if (this.started) {\n return Direction.Backward;\n } else {\n return Direction.Forward;\n }\n }\n\n withUpdatedFragment(fragment) {\n return new FragmentBoundaryEntry(fragment, this._isFragmentStart, this._fragmentIdComparer);\n }\n\n createNeighbourEntry(neighbour) {\n return new FragmentBoundaryEntry(neighbour, !this._isFragmentStart, this._fragmentIdComparer);\n }\n\n addLocalRelation() {}\n removeLocalRelation() {}\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventKey} from \"../EventKey\";\nimport {EventEntry} from \"../entries/EventEntry.js\";\nimport {FragmentBoundaryEntry} from \"../entries/FragmentBoundaryEntry.js\";\nimport {createEventEntry} from \"./common.js\";\nimport {EVENT_TYPE as MEMBER_EVENT_TYPE} from \"../../members/RoomMember.js\";\n\n// Synapse bug? where the m.room.create event appears twice in sync response\n// when first syncing the room\nfunction deduplicateEvents(events) {\n const eventIds = new Set();\n return events.filter(e => {\n if (eventIds.has(e.event_id)) {\n return false;\n } else {\n eventIds.add(e.event_id);\n return true;\n }\n });\n}\n\nexport class SyncWriter {\n constructor({roomId, fragmentIdComparer, memberWriter, relationWriter}) {\n this._roomId = roomId;\n this._memberWriter = memberWriter;\n this._relationWriter = relationWriter;\n this._fragmentIdComparer = fragmentIdComparer;\n this._lastLiveKey = null;\n }\n\n async load(txn, log) {\n const liveFragment = await txn.timelineFragments.liveFragment(this._roomId);\n if (liveFragment) {\n const [lastEvent] = await txn.timelineEvents.lastEvents(this._roomId, liveFragment.id, 1);\n // fall back to the default event index in case the fragment was somehow written but no events\n // we should only create fragments when really writing timeline events now\n // (see https://github.com/vector-im/hydrogen-web/issues/112) but can't hurt to be extra robust.\n const eventIndex = lastEvent ? lastEvent.eventIndex : EventKey.defaultLiveKey.eventIndex;\n this._lastLiveKey = new EventKey(liveFragment.id, eventIndex);\n }\n // if there is no live fragment, we don't create it here because load gets a readonly txn.\n // this is on purpose, load shouldn't modify the store\n if (this._lastLiveKey) {\n log.set(\"live key\", this._lastLiveKey.toString());\n }\n }\n\n async _createLiveFragment(txn, previousToken) {\n const liveFragment = await txn.timelineFragments.liveFragment(this._roomId);\n if (!liveFragment) {\n if (!previousToken) {\n previousToken = null;\n }\n const fragment = {\n roomId: this._roomId,\n id: EventKey.defaultLiveKey.fragmentId,\n previousId: null,\n nextId: null,\n previousToken: previousToken,\n nextToken: null\n };\n txn.timelineFragments.add(fragment);\n this._fragmentIdComparer.add(fragment);\n return fragment;\n } else {\n return liveFragment;\n }\n }\n\n async _replaceLiveFragment(oldFragmentId, newFragmentId, previousToken, txn) {\n const oldFragment = await txn.timelineFragments.get(this._roomId, oldFragmentId);\n if (!oldFragment) {\n throw new Error(`old live fragment doesn't exist: ${oldFragmentId}`);\n }\n oldFragment.nextId = newFragmentId;\n txn.timelineFragments.update(oldFragment);\n const newFragment = {\n roomId: this._roomId,\n id: newFragmentId,\n previousId: oldFragmentId,\n nextId: null,\n previousToken: previousToken,\n nextToken: null\n };\n txn.timelineFragments.add(newFragment);\n this._fragmentIdComparer.append(newFragmentId, oldFragmentId);\n return {oldFragment, newFragment};\n }\n\n /**\n * creates a new live fragment if the timeline is limited, or if no live fragment is created yet\n * @param {EventKey} currentKey current key so far, might be none if room hasn't synced yet\n * @param {Array} entries array to add fragment boundary entries when creating a new fragment\n * @param {Object} timeline timeline part of the room sync response\n * @param {Transaction} txn used to read and write from the fragment store\n * @return {EventKey} the new event key to start writing events at\n */\n async _ensureLiveFragment(currentKey, entries, timeline, txn, log) {\n if (!currentKey) {\n // means we haven't synced this room yet (just joined or did initial sync)\n \n // as this is probably a limited sync, prev_batch should be there\n // (but don't fail if it isn't, we won't be able to back-paginate though)\n let liveFragment = await this._createLiveFragment(txn, timeline.prev_batch);\n currentKey = new EventKey(liveFragment.id, EventKey.defaultLiveKey.eventIndex);\n entries.push(FragmentBoundaryEntry.start(liveFragment, this._fragmentIdComparer));\n log.log({l: \"live fragment\", first: true, id: currentKey.fragmentId});\n } else if (timeline.limited) {\n // replace live fragment for limited sync, *only* if we had a live fragment already\n const oldFragmentId = currentKey.fragmentId;\n currentKey = currentKey.nextFragmentKey();\n const {oldFragment, newFragment} = await this._replaceLiveFragment(oldFragmentId, currentKey.fragmentId, timeline.prev_batch, txn);\n entries.push(FragmentBoundaryEntry.end(oldFragment, this._fragmentIdComparer));\n entries.push(FragmentBoundaryEntry.start(newFragment, this._fragmentIdComparer));\n log.log({l: \"live fragment\", limited: true, id: currentKey.fragmentId});\n }\n return currentKey;\n }\n\n async _writeStateEvents(stateEvents, txn, log) {\n let nonMemberStateEvents = 0;\n for (const event of stateEvents) {\n // member events are written prior by MemberWriter\n if (event.type !== MEMBER_EVENT_TYPE) {\n txn.roomState.set(this._roomId, event);\n nonMemberStateEvents += 1;\n }\n }\n log.set(\"stateEvents\", nonMemberStateEvents);\n }\n\n async _writeTimeline(timelineEvents, timeline, memberSync, currentKey, txn, log) {\n const entries = [];\n const updatedEntries = [];\n if (timelineEvents?.length) {\n // only create a fragment when we will really write an event\n currentKey = await this._ensureLiveFragment(currentKey, entries, timeline, txn, log);\n log.set(\"timelineEvents\", timelineEvents.length);\n let timelineStateEventCount = 0;\n for(const event of timelineEvents) {\n // store event in timeline\n currentKey = currentKey.nextKey();\n const storageEntry = createEventEntry(currentKey, this._roomId, event);\n let member = await memberSync.lookupMemberAtEvent(event.sender, event, txn);\n if (member) {\n storageEntry.displayName = member.displayName;\n storageEntry.avatarUrl = member.avatarUrl;\n }\n const couldInsert = await txn.timelineEvents.tryInsert(storageEntry, log);\n if (!couldInsert) {\n continue;\n }\n const entry = new EventEntry(storageEntry, this._fragmentIdComparer);\n entries.push(entry);\n const updatedRelationTargetEntries = await this._relationWriter.writeRelation(entry, txn, log);\n if (updatedRelationTargetEntries) {\n updatedEntries.push(...updatedRelationTargetEntries);\n }\n // update state events after writing event, so for a member event,\n // we only update the member info after having written the member event\n // to the timeline, as we want that event to have the old profile info.\n // member events are written prior by MemberWriter.\n if (typeof event.state_key === \"string\" && event.type !== MEMBER_EVENT_TYPE) {\n timelineStateEventCount += 1;\n txn.roomState.set(this._roomId, event);\n }\n }\n log.set(\"timelineStateEventCount\", timelineStateEventCount);\n }\n return {currentKey, entries, updatedEntries};\n }\n\n async _handleRejoinOverlap(timeline, txn, log) {\n if (this._lastLiveKey) {\n const {fragmentId} = this._lastLiveKey;\n const [lastEvent] = await txn.timelineEvents.lastEvents(this._roomId, fragmentId, 1);\n if (lastEvent) {\n const lastEventId = lastEvent.event.event_id;\n const {events} = timeline;\n const index = events.findIndex(event => event.event_id === lastEventId);\n if (index !== -1) {\n log.set(\"overlap_event_id\", lastEventId);\n return Object.assign({}, timeline, {\n limited: false,\n events: events.slice(index + 1),\n });\n }\n }\n }\n if (!timeline.limited) {\n log.set(\"force_limited_without_overlap\", true);\n return Object.assign({}, timeline, {limited: true});\n }\n return timeline;\n }\n\n /**\n * @type {SyncWriterResult}\n * @property {Array} entries new timeline entries written\n * @property {EventKey} newLiveKey the advanced key to write events at\n * \n * @param {Object} roomResponse [description]\n * @param {boolean} isRejoin whether the room was rejoined in the sync being processed\n * @param {Transaction} txn \n * @return {SyncWriterResult}\n */\n async writeSync(roomResponse, isRejoin, hasFetchedMembers, txn, log) {\n let {timeline} = roomResponse;\n // we have rejoined the room after having synced it before,\n // check for overlap with the last synced event\n log.set(\"isRejoin\", isRejoin);\n if (isRejoin) {\n timeline = await this._handleRejoinOverlap(timeline, txn, log);\n }\n let timelineEvents;\n if (Array.isArray(timeline?.events)) {\n timelineEvents = deduplicateEvents(timeline.events);\n }\n const {state} = roomResponse;\n let stateEvents;\n if (Array.isArray(state?.events)) {\n stateEvents = state.events;\n }\n const memberSync = this._memberWriter.prepareMemberSync(stateEvents, timelineEvents, hasFetchedMembers);\n if (stateEvents) {\n await this._writeStateEvents(stateEvents, txn, log);\n }\n const {currentKey, entries, updatedEntries} =\n await this._writeTimeline(timelineEvents, timeline, memberSync, this._lastLiveKey, txn, log);\n const memberChanges = await memberSync.write(txn);\n return {entries, updatedEntries, newLiveKey: currentKey, memberChanges, memberSync};\n }\n\n afterSync(newLiveKey) {\n this._lastLiveKey = newLiveKey;\n }\n\n get lastMessageKey() {\n return this._lastLiveKey;\n }\n}\n\nimport {createMockStorage} from \"../../../../mocks/Storage\";\nimport {createEvent, withTextBody} from \"../../../../mocks/event.js\";\nimport {Instance as nullLogger} from \"../../../../logging/NullLogger\";\nexport function tests() {\n const roomId = \"!abc:hs.tld\";\n return {\n \"calling timelineEvents.tryInsert with the same event id a second time fails\": async assert => {\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents]);\n const event = withTextBody(\"hello!\", createEvent(\"m.room.message\", \"$abc\", \"@alice:hs.tld\"));\n const entry1 = createEventEntry(EventKey.defaultLiveKey, roomId, event);\n assert.equal(await txn.timelineEvents.tryInsert(entry1, nullLogger.item), true);\n const entry2 = createEventEntry(EventKey.defaultLiveKey.nextKey(), roomId, event);\n assert.equal(await txn.timelineEvents.tryInsert(entry2, nullLogger.item), false);\n // fake-indexeddb still aborts the transaction when preventDefault is called by tryInsert, so don't await as it will abort\n // await txn.complete();\n },\n \"calling timelineEvents.tryInsert with the same event key a second time fails\": async assert => {\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents]);\n const event1 = withTextBody(\"hello!\", createEvent(\"m.room.message\", \"$abc\", \"@alice:hs.tld\"));\n const entry1 = createEventEntry(EventKey.defaultLiveKey, roomId, event1);\n assert.equal(await txn.timelineEvents.tryInsert(entry1, nullLogger.item), true);\n const event2 = withTextBody(\"hello!\", createEvent(\"m.room.message\", \"$def\", \"@alice:hs.tld\"));\n const entry2 = createEventEntry(EventKey.defaultLiveKey, roomId, event2);\n assert.equal(await txn.timelineEvents.tryInsert(entry2, nullLogger.item), false);\n // fake-indexeddb still aborts the transaction when preventDefault is called by tryInsert, so don't await as it will abort\n // await txn.complete();\n },\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n\ntype FindCallback = (value: T) => boolean;\n/**\n * Very simple least-recently-used cache implementation\n * that should be fast enough for very small cache sizes\n */\nexport class BaseLRUCache {\n\n public readonly limit: number;\n protected _entries: T[];\n\n constructor(limit: number) {\n this.limit = limit;\n this._entries = [];\n }\n\n get size() { return this._entries.length; }\n\n protected _get(findEntryFn: FindCallback) {\n return this._getByIndexAndMoveUp(this._entries.findIndex(findEntryFn));\n }\n\n protected _getByIndexAndMoveUp(idx: number) {\n if (idx !== -1) {\n const entry = this._entries[idx];\n // move to top\n if (idx > 0) {\n this._entries.splice(idx, 1);\n this._entries.unshift(entry);\n }\n return entry;\n }\n }\n\n protected _set(value: T, findEntryFn?: FindCallback) {\n let indexToRemove = findEntryFn ? this._entries.findIndex(findEntryFn) : -1;\n this._entries.unshift(value);\n if (indexToRemove === -1) {\n if (this._entries.length > this.limit) {\n indexToRemove = this._entries.length - 1;\n }\n } else {\n // we added the entry at the start since we looked for the index\n indexToRemove += 1;\n }\n if (indexToRemove !== -1) {\n this.onEvictEntry(this._entries[indexToRemove]);\n this._entries.splice(indexToRemove, 1);\n }\n }\n\n protected onEvictEntry(entry: T) {}\n}\n\nexport class LRUCache extends BaseLRUCache {\n private _keyFn: (T) => K;\n\n constructor(limit: number, keyFn: (T) => K) {\n super(limit);\n this._keyFn = keyFn;\n }\n\n get(key: K): T | undefined {\n return this._get(e => this._keyFn(e) === key);\n }\n\n set(value: T) {\n const key = this._keyFn(value);\n this._set(value, e => this._keyFn(e) === key);\n }\n}\n\nexport function tests() {\n interface NameTuple {\n id: number;\n name: string;\n }\n\n return {\n \"can retrieve added entries\": assert => {\n const cache = new LRUCache(2, e => e.id);\n cache.set({id: 1, name: \"Alice\"});\n cache.set({id: 2, name: \"Bob\"});\n assert.equal(cache.get(1)!.name, \"Alice\");\n assert.equal(cache.get(2)!.name, \"Bob\");\n },\n \"first entry is evicted first\": assert => {\n const cache = new LRUCache(2, e => e.id);\n cache.set({id: 1, name: \"Alice\"});\n cache.set({id: 2, name: \"Bob\"});\n cache.set({id: 3, name: \"Charly\"});\n assert.equal(cache.get(1), undefined);\n assert.equal(cache.get(2)!.name, \"Bob\");\n assert.equal(cache.get(3)!.name, \"Charly\");\n assert.equal(cache.size, 2);\n },\n \"second entry is evicted if first is requested\": assert => {\n const cache = new LRUCache(2, e => e.id);\n cache.set({id: 1, name: \"Alice\"});\n cache.set({id: 2, name: \"Bob\"});\n cache.get(1);\n cache.set({id: 3, name: \"Charly\"});\n assert.equal(cache.get(1)!.name, \"Alice\");\n assert.equal(cache.get(2), undefined);\n assert.equal(cache.get(3)!.name, \"Charly\");\n assert.equal(cache.size, 2);\n },\n \"setting an entry twice removes the first\": assert => {\n const cache = new LRUCache(2, e => e.id);\n cache.set({id: 1, name: \"Alice\"});\n cache.set({id: 2, name: \"Bob\"});\n cache.set({id: 1, name: \"Al Ice\"});\n cache.set({id: 3, name: \"Charly\"});\n assert.equal(cache.get(1)!.name, \"Al Ice\");\n assert.equal(cache.get(2), undefined);\n assert.equal(cache.get(3)!.name, \"Charly\");\n assert.equal(cache.size, 2);\n },\n \"evict callback is called\": assert => {\n let evictions = 0;\n class CustomCache extends LRUCache {\n onEvictEntry(entry) {\n assert.equal(entry.name, \"Alice\");\n evictions += 1;\n }\n }\n const cache = new CustomCache(2, e => e.id);\n cache.set({id: 1, name: \"Alice\"});\n cache.set({id: 2, name: \"Bob\"});\n cache.set({id: 3, name: \"Charly\"});\n assert.equal(evictions, 1);\n },\n \"evict callback is called when replacing entry with same identity\": assert => {\n let evictions = 0;\n class CustomCache extends LRUCache {\n onEvictEntry(entry) {\n assert.equal(entry.name, \"Alice\");\n evictions += 1;\n }\n }\n const cache = new CustomCache(2, e => e.id);\n cache.set({id: 1, name: \"Alice\"});\n cache.set({id: 1, name: \"Bob\"});\n assert.equal(evictions, 1);\n },\n \n };\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MemberChange, RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from \"../../members/RoomMember.js\";\nimport {LRUCache} from \"../../../../utils/LRUCache\";\n\nexport class MemberWriter {\n constructor(roomId) {\n this._roomId = roomId;\n this._cache = new LRUCache(5, member => member.userId);\n }\n\n prepareMemberSync(stateEvents, timelineEvents, hasFetchedMembers) {\n return new MemberSync(this, stateEvents, timelineEvents, hasFetchedMembers);\n }\n\n async _writeMember(member, txn) {\n let existingMember = this._cache.get(member.userId);\n if (!existingMember) {\n const memberData = await txn.roomMembers.get(this._roomId, member.userId);\n if (memberData) {\n existingMember = new RoomMember(memberData);\n }\n }\n // either never heard of the member, or something changed\n if (!existingMember || !existingMember.equals(member)) {\n txn.roomMembers.set(member.serialize());\n this._cache.set(member);\n return new MemberChange(member, existingMember?.membership);\n }\n }\n\n async lookupMember(userId, txn) {\n let member = this._cache.get(userId);\n if (!member) {\n const memberData = await txn.roomMembers.get(this._roomId, userId);\n if (memberData) {\n member = new RoomMember(memberData);\n this._cache.set(member);\n }\n }\n return member;\n }\n}\n\n/** Represents the member changes in a given sync.\n * Used to write the changes to storage and historical member\n * information for events in the same sync.\n **/\nexport class MemberSync {\n constructor(memberWriter, stateEvents, timelineEvents, hasFetchedMembers) {\n this._memberWriter = memberWriter;\n this._timelineEvents = timelineEvents;\n this._hasFetchedMembers = hasFetchedMembers;\n this._newStateMembers = null;\n if (stateEvents) {\n this._newStateMembers = this._stateEventsToMembers(stateEvents);\n }\n }\n\n get _roomId() {\n return this._memberWriter._roomId;\n }\n\n _stateEventsToMembers(stateEvents) {\n let members;\n for (const event of stateEvents) {\n if (event.type === MEMBER_EVENT_TYPE) {\n const member = RoomMember.fromMemberEvent(this._roomId, event);\n if (member) {\n if (!members) {\n members = new Map();\n }\n members.set(member.userId, member);\n }\n }\n }\n return members;\n }\n\n _timelineEventsToMembers(timelineEvents) {\n let members;\n // iterate backwards to only add the last member in the timeline\n for (let i = timelineEvents.length - 1; i >= 0; i--) {\n const e = timelineEvents[i];\n const userId = e.state_key;\n if (e.type === MEMBER_EVENT_TYPE && !members?.has(userId)) {\n const member = RoomMember.fromMemberEvent(this._roomId, e);\n if (member) {\n if (!members) {\n members = new Map();\n }\n members.set(member.userId, member);\n }\n }\n }\n return members;\n }\n\n async lookupMemberAtEvent(userId, event, txn) {\n let member;\n if (this._timelineEvents) {\n member = this._findPrecedingMemberEventInTimeline(userId, event);\n if (member) {\n return member;\n }\n }\n member = this._newStateMembers?.get(userId);\n if (member) {\n return member;\n }\n return await this._memberWriter.lookupMember(userId, txn);\n }\n\n async write(txn) {\n const memberChanges = new Map();\n let newTimelineMembers;\n if (this._timelineEvents) {\n newTimelineMembers = this._timelineEventsToMembers(this._timelineEvents);\n }\n if (this._newStateMembers) {\n for (const member of this._newStateMembers.values()) {\n if (!newTimelineMembers?.has(member.userId)) {\n const memberChange = await this._memberWriter._writeMember(member, txn);\n if (memberChange) {\n // if the member event appeared only in the state section,\n // AND we haven't heard about it AND we haven't fetched all members yet (to avoid #470),\n // this may be a lazy loading member (if it's not in a gap, we are certain\n // it is a ll member, in a gap, we can't tell), so we pass in our own membership as\n // as the previous one so we won't consider it a join to not have false positives (to avoid #192).\n // see also MemberChange.hasJoined\n const maybeLazyLoadingMember = !this._hasFetchedMembers && !memberChange.previousMembership;\n if (maybeLazyLoadingMember) {\n memberChange.previousMembership = member.membership;\n }\n memberChanges.set(memberChange.userId, memberChange);\n }\n }\n }\n }\n if (newTimelineMembers) {\n for (const member of newTimelineMembers.values()) {\n const memberChange = await this._memberWriter._writeMember(member, txn);\n if (memberChange) {\n memberChanges.set(memberChange.userId, memberChange);\n }\n }\n }\n return memberChanges;\n }\n\n // try to find the first member event before the given event,\n // so we respect historical display names within the chunk of timeline\n _findPrecedingMemberEventInTimeline(userId, event) {\n let eventIndex = -1;\n for (let i = this._timelineEvents.length - 1; i >= 0; i--) {\n const e = this._timelineEvents[i];\n if (e.event_id === event.event_id) {\n eventIndex = i;\n break;\n }\n }\n for (let i = eventIndex - 1; i >= 0; i--) {\n const e = this._timelineEvents[i];\n if (e.type === MEMBER_EVENT_TYPE && e.state_key === userId) {\n const member = RoomMember.fromMemberEvent(this._roomId, e);\n if (member) {\n return member;\n }\n }\n }\n }\n}\n\nexport function tests() {\n\n let idCounter = 0;\n\n function createMemberEvent(membership, userId, displayName, avatarUrl) {\n idCounter += 1;\n return {\n content: {\n membership,\n \"displayname\": displayName,\n \"avatar_url\": avatarUrl\n },\n event_id: `$${idCounter}`,\n sender: userId,\n \"state_key\": userId,\n type: \"m.room.member\"\n };\n }\n\n function createStorage(initialMembers = []) {\n const members = new Map();\n for (const m of initialMembers) {\n members.set(m.userId, m);\n }\n return {\n members,\n roomMembers: {\n async get(_, userId) {\n return members.get(userId);\n },\n set(member) {\n members.set(member.userId, member);\n }\n }\n }\n }\n\n function member(...args) {\n return RoomMember.fromMemberEvent(roomId, createMemberEvent.apply(null, args));\n }\n\n const roomId = \"abc\";\n const alice = \"@alice:hs.tld\";\n const avatar = \"mxc://hs.tld/def\";\n\n return {\n \"new join\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"join\", alice)], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasJoined);\n assert.equal(txn.members.get(alice).membership, \"join\");\n },\n \"accept invite\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"invite\", alice)]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"join\", alice)], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert.equal(change.previousMembership, \"invite\");\n assert(change.hasJoined);\n assert.equal(txn.members.get(alice).membership, \"join\");\n },\n \"change display name\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"join\", alice, \"Alies\")], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(!change.hasJoined);\n assert.equal(change.member.displayName, \"Alies\");\n assert.equal(txn.members.get(alice).displayName, \"Alies\");\n },\n \"set avatar\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"join\", alice, \"Alice\", avatar)], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(!change.hasJoined);\n assert.equal(change.member.avatarUrl, avatar);\n assert.equal(txn.members.get(alice).avatarUrl, avatar);\n },\n \"ignore redundant member event in timeline\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\", avatar)]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"join\", alice, \"Alice\", avatar)], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 0);\n },\n \"ignore redundant member event in state\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\", avatar)]);\n const memberSync = writer.prepareMemberSync([createMemberEvent(\"join\", alice, \"Alice\", avatar)], [], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 0);\n },\n \"leave\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"leave\", alice, \"Alice\")], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasLeft);\n assert(!change.hasJoined);\n },\n \"ban\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"ban\", alice, \"Alice\")], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasLeft);\n assert(!change.hasJoined);\n },\n \"reject invite\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"invite\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([], [createMemberEvent(\"leave\", alice, \"Alice\")], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(!change.hasLeft);\n assert(!change.hasJoined);\n },\n \"lazy loaded member we already know about doens't return change\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([createMemberEvent(\"join\", alice, \"Alice\")], [], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 0);\n },\n \"lazy loaded member we already know about changes display name\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage([member(\"join\", alice, \"Alice\")]);\n const memberSync = writer.prepareMemberSync([createMemberEvent(\"join\", alice, \"Alies\")], [], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(!change.hasJoined);\n assert.equal(change.member.displayName, \"Alies\");\n },\n \"unknown lazy loaded member returns change, but not considered a join\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const memberSync = writer.prepareMemberSync([createMemberEvent(\"join\", alice, \"Alice\")], [], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(!change.hasJoined);\n assert(!change.hasLeft);\n assert.equal(change.member.membership, \"join\");\n assert.equal(txn.members.get(alice).displayName, \"Alice\");\n },\n \"new join through both timeline and state\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const aliceJoin = createMemberEvent(\"join\", alice, \"Alice\");\n const memberSync = writer.prepareMemberSync([aliceJoin], [aliceJoin], false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasJoined);\n assert(!change.hasLeft);\n },\n \"change display name in timeline with lazy loaded member in state\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const memberSync = writer.prepareMemberSync(\n [createMemberEvent(\"join\", alice, \"Alice\")],\n [createMemberEvent(\"join\", alice, \"Alies\")],\n false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasJoined);\n assert(!change.hasLeft);\n assert.equal(change.member.displayName, \"Alies\");\n },\n \"lookupMemberAtEvent returns closest member in the past\": async assert => {\n const event1 = createMemberEvent(\"join\", alice, \"Alice\");\n const event2 = createMemberEvent(\"join\", alice, \"Alies\");\n const event3 = createMemberEvent(\"join\", alice, \"Alys\");\n const events = [event1, event2, event3];\n // we write first because the MemberWriter assumes it is called before\n // the SyncWriter does any lookups\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const memberSync = await writer.prepareMemberSync([], events, false);\n let member = await memberSync.lookupMemberAtEvent(event1.sender, event1, txn);\n assert.equal(member, undefined);\n member = await memberSync.lookupMemberAtEvent(event2.sender, event2, txn);\n assert.equal(member.displayName, \"Alice\");\n member = await memberSync.lookupMemberAtEvent(event3.sender, event3, txn);\n assert.equal(member.displayName, \"Alies\");\n\n assert.equal(txn.members.size, 0);\n const changes = await memberSync.write(txn);\n assert.equal(txn.members.size, 1);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasJoined);\n },\n \"lookupMemberAtEvent falls back on state event\": async assert => {\n const event1 = createMemberEvent(\"join\", alice, \"Alice\");\n const event2 = createMemberEvent(\"join\", alice, \"Alies\");\n // we write first because the MemberWriter assumes it is called before\n // the SyncWriter does any lookups\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const memberSync = await writer.prepareMemberSync([event1], [event2], false);\n const member = await memberSync.lookupMemberAtEvent(event2.sender, event2, txn);\n assert.equal(member.displayName, \"Alice\");\n\n assert.equal(txn.members.size, 0);\n const changes = await memberSync.write(txn);\n assert.equal(txn.members.size, 1);\n assert.equal(changes.size, 1);\n const change = changes.get(alice);\n assert(change.hasJoined);\n },\n \"write works without event arrays\": async assert => {\n const writer = new MemberWriter(roomId);\n const txn = createStorage();\n const memberSync = await writer.prepareMemberSync(undefined, undefined, false);\n const changes = await memberSync.write(txn);\n assert.equal(changes.size, 0);\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventKey} from \"../EventKey\";\nimport {EventEntry} from \"../entries/EventEntry.js\";\nimport {createEventEntry, directionalAppend} from \"./common.js\";\nimport {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from \"../../members/RoomMember.js\";\n\nexport class GapWriter {\n constructor({roomId, storage, fragmentIdComparer, relationWriter}) {\n this._roomId = roomId;\n this._storage = storage;\n this._fragmentIdComparer = fragmentIdComparer;\n this._relationWriter = relationWriter;\n }\n\n async _findOverlappingEvents(fragmentEntry, events, txn, log) {\n const eventIds = events.map(e => e.event_id);\n const existingEventKeyMap = await txn.timelineEvents.getEventKeysForIds(this._roomId, eventIds);\n log.set(\"existingEvents\", existingEventKeyMap.size);\n const nonOverlappingEvents = events.filter(e => !existingEventKeyMap.has(e.event_id));\n log.set(\"nonOverlappingEvents\", nonOverlappingEvents.length);\n let neighbourFragmentEntry;\n if (fragmentEntry.hasLinkedFragment) {\n log.set(\"linkedFragmentId\", fragmentEntry.linkedFragmentId);\n for (const eventKey of existingEventKeyMap.values()) {\n if (eventKey.fragmentId === fragmentEntry.linkedFragmentId) {\n log.set(\"foundLinkedFragment\", true);\n const neighbourFragment = await txn.timelineFragments.get(this._roomId, fragmentEntry.linkedFragmentId);\n neighbourFragmentEntry = fragmentEntry.createNeighbourEntry(neighbourFragment);\n break;\n }\n }\n }\n return {nonOverlappingEvents, neighbourFragmentEntry};\n }\n\n async _findFragmentEdgeEventKey(fragmentEntry, txn) {\n const {fragmentId, direction} = fragmentEntry;\n const event = await this._findFragmentEdgeEvent(fragmentId, direction, txn);\n if (event) {\n return new EventKey(event.fragmentId, event.eventIndex);\n } else {\n // no events yet in the fragment ... odd, but let's not fail and take the default key\n return EventKey.defaultFragmentKey(fragmentEntry.fragmentId);\n }\n }\n\n async _findFragmentEdgeEvent(fragmentId, direction, txn) {\n if (direction.isBackward) {\n const [firstEvent] = await txn.timelineEvents.firstEvents(this._roomId, fragmentId, 1);\n return firstEvent;\n } else {\n const [lastEvent] = await txn.timelineEvents.lastEvents(this._roomId, fragmentId, 1);\n return lastEvent;\n }\n }\n\n async _storeEvents(events, startKey, direction, state, txn, log) {\n const entries = [];\n const updatedEntries = [];\n // events is in reverse chronological order for backwards pagination,\n // e.g. order is moving away from the `from` point.\n let key = startKey;\n for (let i = 0; i < events.length; ++i) {\n const event = events[i];\n key = key.nextKeyForDirection(direction);\n const eventStorageEntry = createEventEntry(key, this._roomId, event);\n const member = this._findMember(event.sender, state, events, i, direction);\n if (member) {\n eventStorageEntry.displayName = member.displayName;\n eventStorageEntry.avatarUrl = member.avatarUrl;\n }\n // this will modify eventStorageEntry if it is a relation target\n const updatedRelationTargetEntries = await this._relationWriter.writeGapRelation(eventStorageEntry, direction, txn, log);\n if (updatedRelationTargetEntries) {\n updatedEntries.push(...updatedRelationTargetEntries);\n }\n if (await txn.timelineEvents.tryInsert(eventStorageEntry, log)) {\n const eventEntry = new EventEntry(eventStorageEntry, this._fragmentIdComparer);\n directionalAppend(entries, eventEntry, direction);\n }\n }\n return {entries, updatedEntries};\n }\n\n _findMember(userId, state, events, index, direction) {\n function isOurUser(event) {\n return event.type === MEMBER_EVENT_TYPE && event.state_key === userId;\n }\n // older messages are at a higher index in the array when going backwards\n const inc = direction.isBackward ? 1 : -1;\n for (let i = index + inc; i >= 0 && i < events.length; i += inc) {\n const event = events[i];\n if (isOurUser(event)) {\n return RoomMember.fromMemberEvent(this._roomId, event);\n }\n }\n // look into newer events, but using prev_content if found.\n // We do this before looking into `state` because it is not well specified\n // in the spec whether the events in there represent state before or after `chunk`.\n // So we look both directions first in chunk to make sure it doesn't matter.\n for (let i = index; i >= 0 && i < events.length; i -= inc) {\n const event = events[i];\n if (isOurUser(event)) {\n return RoomMember.fromReplacingMemberEvent(this._roomId, event);\n }\n }\n // assuming the member hasn't changed within the chunk, just take it from state if it's there.\n // Don't assume state is set though, as it can be empty at the top of the timeline in some circumstances \n const stateMemberEvent = state?.find(isOurUser);\n if (stateMemberEvent) {\n return RoomMember.fromMemberEvent(this._roomId, stateMemberEvent);\n }\n }\n\n async _updateFragments(fragmentEntry, neighbourFragmentEntry, end, entries, txn, log) {\n const {direction} = fragmentEntry;\n const changedFragments = [];\n directionalAppend(entries, fragmentEntry, direction);\n // set `end` as token, and if we found an event in the step before, link up the fragments in the fragment entry\n if (neighbourFragmentEntry) {\n // if neighbourFragmentEntry was found, it means the events were overlapping,\n // so no pagination should happen anymore.\n log.set(\"closedGapWith\", neighbourFragmentEntry.fragmentId);\n neighbourFragmentEntry.token = null;\n fragmentEntry.token = null;\n\n txn.timelineFragments.update(neighbourFragmentEntry.fragment);\n directionalAppend(entries, neighbourFragmentEntry, direction);\n\n // fragments that need to be changed in the fragmentIdComparer here\n // after txn succeeds\n changedFragments.push(fragmentEntry.fragment);\n changedFragments.push(neighbourFragmentEntry.fragment);\n } else {\n fragmentEntry.token = end;\n }\n txn.timelineFragments.update(fragmentEntry.fragment);\n\n return changedFragments;\n }\n\n /**\n * @param {string} fromToken the token used to call /messages, to ensure it hasn't changed in storage \n */\n async writeFragmentFill(fragmentEntry, response, fromToken, txn, log) {\n const {fragmentId, direction} = fragmentEntry;\n // chunk is in reverse-chronological order when backwards\n const {chunk, state} = response;\n let {end} = response;\n\n if (!Array.isArray(chunk)) {\n throw new Error(\"Invalid chunk in response\");\n }\n if (typeof end !== \"string\" && typeof end !== \"undefined\") {\n throw new Error(\"Invalid end token in response\");\n }\n\n // make sure we have the latest fragment from the store\n const fragment = await txn.timelineFragments.get(this._roomId, fragmentId);\n if (!fragment) {\n throw new Error(`Unknown fragment: ${fragmentId}`);\n }\n fragmentEntry = fragmentEntry.withUpdatedFragment(fragment);\n // check that the request was done with the token we are aware of (extra care to avoid timeline corruption)\n if (fragmentEntry.token !== fromToken) {\n throw new Error(\"The pagination token has changed locally while fetching messages.\");\n }\n\n // begin (or end) of timeline reached\n if (chunk.length === 0) {\n fragmentEntry.edgeReached = true;\n await txn.timelineFragments.update(fragmentEntry.fragment);\n return {entries: [fragmentEntry], updatedEntries: [], fragments: []};\n }\n\n // find last event in fragment so we get the eventIndex to begin creating keys at\n let lastKey = await this._findFragmentEdgeEventKey(fragmentEntry, txn);\n log.set(\"lastKey\", lastKey.toString());\n // find out if any event in chunk is already present using findFirstOrLastOccurringEventId\n const {\n nonOverlappingEvents,\n neighbourFragmentEntry\n } = await this._findOverlappingEvents(fragmentEntry, chunk, txn, log);\n // create entries for all events in chunk, add them to entries\n const {entries, updatedEntries} = await this._storeEvents(nonOverlappingEvents, lastKey, direction, state, txn, log);\n const fragments = await this._updateFragments(fragmentEntry, neighbourFragmentEntry, end, entries, txn, log);\n \n return {entries, updatedEntries, fragments};\n }\n}\n\nimport {FragmentIdComparer} from \"../FragmentIdComparer.js\";\nimport {RelationWriter} from \"./RelationWriter.js\";\nimport {createMockStorage} from \"../../../../mocks/Storage\";\nimport {FragmentBoundaryEntry} from \"../entries/FragmentBoundaryEntry.js\";\nimport {NullLogItem} from \"../../../../logging/NullLogger\";\nimport {TimelineMock, eventIds, eventId} from \"../../../../mocks/TimelineMock.ts\";\nimport {SyncWriter} from \"./SyncWriter.js\";\nimport {MemberWriter} from \"./MemberWriter.js\";\nimport {KeyLimits} from \"../../../storage/common\";\n\nexport function tests() {\n const roomId = \"!room:hs.tdl\";\n const alice = \"alice@hs.tdl\";\n const logger = new NullLogItem();\n\n async function createGapFillTxn(storage) {\n return storage.readWriteTxn([\n storage.storeNames.roomMembers,\n storage.storeNames.pendingEvents,\n storage.storeNames.timelineEvents,\n storage.storeNames.timelineRelations,\n storage.storeNames.timelineFragments,\n ]);\n }\n\n async function setup() {\n const storage = await createMockStorage();\n const txn = await createGapFillTxn(storage);\n const fragmentIdComparer = new FragmentIdComparer([]);\n const relationWriter = new RelationWriter({\n roomId, fragmentIdComparer, ownUserId: alice,\n });\n const gapWriter = new GapWriter({\n roomId, storage, fragmentIdComparer, relationWriter\n });\n const memberWriter = new MemberWriter(roomId);\n const syncWriter = new SyncWriter({\n roomId,\n fragmentIdComparer,\n memberWriter,\n relationWriter\n });\n return { storage, txn, fragmentIdComparer, gapWriter, syncWriter, timelineMock: new TimelineMock() };\n }\n\n async function syncAndWrite(mocks, { previous, limit } = {}) {\n const {txn, timelineMock, syncWriter, fragmentIdComparer} = mocks;\n const syncResponse = timelineMock.sync(previous?.next_batch, limit);\n const {newLiveKey} = await syncWriter.writeSync(syncResponse, false, false, txn, logger);\n syncWriter.afterSync(newLiveKey);\n return {\n syncResponse,\n fragmentEntry: newLiveKey ? FragmentBoundaryEntry.start(\n await txn.timelineFragments.get(roomId, newLiveKey.fragmentId),\n fragmentIdComparer,\n ) : null,\n };\n }\n\n async function backfillAndWrite(mocks, fragmentEntry, limit) {\n const {txn, timelineMock, gapWriter} = mocks;\n const messageResponse = timelineMock.messages(fragmentEntry.token, undefined, fragmentEntry.direction.asApiString(), limit);\n await gapWriter.writeFragmentFill(fragmentEntry, messageResponse, fragmentEntry.token, txn, logger);\n }\n\n async function allFragmentEvents(mocks, fragmentId) {\n const {txn} = mocks;\n const entries = await txn.timelineEvents.eventsAfter(roomId, new EventKey(fragmentId, KeyLimits.minStorageKey));\n return entries.map(e => e.event);\n }\n\n async function fetchFragment(mocks, fragmentId) {\n const {txn} = mocks;\n return txn.timelineFragments.get(roomId, fragmentId);\n }\n\n function assertFilledLink(assert, fragment1, fragment2) {\n assert.equal(fragment1.nextId, fragment2.id);\n assert.equal(fragment2.previousId, fragment1.id);\n assert.equal(fragment1.nextToken, null);\n assert.equal(fragment2.previousToken, null);\n }\n\n function assertGapLink(assert, fragment1, fragment2) {\n assert.equal(fragment1.nextId, fragment2.id);\n assert.equal(fragment2.previousId, fragment1.id);\n assert.notEqual(fragment2.previousToken, null);\n }\n\n return {\n \"Backfilling after one sync\": async assert => {\n const mocks = await setup();\n const { timelineMock } = mocks;\n timelineMock.append(30);\n const {fragmentEntry} = await syncAndWrite(mocks);\n await backfillAndWrite(mocks, fragmentEntry, 10);\n const events = await allFragmentEvents(mocks, fragmentEntry.fragmentId);\n assert.deepEqual(events.map(e => e.event_id), eventIds(10, 30));\n await mocks.txn.complete();\n },\n \"Backfilling a fragment that is expected to close a gap, and does\": async assert => {\n const mocks = await setup();\n const { timelineMock } = mocks;\n timelineMock.append(10);\n const {syncResponse, fragmentEntry: firstFragmentEntry} = await syncAndWrite(mocks, { limit: 10 });\n timelineMock.append(15);\n const {fragmentEntry: secondFragmentEntry} = await syncAndWrite(mocks, { previous: syncResponse, limit: 10 });\n await backfillAndWrite(mocks, secondFragmentEntry, 10);\n\n const firstFragment = await fetchFragment(mocks, firstFragmentEntry.fragmentId);\n const secondFragment = await fetchFragment(mocks, secondFragmentEntry.fragmentId);\n assertFilledLink(assert, firstFragment, secondFragment)\n const firstEvents = await allFragmentEvents(mocks, firstFragmentEntry.fragmentId);\n assert.deepEqual(firstEvents.map(e => e.event_id), eventIds(0, 10));\n const secondEvents = await allFragmentEvents(mocks, secondFragmentEntry.fragmentId);\n assert.deepEqual(secondEvents.map(e => e.event_id), eventIds(10, 25));\n await mocks.txn.complete();\n },\n \"Backfilling a fragment that is expected to close a gap, but doesn't yet\": async assert => {\n const mocks = await setup();\n const { timelineMock } = mocks;\n timelineMock.append(10);\n const {syncResponse, fragmentEntry: firstFragmentEntry} = await syncAndWrite(mocks, { limit: 10 });\n timelineMock.append(20);\n const {fragmentEntry: secondFragmentEntry} = await syncAndWrite(mocks, { previous: syncResponse, limit: 10 });\n await backfillAndWrite(mocks, secondFragmentEntry, 10);\n\n const firstFragment = await fetchFragment(mocks, firstFragmentEntry.fragmentId);\n const secondFragment = await fetchFragment(mocks, secondFragmentEntry.fragmentId);\n assertGapLink(assert, firstFragment, secondFragment)\n const firstEvents = await allFragmentEvents(mocks, firstFragmentEntry.fragmentId);\n assert.deepEqual(firstEvents.map(e => e.event_id), eventIds(0, 10));\n const secondEvents = await allFragmentEvents(mocks, secondFragmentEntry.fragmentId);\n assert.deepEqual(secondEvents.map(e => e.event_id), eventIds(10, 30));\n await mocks.txn.complete();\n },\n \"Receiving a sync with the same events as the current fragment does not create infinite link\": async assert => {\n const mocks = await setup();\n const { txn, timelineMock } = mocks;\n timelineMock.append(10);\n const {syncResponse, fragmentEntry: fragmentEntry} = await syncAndWrite(mocks, { limit: 10 });\n // Mess with the saved token to receive old events in backfill\n fragmentEntry.token = syncResponse.next_batch;\n txn.timelineFragments.update(fragmentEntry.fragment);\n await backfillAndWrite(mocks, fragmentEntry, 10);\n\n const fragment = await fetchFragment(mocks, fragmentEntry.fragmentId);\n assert.notEqual(fragment.nextId, fragment.id);\n assert.notEqual(fragment.previousId, fragment.id);\n await mocks.txn.complete();\n },\n \"An event received by sync does not interrupt backfilling\": async assert => {\n const mocks = await setup();\n const { timelineMock } = mocks;\n timelineMock.append(10);\n const {syncResponse, fragmentEntry: firstFragmentEntry} = await syncAndWrite(mocks, { limit: 10 });\n timelineMock.append(11);\n const {fragmentEntry: secondFragmentEntry} = await syncAndWrite(mocks, { previous: syncResponse, limit: 10 });\n timelineMock.insertAfter(eventId(9), 5);\n await backfillAndWrite(mocks, secondFragmentEntry, 10);\n\n const firstEvents = await allFragmentEvents(mocks, firstFragmentEntry.fragmentId);\n assert.deepEqual(firstEvents.map(e => e.event_id), eventIds(0, 10));\n const secondEvents = await allFragmentEvents(mocks, secondFragmentEntry.fragmentId);\n assert.deepEqual(secondEvents.map(e => e.event_id), [...eventIds(21,26), ...eventIds(10, 21)]);\n const firstFragment = await fetchFragment(mocks, firstFragmentEntry.fragmentId);\n const secondFragment = await fetchFragment(mocks, secondFragmentEntry.fragmentId);\n assertFilledLink(assert, firstFragment, secondFragment)\n await mocks.txn.complete();\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {directionalConcat, directionalAppend} from \"./common.js\";\nimport {Direction} from \"../Direction\";\nimport {EventEntry} from \"../entries/EventEntry.js\";\nimport {FragmentBoundaryEntry} from \"../entries/FragmentBoundaryEntry.js\";\n\nclass ReaderRequest {\n constructor(fn, log) {\n this.decryptRequest = null;\n this._promise = fn(this, log);\n }\n\n complete() {\n return this._promise;\n }\n\n dispose() {\n if (this.decryptRequest) {\n this.decryptRequest.dispose();\n this.decryptRequest = null;\n }\n }\n}\n\n/**\n * Raw because it doesn't do decryption and in the future it should not read relations either.\n * It is just about reading entries and following fragment links\n */\nasync function readRawTimelineEntriesWithTxn(roomId, eventKey, direction, amount, fragmentIdComparer, txn) {\n let entries = [];\n const timelineStore = txn.timelineEvents;\n const fragmentStore = txn.timelineFragments;\n\n while (entries.length < amount && eventKey) {\n let eventsWithinFragment;\n if (direction.isForward) {\n // TODO: should we pass amount - entries.length here?\n eventsWithinFragment = await timelineStore.eventsAfter(roomId, eventKey, amount);\n } else {\n eventsWithinFragment = await timelineStore.eventsBefore(roomId, eventKey, amount);\n }\n let eventEntries = eventsWithinFragment.map(e => new EventEntry(e, fragmentIdComparer));\n entries = directionalConcat(entries, eventEntries, direction);\n // prepend or append eventsWithinFragment to entries, and wrap them in EventEntry\n\n if (entries.length < amount) {\n const fragment = await fragmentStore.get(roomId, eventKey.fragmentId);\n // TODO: why does the first fragment not need to be added? (the next *is* added below)\n // it looks like this would be fine when loading in the sync island\n // (as the live fragment should be added already) but not for permalinks when we support them\n // \n // fragmentIdComparer.addFragment(fragment);\n let fragmentEntry = new FragmentBoundaryEntry(fragment, direction.isBackward, fragmentIdComparer);\n // append or prepend fragmentEntry, reuse func from GapWriter?\n directionalAppend(entries, fragmentEntry, direction);\n // only continue loading if the fragment boundary can't be backfilled\n if (!fragmentEntry.token && fragmentEntry.hasLinkedFragment) {\n const nextFragment = await fragmentStore.get(roomId, fragmentEntry.linkedFragmentId);\n fragmentIdComparer.add(nextFragment);\n const nextFragmentEntry = new FragmentBoundaryEntry(nextFragment, direction.isForward, fragmentIdComparer);\n directionalAppend(entries, nextFragmentEntry, direction);\n eventKey = nextFragmentEntry.asEventKey();\n } else {\n eventKey = null;\n }\n }\n }\n return entries;\n}\n\nexport class TimelineReader {\n constructor({roomId, storage, fragmentIdComparer}) {\n this._roomId = roomId;\n this._storage = storage;\n this._fragmentIdComparer = fragmentIdComparer;\n this._decryptEntries = null;\n }\n\n enableEncryption(decryptEntries) {\n this._decryptEntries = decryptEntries;\n }\n\n get readTxnStores() {\n const stores = [\n this._storage.storeNames.timelineEvents,\n this._storage.storeNames.timelineFragments,\n ];\n if (this._decryptEntries) {\n stores.push(this._storage.storeNames.inboundGroupSessions);\n }\n return stores;\n }\n\n readFrom(eventKey, direction, amount, log) {\n return new ReaderRequest(async (r, log) => {\n const txn = await this._storage.readTxn(this.readTxnStores);\n return await this._readFrom(eventKey, direction, amount, r, txn, log);\n }, log);\n }\n\n readFromEnd(amount, existingTxn = null, log) {\n return new ReaderRequest(async (r, log) => {\n const txn = existingTxn || await this._storage.readTxn(this.readTxnStores);\n const liveFragment = await txn.timelineFragments.liveFragment(this._roomId);\n let entries;\n // room hasn't been synced yet\n if (!liveFragment) {\n entries = [];\n } else {\n this._fragmentIdComparer.add(liveFragment);\n const liveFragmentEntry = FragmentBoundaryEntry.end(liveFragment, this._fragmentIdComparer);\n const eventKey = liveFragmentEntry.asEventKey();\n entries = await this._readFrom(eventKey, Direction.Backward, amount, r, txn, log);\n entries.unshift(liveFragmentEntry);\n }\n return entries;\n }, log);\n }\n\n async readById(id, log) {\n let stores = [this._storage.storeNames.timelineEvents];\n if (this._decryptEntries) {\n stores.push(this._storage.storeNames.inboundGroupSessions);\n }\n const txn = await this._storage.readTxn(stores); // todo: can we just use this.readTxnStores here? probably\n const storageEntry = await txn.timelineEvents.getByEventId(this._roomId, id);\n if (storageEntry) {\n const entry = new EventEntry(storageEntry, this._fragmentIdComparer);\n if (this._decryptEntries) {\n const request = this._decryptEntries([entry], txn, log);\n await request.complete();\n }\n return entry;\n }\n }\n\n async _readFrom(eventKey, direction, amount, r, txn, log) {\n const entries = await readRawTimelineEntriesWithTxn(this._roomId, eventKey, direction, amount, this._fragmentIdComparer, txn);\n if (this._decryptEntries) {\n r.decryptRequest = this._decryptEntries(entries, txn, log);\n try {\n await r.decryptRequest.complete();\n } finally {\n r.decryptRequest = null;\n }\n }\n return entries;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventEntry} from \"./EventEntry.js\";\n\n// EventEntry but without the two properties that are populated via SyncWriter\n// Useful if you want to create an EventEntry that is ephemeral\n\nexport class NonPersistedEventEntry extends EventEntry {\n get fragmentId() {\n throw new Error(\"Cannot access fragmentId for non-persisted EventEntry\");\n }\n\n get entryIndex() {\n throw new Error(\"Cannot access entryIndex for non-persisted EventEntry\");\n }\n\n get isNonPersisted() {\n return true;\n }\n\n // overridden here because we reuse addLocalRelation() for updating this entry\n // we don't want the RedactedTile created using this entry to ever show \"is being redacted\"\n get isRedacting() {\n return false;\n }\n\n get isRedacted() {\n return super.isRedacting;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class RetainedValue {\n private readonly _freeCallback: () => void;\n private _retentionCount: number = 1;\n\n constructor(freeCallback: () => void) {\n this._freeCallback = freeCallback;\n }\n\n retain(): void {\n this._retentionCount += 1;\n }\n\n release(): void {\n this._retentionCount -= 1;\n if (this._retentionCount === 0) {\n this._freeCallback();\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class User {\n constructor(userId) {\n this._userId = userId;\n }\n\n get id() {\n return this._userId;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SortedArray, AsyncMappedList, ConcatList, ObservableArray} from \"../../../observable\";\nimport {Disposables} from \"../../../utils/Disposables\";\nimport {Direction} from \"./Direction\";\nimport {TimelineReader} from \"./persistence/TimelineReader.js\";\nimport {PendingEventEntry} from \"./entries/PendingEventEntry.js\";\nimport {RoomMember} from \"../members/RoomMember.js\";\nimport {getRelation, ANNOTATION_RELATION_TYPE} from \"./relations.js\";\nimport {REDACTION_TYPE} from \"../common\";\nimport {NonPersistedEventEntry} from \"./entries/NonPersistedEventEntry.js\";\nimport {EVENT_TYPE as MEMBER_EVENT_TYPE} from \"../members/RoomMember.js\";\nimport {RetainedValue} from \"../../../utils/RetainedValue\";\n\nexport class Timeline extends RetainedValue {\n constructor({roomId, storage, closeCallback, fragmentIdComparer, pendingEvents, clock, powerLevelsObservable, hsApi}) {\n super(() => { this.dispose(); });\n this._roomId = roomId;\n this._storage = storage;\n this._closeCallback = closeCallback;\n this._fragmentIdComparer = fragmentIdComparer;\n this._disposables = new Disposables();\n this._pendingEvents = pendingEvents;\n this._clock = clock;\n // constructing this early avoid some problem while sync and openTimeline race\n this._remoteEntries = new SortedArray((a, b) => a.compare(b));\n this._ownMember = null;\n this._timelineReader = new TimelineReader({\n roomId: this._roomId,\n storage: this._storage,\n fragmentIdComparer: this._fragmentIdComparer\n });\n this._readerRequest = null;\n this._allEntries = null;\n /** Stores event entries that we had to fetch from hs/storage for reply previews (because they were not in timeline) */\n this._contextEntriesNotInTimeline = new Map();\n /** Only used to decrypt non-persisted context entries fetched from the homeserver */\n this._decryptEntries = null;\n this._hsApi = hsApi;\n this.initializePowerLevels(powerLevelsObservable);\n }\n\n initializePowerLevels(observable) {\n if (observable) {\n this._powerLevels = observable.get();\n this._disposables.track(observable.subscribe(powerLevels => this._powerLevels = powerLevels));\n }\n }\n\n /** @package */\n async load(user, membership, log) {\n const txn = await this._storage.readTxn(this._timelineReader.readTxnStores.concat(\n this._storage.storeNames.roomMembers,\n this._storage.storeNames.roomState\n ));\n const memberData = await txn.roomMembers.get(this._roomId, user.id);\n if (memberData) {\n this._ownMember = new RoomMember(memberData);\n } else {\n // this should never happen, as our own join into the room would have\n // made us receive our own member event, but just to be on the safe side and not crash,\n // fall back to bare user id\n this._ownMember = RoomMember.fromUserId(this._roomId, user.id, membership);\n }\n // it should be fine to not update the local entries,\n // as they should only populate once the view subscribes to it\n // if they are populated already, the sender profile would be empty\n\n // choose good amount here between showing messages initially and\n // not spending too much time decrypting messages before showing the timeline.\n // more messages should be loaded automatically until the viewport is full by the view if needed.\n const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(20, txn, log));\n try {\n const entries = await readerRequest.complete();\n this._loadContextEntriesWhereNeeded(entries);\n this._setupEntries(entries);\n } finally {\n this._disposables.disposeTracked(readerRequest);\n }\n // txn should be assumed to have finished here, as decryption will close it.\n }\n\n _setupEntries(timelineEntries) {\n this._remoteEntries.setManySorted(timelineEntries);\n if (this._pendingEvents) {\n this._localEntries = new AsyncMappedList(this._pendingEvents,\n pe => this._mapPendingEventToEntry(pe),\n (pee, params) => {\n // is sending but redacted, who do we detect that here to remove the relation?\n pee.notifyUpdate(params);\n },\n pee => this._applyAndEmitLocalRelationChange(pee, target => target.removeLocalRelation(pee))\n );\n } else {\n this._localEntries = new ObservableArray();\n }\n this._allEntries = new ConcatList(this._remoteEntries, this._localEntries);\n }\n\n async _mapPendingEventToEntry(pe) {\n // we load the redaction target for pending events,\n // so if we are redacting a relation, we can pass the redaction\n // to the relation target and the removal of the relation can\n // be taken into account for local echo.\n let redactingEntry;\n if (pe.eventType === REDACTION_TYPE) {\n redactingEntry = await this._getOrLoadEntry(pe.relatedTxnId, pe.relatedEventId);\n }\n const pee = new PendingEventEntry({\n pendingEvent: pe, member: this._ownMember,\n clock: this._clock, redactingEntry\n });\n this._loadContextEntriesWhereNeeded([pee]);\n this._applyAndEmitLocalRelationChange(pee, target => target.addLocalRelation(pee));\n return pee;\n }\n\n _applyAndEmitLocalRelationChange(pee, updater) {\n // this is the contract of findAndUpdate, used in _findAndUpdateRelatedEntry\n const updateOrFalse = e => {\n const params = updater(e);\n return params ? params : false;\n };\n this._findAndUpdateEntryById(pee.pendingEvent.relatedTxnId, pee.relatedEventId, updateOrFalse);\n // also look for a relation target to update with this redaction\n if (pee.redactingEntry) {\n // redactingEntry might be a PendingEventEntry or an EventEntry, so don't assume pendingEvent\n const relatedTxnId = pee.redactingEntry.pendingEvent?.relatedTxnId;\n this._findAndUpdateEntryById(relatedTxnId, pee.redactingEntry.relatedEventId, updateOrFalse);\n pee.redactingEntry.contextForEntries?.forEach(e => this._emitUpdateForEntry(e, \"contextEntry\"));\n }\n }\n\n _findAndUpdateEntryById(txnId, eventId, updateOrFalse) {\n let found = false;\n // first, look in local entries based on txn id\n if (txnId) {\n found = this._localEntries.findAndUpdate(\n e => e.id === txnId,\n updateOrFalse,\n );\n }\n // if not found here, look in remote entries based on event id\n if (!found && eventId) {\n this._remoteEntries.findAndUpdate(\n e => e.id === eventId,\n updateOrFalse\n );\n }\n }\n\n async getOwnAnnotationEntry(targetId, key) {\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.timelineEvents,\n this._storage.storeNames.timelineRelations,\n ]);\n const relations = await txn.timelineRelations.getForTargetAndType(this._roomId, targetId, ANNOTATION_RELATION_TYPE);\n for (const relation of relations) {\n const annotation = await txn.timelineEvents.getByEventId(this._roomId, relation.sourceEventId);\n if (annotation && annotation.event.sender === this._ownMember.userId && getRelation(annotation.event).key === key) {\n const eventEntry = new EventEntry(annotation, this._fragmentIdComparer);\n this._addLocalRelationsToNewRemoteEntries([eventEntry]);\n return eventEntry;\n }\n }\n return null;\n }\n\n /** @package */\n updateOwnMember(member) {\n this._ownMember = member;\n }\n\n _addLocalRelationsToNewRemoteEntries(entries) {\n // because it is not safe to iterate a derived observable collection\n // before it has any subscriptions, we bail out if this isn't\n // the case yet. This can happen when sync adds or replaces entries\n // before load has finished and the view has subscribed to the timeline.\n //\n // Once the subscription is setup, MappedList will set up the local\n // relations as needed with _applyAndEmitLocalRelationChange,\n // so we're not missing anything by bailing out.\n //\n // _localEntries can also not yet exist\n if (!this._localEntries?.hasSubscriptions) {\n return;\n }\n // find any local relations to this new remote event\n for (const pee of this._localEntries) {\n // this will work because we set relatedEventId when removing remote echos\n if (pee.relatedEventId) {\n const relationTarget = entries.find(e => e.id === pee.relatedEventId);\n // no need to emit here as this entry is about to be added\n relationTarget?.addLocalRelation(pee);\n }\n if (pee.redactingEntry) {\n const eventId = pee.redactingEntry.relatedEventId;\n const relationTarget = entries.find(e => e.id === eventId);\n relationTarget?.addLocalRelation(pee);\n }\n }\n }\n\n // used in replaceEntries\n static _entryUpdater(existingEntry, entry) {\n // ensure other entries for which this existingEntry is a context point to the new entry instead of existingEntry\n existingEntry.contextForEntries?.forEach(event => event.setContextEntry(entry));\n entry.updateFrom(existingEntry);\n return entry;\n }\n\n /** @package */\n replaceEntries(entries) {\n this._addLocalRelationsToNewRemoteEntries(entries);\n for (const entry of entries) {\n try {\n this._remoteEntries.getAndUpdate(entry, Timeline._entryUpdater);\n const oldEntry = this._contextEntriesNotInTimeline.get(entry.id)\n if (oldEntry) {\n Timeline._entryUpdater(oldEntry, entry);\n this._contextEntriesNotInTimeline.set(entry.id, entry);\n }\n // Since this entry changed, all dependent entries should be updated\n entry.contextForEntries?.forEach(e => this._emitUpdateForEntry(e, \"contextEntry\"));\n } catch (err) {\n if (err.name === \"CompareError\") {\n // see FragmentIdComparer, if the replacing entry is on a fragment\n // that is currently not loaded into the FragmentIdComparer, it will\n // throw a CompareError, and it means that the event is not loaded\n // in the timeline (like when receiving a relation for an event\n // that is not loaded in memory) so we can just drop this error as\n // replacing an event that is not already loaded is a no-op.\n continue;\n } else {\n // don't swallow other errors\n throw err;\n }\n }\n }\n }\n\n /** @package */\n addEntries(newEntries) {\n this._addLocalRelationsToNewRemoteEntries(newEntries);\n this._updateEntriesFetchedFromHomeserver(newEntries);\n this._moveEntryToRemoteEntries(newEntries);\n this._loadContextEntriesWhereNeeded(newEntries);\n this._remoteEntries.setManySorted(newEntries);\n }\n\n /**\n * Update entries based on newly received events.\n * This is specific to events that are not in the timeline but had to be fetched from the homeserver\n * because they are context-events for other events in the timeline (i.e fetched from hs so that we\n * can render things like reply previews)\n */\n _updateEntriesFetchedFromHomeserver(entries) {\n /**\n * Updates for entries in timeline is handled by remoteEntries observable collection\n * Updates for entries not in timeline but fetched from storage is handled in this.replaceEntries()\n * This code is specific to entries fetched from HomeServer i.e NonPersistedEventEntry\n */\n for (const entry of entries) {\n const relatedEntry = this._contextEntriesNotInTimeline.get(entry.relatedEventId);\n if (relatedEntry?.isNonPersisted && relatedEntry?.addLocalRelation(entry)) {\n // update other entries for which this entry is a context entry\n relatedEntry.contextForEntries?.forEach(e => this._emitUpdateForEntry(e, \"contextEntry\"));\n }\n }\n }\n\n /**\n * If an event we had to fetch from hs/storage is now in the timeline (for eg, due to gap fill),\n * remove the event from _contextEntriesNotInTimeline since it is now in remoteEntries\n */\n _moveEntryToRemoteEntries(entries) {\n for (const entry of entries) {\n const fetchedEntry = this._contextEntriesNotInTimeline.get(entry.id);\n if (fetchedEntry) {\n fetchedEntry.contextForEntries.forEach(e => {\n e.setContextEntry(entry);\n this._emitUpdateForEntry(e, \"contextEntry\");\n });\n this._contextEntriesNotInTimeline.delete(entry.id);\n }\n }\n }\n\n _emitUpdateForEntry(entry, param) {\n const txnId = entry.isPending ? entry.id : null;\n const eventId = entry.isPending ? null : entry.id;\n this._findAndUpdateEntryById(txnId, eventId, () => param);\n }\n\n /**\n * For each entry in entries, this method associates a context-entry (if needed) to it.\n * The context-entry is fetched using the following strategies (in the same order as given):\n * - timeline\n * - storage\n * - homeserver\n * @param {EventEntry[]} entries\n */\n async _loadContextEntriesWhereNeeded(entries) {\n for (const entry of entries) {\n if (!entry.contextEventId) {\n continue;\n }\n const id = entry.contextEventId;\n // before looking into remoteEntries, check the entries\n // that are about to be added first\n let contextEvent = entries.find(e => e.id === id);\n if (!contextEvent) {\n contextEvent = this._findLoadedEventById(id);\n }\n if (contextEvent) {\n entry.setContextEntry(contextEvent);\n // we don't emit an update for `entry` here, as the add or update\n // that the callee will emit hasn't been emitted yet.\n // however we do emit an update for the `contextEvent` so that it\n // can do something in response to `entry` being added (if needed).\n this._emitUpdateForEntry(contextEvent, \"context-added\");\n } else {\n // we don't await here, which is not ideal,\n // but one of our callers, addEntries, is not async\n // so there is not much point.\n // Also, we want to run the entry fetching in parallel.\n this._loadContextEntryNotInTimeline(entry);\n }\n }\n }\n\n async _loadContextEntryNotInTimeline(entry) {\n const id = entry.contextEventId;\n let contextEvent = await this._getEventFromStorage(id);\n if (!contextEvent) {\n contextEvent = await this._getEventFromHomeserver(id);\n }\n if (contextEvent) {\n // this entry was created from storage/hs, so it's not tracked by remoteEntries\n // we track them here so that we can update reply previews later\n this._contextEntriesNotInTimeline.set(id, contextEvent);\n entry.setContextEntry(contextEvent);\n // here, we awaited something, so from now on we do have to emit\n // an update if we set the context entry.\n this._emitUpdateForEntry(entry, \"contextEntry\");\n }\n }\n\n /**\n * Fetches an entry with the given event-id from localEntries, remoteEntries or contextEntriesNotInTimeline.\n * @param {string} eventId event-id of the entry\n * @returns entry if found, undefined otherwise\n */\n _findLoadedEventById(eventId) {\n return this.getByEventId(eventId) ?? this._contextEntriesNotInTimeline.get(eventId);\n }\n\n async _getEventFromStorage(eventId) {\n const entry = await this._timelineReader.readById(eventId);\n return entry;\n }\n\n async _getEventFromHomeserver(eventId) {\n const response = await this._hsApi.context(this._roomId, eventId, 0).response();\n const sender = response.event.sender;\n const member = response.state.find(e => e.type === MEMBER_EVENT_TYPE && e.user_id === sender);\n const entry = {\n event: response.event,\n displayName: member.content.displayname,\n avatarUrl: member.content.avatar_url\n };\n const eventEntry = new NonPersistedEventEntry(entry, this._fragmentIdComparer);\n if (this._decryptEntries) {\n const request = this._decryptEntries([eventEntry]);\n await request.complete();\n }\n return eventEntry;\n }\n\n // tries to prepend `amount` entries to the `entries` list.\n /**\n * [loadAtTop description]\n * @param {[type]} amount [description]\n * @return {boolean} true if the top of the timeline has been reached\n *\n */\n async loadAtTop(amount) {\n if (this._disposables.isDisposed) {\n return true;\n }\n const firstEventEntry = this._remoteEntries.array.find(e => !!e.eventType);\n if (!firstEventEntry) {\n return true;\n }\n const readerRequest = this._disposables.track(this._timelineReader.readFrom(\n firstEventEntry.asEventKey(),\n Direction.Backward,\n amount\n ));\n try {\n const entries = await readerRequest.complete();\n this.addEntries(entries);\n return entries.length < amount;\n } finally {\n this._disposables.disposeTracked(readerRequest);\n }\n }\n\n async _getOrLoadEntry(txnId, eventId) {\n if (txnId) {\n // also look for redacting relation in pending events, in case the target is already being sent\n for (const p of this._localEntries) {\n if (p.id === txnId) {\n return p;\n }\n }\n }\n if (eventId) {\n return this.getByEventId(eventId) ?? await this._getEventFromStorage(eventId);\n }\n return null;\n }\n\n getByEventId(eventId) {\n for (let i = 0; i < this._remoteEntries.length; i += 1) {\n const entry = this._remoteEntries.get(i);\n if (entry.id === eventId) {\n return entry;\n }\n }\n return null;\n }\n\n /** @public */\n get entries() {\n return this._allEntries;\n }\n\n /**\n * @internal\n * @return {Array} remote event entries, should not be modified\n */\n get remoteEntries() {\n return this._remoteEntries.array;\n }\n\n /** @public */\n dispose() {\n if (this._closeCallback) {\n this._disposables.dispose();\n this._closeCallback();\n this._closeCallback = null;\n }\n }\n\n /** @internal */\n enableEncryption(decryptEntries) {\n this._decryptEntries = decryptEntries;\n this._timelineReader.enableEncryption(decryptEntries);\n }\n\n get powerLevels() {\n return this._powerLevels;\n }\n\n get me() {\n return this._ownMember;\n }\n}\n\nimport {FragmentIdComparer} from \"./FragmentIdComparer.js\";\nimport {poll} from \"../../../mocks/poll.js\";\nimport {Clock as MockClock} from \"../../../mocks/Clock.js\";\nimport {createMockStorage} from \"../../../mocks/Storage\";\nimport {ListObserver} from \"../../../mocks/ListObserver.js\";\nimport {createEvent, withTextBody, withContent, withSender, withRedacts, withReply} from \"../../../mocks/event.js\";\nimport {NullLogItem} from \"../../../logging/NullLogger\";\nimport {EventEntry} from \"./entries/EventEntry.js\";\nimport {User} from \"../../User.js\";\nimport {PendingEvent} from \"../sending/PendingEvent.js\";\nimport {createAnnotation} from \"./relations.js\";\nimport {redactEvent} from \"./common.js\";\n\nexport function tests() {\n const fragmentIdComparer = new FragmentIdComparer([]);\n const roomId = \"$abc\";\n const alice = \"@alice:hs.tld\";\n const bob = \"@bob:hs.tld\";\n const hsApi = {\n context() {\n const result = {\n event: withTextBody(\"foo\", createEvent(\"m.room.message\", \"event_id_1\", alice)),\n state: [{\n type: MEMBER_EVENT_TYPE,\n user_id: alice,\n content: {\n displayName: \"\",\n avatarUrl: \"\"\n }\n }]\n };\n return { response: () => result };\n }\n };\n\n function getIndexFromIterable(it, n) {\n let i = 0;\n for (const item of it) {\n if (i === n) {\n return item;\n }\n i += 1;\n }\n throw new Error(\"not enough items in iterable\");\n }\n\n return {\n \"adding or replacing entries before subscribing to entries does not lose local relations\": async assert => {\n const pendingEvents = new ObservableArray();\n const timeline = new Timeline({roomId, storage: await createMockStorage(),\n closeCallback: () => {}, fragmentIdComparer, pendingEvents, clock: new MockClock()});\n // 1. load timeline\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n // 2. test replaceEntries and addEntries don't fail\n const event1 = withTextBody(\"hi!\", withSender(bob, createEvent(\"m.room.message\", \"!abc\")));\n const entry1 = new EventEntry({event: event1, fragmentId: 1, eventIndex: 1}, fragmentIdComparer);\n timeline.replaceEntries([entry1]);\n const event2 = withTextBody(\"hi bob!\", withSender(alice, createEvent(\"m.room.message\", \"!def\")));\n const entry2 = new EventEntry({event: event2, fragmentId: 1, eventIndex: 2}, fragmentIdComparer);\n timeline.addEntries([entry2]);\n // 3. add local relation (redaction)\n pendingEvents.append(new PendingEvent({data: {\n roomId,\n queueIndex: 1,\n eventType: \"m.room.redaction\",\n txnId: \"t123\",\n content: {},\n relatedEventId: event2.event_id\n }}));\n // 4. subscribe (it's now safe to iterate timeline.entries)\n timeline.entries.subscribe(new ListObserver());\n // 5. check the local relation got correctly aggregated\n const locallyRedacted = await poll(() => Array.from(timeline.entries)[0].isRedacting);\n assert.equal(locallyRedacted, true);\n },\n \"add and remove local reaction, and cancel again\": async assert => {\n // 1. setup timeline with message\n const pendingEvents = new ObservableArray();\n const timeline = new Timeline({roomId, storage: await createMockStorage(),\n closeCallback: () => {}, fragmentIdComparer, pendingEvents, clock: new MockClock()});\n await timeline.load(new User(bob), \"join\", new NullLogItem());\n timeline.entries.subscribe(new ListObserver());\n const event = withTextBody(\"hi bob!\", withSender(alice, createEvent(\"m.room.message\", \"!abc\")));\n timeline.addEntries([new EventEntry({event, fragmentId: 1, eventIndex: 2}, fragmentIdComparer)]);\n let entry = getIndexFromIterable(timeline.entries, 0);\n // 2. add local reaction\n pendingEvents.append(new PendingEvent({data: {\n roomId,\n queueIndex: 1,\n eventType: \"m.reaction\",\n txnId: \"t123\",\n content: entry.annotate(\"👋\"),\n relatedEventId: entry.id\n }}));\n await poll(() => timeline.entries.length === 2);\n assert.equal(entry.pendingAnnotations.get(\"👋\").count, 1);\n const reactionEntry = getIndexFromIterable(timeline.entries, 1);\n // 3. add redaction to timeline\n pendingEvents.append(new PendingEvent({data: {\n roomId,\n queueIndex: 2,\n eventType: \"m.room.redaction\",\n txnId: \"t456\",\n content: {},\n relatedTxnId: reactionEntry.id\n }}));\n // TODO: await nextUpdate here with ListObserver, to ensure entry emits an update when pendingAnnotations changes\n await poll(() => timeline.entries.length === 3);\n assert.equal(entry.pendingAnnotations.get(\"👋\").count, 0);\n // 4. cancel redaction\n pendingEvents.remove(1);\n await poll(() => timeline.entries.length === 2);\n assert.equal(entry.pendingAnnotations.get(\"👋\").count, 1);\n // 5. cancel reaction\n pendingEvents.remove(0);\n await poll(() => timeline.entries.length === 1);\n assert(!entry.pendingAnnotations);\n },\n \"getOwnAnnotationEntry\": async assert => {\n const messageId = \"!abc\";\n const reactionId = \"!def\";\n // 1. put event and reaction into storage\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({\n event: withContent(createAnnotation(messageId, \"👋\"), createEvent(\"m.reaction\", reactionId, bob)),\n fragmentId: 1, eventIndex: 1, roomId\n }, new NullLogItem());\n txn.timelineRelations.add(roomId, messageId, ANNOTATION_RELATION_TYPE, reactionId);\n await txn.complete();\n // 2. setup the timeline\n const timeline = new Timeline({roomId, storage, closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock()});\n await timeline.load(new User(bob), \"join\", new NullLogItem());\n // 3. get the own annotation out\n const reactionEntry = await timeline.getOwnAnnotationEntry(messageId, \"👋\");\n assert.equal(reactionEntry.id, reactionId);\n assert.equal(reactionEntry.relation.key, \"👋\");\n },\n \"remote reaction\": async assert => {\n const messageEntry = new EventEntry({\n event: withTextBody(\"hi bob!\", createEvent(\"m.room.message\", \"!abc\", alice)),\n fragmentId: 1, eventIndex: 2, roomId,\n annotations: { // aggregated like RelationWriter would\n \"👋\": {count: 1, me: true, firstTimestamp: 0}\n },\n }, fragmentIdComparer);\n // 2. setup timeline\n const pendingEvents = new ObservableArray();\n const timeline = new Timeline({roomId, storage: await createMockStorage(),\n closeCallback: () => {}, fragmentIdComparer, pendingEvents, clock: new MockClock()});\n await timeline.load(new User(bob), \"join\", new NullLogItem());\n timeline.entries.subscribe(new ListObserver());\n // 3. add message to timeline\n timeline.addEntries([messageEntry]);\n const entry = getIndexFromIterable(timeline.entries, 0);\n assert.equal(entry, messageEntry);\n assert.equal(entry.annotations[\"👋\"].count, 1);\n },\n \"remove remote reaction\": async assert => {\n // 1. setup timeline\n const pendingEvents = new ObservableArray();\n const timeline = new Timeline({roomId, storage: await createMockStorage(),\n closeCallback: () => { }, fragmentIdComparer, pendingEvents, clock: new MockClock()});\n await timeline.load(new User(bob), \"join\", new NullLogItem());\n timeline.entries.subscribe(new ListObserver());\n // 2. add message and reaction to timeline\n const messageEntry = new EventEntry({\n event: withTextBody(\"hi bob!\", createEvent(\"m.room.message\", \"!abc\", alice)),\n fragmentId: 1, eventIndex: 2, roomId,\n }, fragmentIdComparer);\n const reactionEntry = new EventEntry({\n event: withContent(createAnnotation(messageEntry.id, \"👋\"), createEvent(\"m.reaction\", \"!def\", bob)),\n fragmentId: 1, eventIndex: 3, roomId\n }, fragmentIdComparer);\n timeline.addEntries([messageEntry, reactionEntry]);\n // 3. redact reaction\n pendingEvents.append(new PendingEvent({data: {\n roomId,\n queueIndex: 1,\n eventType: \"m.room.redaction\",\n txnId: \"t123\",\n content: {},\n relatedEventId: reactionEntry.id\n }}));\n await poll(() => timeline.entries.length >= 3);\n assert.equal(messageEntry.pendingAnnotations.get(\"👋\").count, -1);\n },\n \"local reaction gets applied after remote echo is added to timeline\": async assert => {\n const messageEntry = new EventEntry({event: withTextBody(\"hi bob!\", withSender(alice, createEvent(\"m.room.message\", \"!abc\"))),\n fragmentId: 1, eventIndex: 2}, fragmentIdComparer);\n // 1. setup timeline\n const pendingEvents = new ObservableArray();\n const timeline = new Timeline({roomId, storage: await createMockStorage(),\n closeCallback: () => {}, fragmentIdComparer, pendingEvents, clock: new MockClock()});\n await timeline.load(new User(bob), \"join\", new NullLogItem());\n timeline.entries.subscribe(new ListObserver());\n // 2. add local reaction\n pendingEvents.append(new PendingEvent({data: {\n roomId,\n queueIndex: 1,\n eventType: \"m.reaction\",\n txnId: \"t123\",\n content: messageEntry.annotate(\"👋\"),\n relatedEventId: messageEntry.id\n }}));\n await poll(() => timeline.entries.length === 1);\n // 3. add remote reaction target\n timeline.addEntries([messageEntry]);\n await poll(() => timeline.entries.length === 2);\n const entry = getIndexFromIterable(timeline.entries, 0);\n assert.equal(entry, messageEntry);\n assert.equal(entry.pendingAnnotations.get(\"👋\").count, 1);\n },\n \"local reaction removal gets applied after remote echo is added to timeline with reaction not loaded\": async assert => {\n const messageId = \"!abc\";\n const reactionId = \"!def\";\n // 1. put reaction in storage\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({\n event: withContent(createAnnotation(messageId, \"👋\"), createEvent(\"m.reaction\", reactionId, bob)),\n fragmentId: 1, eventIndex: 3, roomId\n }, new NullLogItem());\n await txn.complete();\n // 2. setup timeline\n const pendingEvents = new ObservableArray();\n const timeline = new Timeline({roomId, storage, closeCallback: () => {},\n fragmentIdComparer, pendingEvents, clock: new MockClock()});\n await timeline.load(new User(bob), \"join\", new NullLogItem());\n timeline.entries.subscribe(new ListObserver());\n // 3. add local redaction for reaction\n pendingEvents.append(new PendingEvent({data: {\n roomId,\n queueIndex: 1,\n eventType: \"m.room.redaction\",\n txnId: \"t123\",\n content: {},\n relatedEventId: reactionId\n }}));\n await poll(() => timeline.entries.length === 1);\n // 4. add reaction target\n timeline.addEntries([new EventEntry({\n event: withTextBody(\"hi bob!\", createEvent(\"m.room.message\", messageId, alice)),\n fragmentId: 1, eventIndex: 2}, fragmentIdComparer)\n ]);\n await poll(() => timeline.entries.length === 2);\n // 5. check that redaction was linked to reaction target\n const entry = getIndexFromIterable(timeline.entries, 0);\n assert.equal(entry.pendingAnnotations.get(\"👋\").count, -1);\n },\n \"decrypted entry preserves content when receiving other update without decryption\": async assert => {\n // 1. create encrypted and decrypted entry\n const encryptedEntry = new EventEntry({\n event: withContent({ciphertext: \"abc\"}, createEvent(\"m.room.encrypted\", \"!abc\", alice)),\n fragmentId: 1, eventIndex: 1, roomId\n }, fragmentIdComparer);\n const decryptedEntry = encryptedEntry.clone();\n decryptedEntry.setDecryptionResult({\n event: withTextBody(\"hi bob!\", createEvent(\"m.room.message\", encryptedEntry.id, encryptedEntry.sender))\n });\n // 2. setup the timeline\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock()});\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.addEntries([decryptedEntry]);\n const observer = new ListObserver();\n timeline.entries.subscribe(observer);\n // 3. replace the entry with one that is not decrypted\n // (as would happen when receiving a reaction,\n // as it does not rerun the decryption)\n // and check that the decrypted content is preserved\n timeline.replaceEntries([encryptedEntry]);\n const {value, type} = await observer.next();\n assert.equal(type, \"update\");\n assert.equal(value.eventType, \"m.room.message\");\n assert.equal(value.content.body, \"hi bob!\");\n },\n\n \"context entry is fetched from remoteEntries\": async assert => {\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock()});\n const entryA = new EventEntry({ event: withTextBody(\"foo\", createEvent(\"m.room.message\", \"event_id_1\", alice)) });\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.entries.subscribe({\n onAdd() {},\n });\n timeline.addEntries([entryA, entryB]);\n assert.deepEqual(entryB.contextEntry, entryA);\n },\n\n \"context entry is fetched from storage\": async assert => {\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([storage.storeNames.timelineEvents, storage.storeNames.timelineRelations]);\n txn.timelineEvents.tryInsert({ event: withTextBody(\"foo\", createEvent(\"m.room.message\", \"event_id_1\", alice)), fragmentId: 1, eventIndex: 1, roomId });\n await txn.complete();\n const timeline = new Timeline({roomId, storage, closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock()});\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.entries.subscribe({ onAdd: () => null, onUpdate: () => null });\n timeline.addEntries([entryB]);\n await poll(() => entryB.contextEntry);\n assert.strictEqual(entryB.contextEntry.id, \"event_id_1\");\n },\n\n \"context entry is fetched from hs\": async assert => {\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock(), hsApi});\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.entries.subscribe({ onAdd: () => null, onUpdate: () => null });\n timeline.addEntries([entryB]);\n await poll(() => entryB.contextEntry);\n assert.strictEqual(entryB.contextEntry.id, \"event_id_1\");\n },\n\n \"context entry has a list of entries to which it forms the context\": async assert => {\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock()});\n const entryA = new EventEntry({ event: withTextBody(\"foo\", createEvent(\"m.room.message\", \"event_id_1\", alice)), eventIndex: 1 });\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2 });\n const entryC = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_3\", bob)), eventIndex: 3 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.entries.subscribe({ onAdd: () => null, onUpdate: () => null });\n timeline.addEntries([entryA, entryB, entryC]);\n await poll(() => entryA.contextForEntries.length === 2);\n assert.deepEqual(entryA.contextForEntries, [entryB, entryC]);\n },\n\n \"context entry in contextEntryNotInTimeline gets updated based on incoming redaction\": async assert => {\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock(), hsApi});\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.entries.subscribe({ onAdd: () => null, onUpdate: () => null });\n timeline.addEntries([entryB]);\n await poll(() => entryB.contextEntry);\n const redactingEntry = new EventEntry({ event: withRedacts(\"event_id_1\", \"foo\", createEvent(\"m.room.redaction\", \"event_id_3\", alice)), eventIndex: 3 });\n timeline.addEntries([redactingEntry]);\n assert.strictEqual(entryB.contextEntry.isRedacted, true);\n },\n\n \"redaction of context entry triggers updates in other entries\": async assert => {\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock(), hsApi});\n const entryA = new EventEntry({ event: withTextBody(\"foo\", createEvent(\"m.room.message\", \"event_id_1\", alice)), eventIndex: 1, fragmentId: 1 });\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2, fragmentId: 1 });\n const entryC = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_3\", bob)), eventIndex: 3, fragmentId: 1 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n const bin = [];\n timeline.entries.subscribe({\n onUpdate: (index, e) => {\n bin.push(e.id);\n },\n onAdd: () => null,\n });\n timeline.addEntries([entryA, entryB, entryC]);\n const eventAClone = JSON.parse(JSON.stringify(entryA.event));\n redactEvent(withRedacts(\"event_id_1\", \"foo\", createEvent(\"m.room.redaction\", \"event_id_4\", alice)), eventAClone);\n const redactedEntry = new EventEntry({ event: eventAClone, eventIndex: 1, fragmentId: 1 });\n timeline.replaceEntries([redactedEntry]);\n assert.strictEqual(bin.includes(\"event_id_2\"), true);\n assert.strictEqual(bin.includes(\"event_id_3\"), true);\n },\n\n \"context entries fetched from storage/hs are moved to remoteEntries\": async assert => {\n const timeline = new Timeline({roomId, storage: await createMockStorage(), closeCallback: () => {},\n fragmentIdComparer, pendingEvents: new ObservableArray(), clock: new MockClock(), hsApi});\n const entryA = new EventEntry({ event: withTextBody(\"foo\", createEvent(\"m.room.message\", \"event_id_1\", alice)), eventIndex: 1 });\n const entryB = new EventEntry({ event: withReply(\"event_id_1\", createEvent(\"m.room.message\", \"event_id_2\", bob)), eventIndex: 2 });\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n timeline.entries.subscribe({ onAdd: () => null, onUpdate: () => null });\n timeline.addEntries([entryB]);\n await poll(() => entryB.contextEntry);\n assert.strictEqual(timeline._contextEntriesNotInTimeline.has(entryA.id), true);\n timeline.addEntries([entryA]);\n assert.strictEqual(timeline._contextEntriesNotInTimeline.has(entryA.id), false);\n const movedEntry = timeline.remoteEntries[0];\n assert.deepEqual(movedEntry, entryA);\n assert.deepEqual(movedEntry.contextForEntries[0], entryB);\n assert.deepEqual(entryB.contextEntry, movedEntry);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {RoomMember} from \"./RoomMember.js\";\n\nasync function loadMembers({roomId, storage, txn}) {\n if (!txn) {\n txn = await storage.readTxn([\n storage.storeNames.roomMembers,\n ]);\n }\n const memberDatas = await txn.roomMembers.getAll(roomId);\n return memberDatas.map(d => new RoomMember(d));\n}\n\nasync function fetchMembers({summary, syncToken, roomId, hsApi, storage, setChangedMembersMap}, log) {\n // if any members are changed by sync while we're fetching members,\n // they will end up here, so we check not to override them\n const changedMembersDuringSync = new Map();\n setChangedMembersMap(changedMembersDuringSync);\n \n const memberResponse = await hsApi.members(roomId, {at: syncToken}, {log}).response();\n\n const txn = await storage.readWriteTxn([\n storage.storeNames.roomSummary,\n storage.storeNames.roomMembers,\n ]);\n\n let summaryChanges;\n let members;\n \n try {\n summaryChanges = summary.writeHasFetchedMembers(true, txn);\n const {roomMembers} = txn;\n const memberEvents = memberResponse.chunk;\n if (!Array.isArray(memberEvents)) {\n throw new Error(\"malformed\");\n }\n log.set(\"members\", memberEvents.length);\n members = await Promise.all(memberEvents.map(async memberEvent => {\n const userId = memberEvent?.state_key;\n if (!userId) {\n throw new Error(\"malformed\");\n }\n // this member was changed during a sync that happened while calling /members\n // and thus is more recent, so don't overwrite\n const changedMember = changedMembersDuringSync.get(userId);\n if (changedMember) {\n return changedMember;\n } else {\n const member = RoomMember.fromMemberEvent(roomId, memberEvent);\n if (member) {\n roomMembers.set(member.serialize());\n }\n return member;\n }\n }));\n } catch (err) {\n // abort txn on any error\n txn.abort();\n throw err;\n } finally {\n // important this gets cleared\n // or otherwise Room remains in \"fetching-members\" mode\n setChangedMembersMap(null);\n }\n await txn.complete();\n summary.applyChanges(summaryChanges);\n return members;\n}\n\nexport async function fetchOrLoadMembers(options, logger) {\n const {summary} = options;\n if (!summary.data.hasFetchedMembers) {\n // we only want to log if we fetch members, so start or continue the optional log operation here\n return logger.wrapOrRun(options.log, \"fetchMembers\", log => fetchMembers(options, log));\n } else {\n return loadMembers(options);\n }\n}\n\nexport async function fetchOrLoadMember(options, logger) {\n const member = await loadMember(options);\n const {summary} = options;\n if (!summary.data.hasFetchedMembers && !member) {\n // We haven't fetched the memberlist yet; so ping the hs to see if this member does exist\n return logger.wrapOrRun(options.log, \"fetchMember\", log => fetchMember(options, log));\n }\n return member;\n}\n\nasync function loadMember({roomId, userId, storage}) {\n const txn = await storage.readTxn([storage.storeNames.roomMembers,]);\n const member = await txn.roomMembers.get(roomId, userId);\n return member? new RoomMember(member) : null;\n}\n\nasync function fetchMember({roomId, userId, hsApi, storage}, log) {\n let memberData;\n try {\n memberData = await hsApi.state(roomId, \"m.room.member\", userId, { log }).response();\n }\n catch (error) {\n if (error.name === \"HomeServerError\" && error.errcode === \"M_NOT_FOUND\") {\n return null;\n }\n throw error;\n }\n const member = new RoomMember({\n roomId,\n userId,\n membership: memberData.membership,\n avatarUrl: memberData.avatar_url,\n displayName: memberData.displayname,\n });\n const txn = await storage.readWriteTxn([storage.storeNames.roomMembers]);\n try {\n txn.roomMembers.set(member.serialize());\n }\n catch(e) {\n txn.abort();\n throw e;\n }\n await txn.complete();\n return member;\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableMap} from \"../../../observable\";\nimport {RetainedValue} from \"../../../utils/RetainedValue\";\n\nexport class MemberList extends RetainedValue {\n constructor({members, closeCallback}) {\n super(closeCallback);\n this._members = new ObservableMap();\n for (const member of members) {\n this._members.add(member.userId, member);\n }\n }\n\n afterSync(memberChanges) {\n for (const [userId, memberChange] of memberChanges.entries()) {\n this._members.set(userId, memberChange.member);\n }\n }\n\n get members() {\n return this._members;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {RoomMember} from \"./RoomMember.js\";\n\nexport function calculateRoomName(sortedMembers, summaryData, log) {\n const countWithoutMe = summaryData.joinCount + summaryData.inviteCount - 1;\n if (sortedMembers.length >= countWithoutMe) {\n if (sortedMembers.length > 1) {\n const lastMember = sortedMembers[sortedMembers.length - 1];\n const firstMembers = sortedMembers.slice(0, sortedMembers.length - 1);\n return firstMembers.map(m => m.name).join(\", \") + \" and \" + lastMember.name;\n } else {\n const otherMember = sortedMembers[0];\n if (otherMember) {\n return otherMember.name;\n } else {\n log.log({l: \"could get get other member name\", length: sortedMembers.length, otherMember: !!otherMember, otherMemberMembership: otherMember?.membership});\n return \"Unknown DM Name\";\n }\n }\n } else if (sortedMembers.length < countWithoutMe) {\n return sortedMembers.map(m => m.name).join(\", \") + ` and ${countWithoutMe} others`;\n } else {\n // Empty Room\n return null;\n }\n}\n\nexport class Heroes {\n constructor(roomId) {\n this._roomId = roomId;\n this._members = new Map();\n }\n\n /**\n * @param {string[]} newHeroes array of user ids\n * @param {Map} memberChanges map of changed memberships\n * @param {Transaction} txn\n * @return {Promise}\n */\n async calculateChanges(newHeroes, memberChanges, txn) {\n const updatedHeroMembers = new Map();\n const removedUserIds = [];\n // remove non-present members\n for (const existingUserId of this._members.keys()) {\n if (newHeroes.indexOf(existingUserId) === -1) {\n removedUserIds.push(existingUserId);\n }\n }\n // update heroes with synced member changes\n for (const [userId, memberChange] of memberChanges.entries()) {\n if (this._members.has(userId) || newHeroes.indexOf(userId) !== -1) {\n updatedHeroMembers.set(userId, memberChange.member);\n }\n }\n // load member for new heroes from storage\n for (const userId of newHeroes) {\n if (!this._members.has(userId) && !updatedHeroMembers.has(userId)) {\n const memberData = await txn.roomMembers.get(this._roomId, userId);\n if (memberData) {\n const member = new RoomMember(memberData);\n updatedHeroMembers.set(member.userId, member);\n }\n }\n }\n return {updatedHeroMembers: updatedHeroMembers.values(), removedUserIds};\n }\n\n applyChanges({updatedHeroMembers, removedUserIds}, summaryData, log) {\n for (const userId of removedUserIds) {\n this._members.delete(userId);\n }\n for (const member of updatedHeroMembers) {\n if (!removedUserIds.includes(member.userId)) {\n this._members.set(member.userId, member);\n }\n }\n const sortedMembers = Array.from(this._members.values()).sort((a, b) => a.name.localeCompare(b.name));\n this._roomName = calculateRoomName(sortedMembers, summaryData, log);\n }\n\n get roomName() {\n return this._roomName;\n }\n\n get roomAvatarUrl() {\n if (this._members.size === 1) {\n for (const member of this._members.values()) {\n return member.avatarUrl;\n }\n }\n return null;\n }\n\n /**\n * In DM rooms, we want the room's color to be\n * the same as the other user's color. Thus, if the room\n * only has one hero, we use their ID, instead\n * of the room's, to get the avatar color.\n *\n * @returns {?string} the ID of the single hero.\n */\n get roomAvatarColorId() {\n if (this._members.size === 1) {\n for (const member of this._members.keys()) {\n return member\n }\n }\n return null;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"../../observable/value\";\n\nexport class ObservedEventMap {\n constructor(notifyEmpty) {\n this._map = new Map();\n this._notifyEmpty = notifyEmpty;\n }\n\n observe(eventId, eventEntry = null) {\n let observable = this._map.get(eventId);\n if (!observable) {\n observable = new ObservedEvent(this, eventEntry, eventId);\n this._map.set(eventId, observable);\n }\n return observable;\n }\n\n updateEvents(eventEntries) {\n for (let i = 0; i < eventEntries.length; i += 1) {\n const entry = eventEntries[i];\n const observable = this._map.get(entry.id);\n observable?.update(entry);\n }\n }\n\n _remove(id) {\n this._map.delete(id);\n if (this._map.size === 0) {\n this._notifyEmpty();\n }\n }\n}\n\nclass ObservedEvent extends BaseObservableValue {\n constructor(eventMap, entry, id) {\n super();\n this._eventMap = eventMap;\n this._entry = entry;\n this._id = id;\n // remove subscription in microtask after creating it\n // otherwise ObservedEvents would easily never get\n // removed if you never subscribe\n Promise.resolve().then(() => {\n if (!this.hasSubscriptions) {\n this._eventMap._remove(this._id);\n this._eventMap = null;\n }\n });\n }\n\n subscribe(handler) {\n if (!this._eventMap) {\n throw new Error(\"ObservedEvent expired, subscribe right after calling room.observeEvent()\");\n }\n return super.subscribe(handler);\n }\n\n onUnsubscribeLast() {\n this._eventMap._remove(this._id);\n this._eventMap = null;\n super.onUnsubscribeLast();\n }\n\n update(entry) {\n // entries are mostly updated in-place,\n // apart from when they are created,\n // but doesn't hurt to reassign\n this._entry = entry;\n this.emit(this._entry);\n }\n\n get() {\n return this._entry;\n }\n}\n","// these are helper functions if you can't assume you always have a log item (e.g. some code paths call with one set, others don't)\n// if you know you always have a log item, better to use the methods on the log item than these utility functions.\n\nimport {Instance as NullLoggerInstance} from \"./NullLogger\";\nimport type {FilterCreator, ILogItem, LabelOrValues, LogCallback} from \"./types\";\nimport {LogLevel} from \"./LogFilter\";\n\nexport function wrapOrRunNullLogger(logItem: ILogItem | undefined, labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): T | Promise {\n if (logItem) {\n return logItem.wrap(labelOrValues, callback, logLevel, filterCreator);\n } else {\n return NullLoggerInstance.run(null, callback);\n }\n}\n\nexport function ensureLogItem(logItem: ILogItem): ILogItem {\n return logItem || NullLoggerInstance.item;\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport const EVENT_TYPE = \"m.room.power_levels\";\n\n// See https://spec.matrix.org/latest/client-server-api/#mroompower_levels\nconst STATE_DEFAULT_POWER_LEVEL = 50;\n\nexport class PowerLevels {\n constructor({powerLevelEvent, createEvent, ownUserId, membership}) {\n this._plEvent = powerLevelEvent;\n this._createEvent = createEvent;\n this._ownUserId = ownUserId;\n this._membership = membership;\n }\n\n canRedactFromSender(userId) {\n if (userId === this._ownUserId && this._membership === \"join\") {\n return true;\n } else {\n return this.canRedact;\n }\n }\n\n canSendType(eventType) {\n return this._myLevel >= this._getEventTypeLevel(eventType);\n }\n\n get canRedact() {\n return this._myLevel >= this._getActionLevel(\"redact\");\n }\n\n get _myLevel() {\n if (this._membership !== \"join\") {\n return Number.MIN_SAFE_INTEGER;\n }\n return this.getUserLevel(this._ownUserId);\n }\n\n getUserLevel(userId) {\n if (this._plEvent) {\n let userLevel = this._plEvent.content?.users?.[userId];\n if (typeof userLevel !== \"number\") {\n userLevel = this._plEvent.content?.users_default;\n }\n if (typeof userLevel === \"number\") {\n return userLevel;\n }\n } else if (this._createEvent) {\n if (userId === this._createEvent.content?.creator) {\n return 100;\n }\n }\n return 0;\n }\n\n /** @param {string} action either \"invite\", \"kick\", \"ban\" or \"redact\". */\n _getActionLevel(action) {\n const level = this._plEvent?.content?.[action];\n if (typeof level === \"number\") {\n return level;\n } else {\n return STATE_DEFAULT_POWER_LEVEL;\n }\n }\n\n _getEventTypeLevel(eventType) {\n const level = this._plEvent?.content?.events?.[eventType];\n if (typeof level === \"number\") {\n return level;\n } else {\n const level = this._plEvent?.content?.events_default;\n if (typeof level === \"number\") {\n return level;\n } else {\n return 0;\n }\n }\n }\n}\n\nexport function tests() {\n const alice = \"@alice:hs.tld\";\n const bob = \"@bob:hs.tld\";\n const charly = \"@charly:hs.tld\";\n const createEvent = {content: {creator: alice}};\n const redactPowerLevelEvent = {content: {\n redact: 50,\n users: {\n [alice]: 50\n },\n users_default: 0\n }};\n const eventsPowerLevelEvent = {content: {\n events_default: 5,\n events: {\n \"m.room.message\": 45,\n \"m.room.topic\": 50,\n },\n users: {\n [alice]: 50,\n [bob]: 10\n },\n users_default: 0\n }};\n\n return {\n \"redact somebody else event with power level event\": assert => {\n const pl1 = new PowerLevels({powerLevelEvent: redactPowerLevelEvent, ownUserId: alice, membership: \"join\"});\n assert.equal(pl1.canRedact, true);\n const pl2 = new PowerLevels({powerLevelEvent: redactPowerLevelEvent, ownUserId: bob, membership: \"join\"});\n assert.equal(pl2.canRedact, false);\n },\n \"redact somebody else event with create event\": assert => {\n const pl1 = new PowerLevels({createEvent, ownUserId: alice, membership: \"join\"});\n assert.equal(pl1.canRedact, true);\n const pl2 = new PowerLevels({createEvent, ownUserId: bob, membership: \"join\"});\n assert.equal(pl2.canRedact, false);\n },\n \"redact own event\": assert => {\n const pl = new PowerLevels({ownUserId: alice, membership: \"join\"});\n assert.equal(pl.canRedactFromSender(alice), true);\n assert.equal(pl.canRedactFromSender(bob), false);\n },\n \"can send event without power levels\": assert => {\n const pl = new PowerLevels({createEvent, ownUserId: charly, membership: \"join\"});\n assert.equal(pl.canSendType(\"m.room.message\"), true);\n },\n \"can't send any event below events_default\": assert => {\n const pl = new PowerLevels({powerLevelEvent: eventsPowerLevelEvent, ownUserId: charly, membership: \"join\"});\n assert.equal(pl.canSendType(\"m.foo\"), false);\n },\n \"can't send event below events[type]\": assert => {\n const pl = new PowerLevels({powerLevelEvent: eventsPowerLevelEvent, ownUserId: bob, membership: \"join\"});\n assert.equal(pl.canSendType(\"m.foo\"), true);\n assert.equal(pl.canSendType(\"m.room.message\"), false);\n },\n \"can send event above or at events[type]\": assert => {\n const pl = new PowerLevels({powerLevelEvent: eventsPowerLevelEvent, ownUserId: alice, membership: \"join\"});\n assert.equal(pl.canSendType(\"m.room.message\"), true);\n assert.equal(pl.canSendType(\"m.room.topic\"), true);\n },\n \"can't redact or send in non-joined room'\": assert => {\n const pl = new PowerLevels({createEvent, ownUserId: alice, membership: \"leave\"});\n assert.equal(pl.canRedact, false);\n assert.equal(pl.canRedactFromSender(alice), false);\n assert.equal(pl.canSendType(\"m.room.message\"), false);\n },\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {StateObserver} from \"./types\";\nimport type {StateEvent} from \"../../storage/types\";\nimport type {Transaction} from \"../../storage/idb/Transaction\";\nimport {ObservableMap} from \"../../../observable/map\";\n\n/**\n * Observable map for a given type with state keys as map keys.\n * Unsubscribes when last subscription is removed */\nexport class ObservedStateTypeMap extends ObservableMap implements StateObserver {\n private removeCallback?: () => void;\n \n constructor(private readonly type: string) {\n super();\n }\n /** @internal */\n async load(roomId: string, txn: Transaction): Promise {\n const events = await txn.roomState.getAllForType(roomId, this.type);\n for (let i = 0; i < events.length; ++i) {\n const {event} = events[i];\n this.add(event.state_key, event);\n }\n }\n /** @internal */\n handleStateEvent(event: StateEvent) {\n if (event.type === this.type) {\n this.set(event.state_key, event);\n }\n }\n\n setRemoveCallback(callback: () => void) {\n this.removeCallback = callback;\n }\n\n onUnsubscribeLast() {\n this.removeCallback?.();\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {StateObserver} from \"./types\";\nimport type {StateEvent} from \"../../storage/types\";\nimport type {Transaction} from \"../../storage/idb/Transaction\";\nimport {BaseObservableValue} from \"../../../observable/value\";\n\n/**\n * Observable value for a state event with a given type and state key.\n * Unsubscribes when last subscription is removed */\nexport class ObservedStateKeyValue extends BaseObservableValue implements StateObserver {\n private event?: StateEvent;\n private removeCallback?: () => void;\n\n constructor(private readonly type: string, private readonly stateKey: string) {\n super();\n }\n /** @internal */\n async load(roomId: string, txn: Transaction): Promise {\n this.event = (await txn.roomState.get(roomId, this.type, this.stateKey))?.event;\n }\n /** @internal */\n handleStateEvent(event: StateEvent) {\n if (event.type === this.type && event.state_key === this.stateKey) {\n this.event = event;\n this.emit(this.get());\n }\n }\n\n get(): StateEvent | undefined {\n return this.event;\n }\n\n setRemoveCallback(callback: () => void) {\n this.removeCallback = callback;\n }\n\n onUnsubscribeLast() {\n this.removeCallback?.();\n }\n}\n\nimport {createMockStorage} from \"../../../mocks/Storage\";\n\nexport async function tests() {\n return {\n \"test load and update\": async assert => {\n const storage = await createMockStorage();\n const writeTxn = await storage.readWriteTxn([storage.storeNames.roomState]);\n writeTxn.roomState.set(\"!abc\", {\n event_id: \"$abc\",\n type: \"m.room.member\",\n state_key: \"@alice\",\n sender: \"@alice\",\n origin_server_ts: 5,\n content: {}\n });\n await writeTxn.complete();\n const txn = await storage.readTxn([storage.storeNames.roomState]);\n const value = new ObservedStateKeyValue(\"m.room.member\", \"@alice\");\n await value.load(\"!abc\", txn);\n const updates: Array = [];\n assert.strictEqual(value.get()?.origin_server_ts, 5);\n const unsubscribe = value.subscribe(value => updates.push(value));\n value.handleStateEvent({\n event_id: \"$abc\",\n type: \"m.room.member\",\n state_key: \"@bob\",\n sender: \"@alice\",\n origin_server_ts: 10,\n content: {}\n });\n assert.strictEqual(updates.length, 0);\n value.handleStateEvent({\n event_id: \"$abc\",\n type: \"m.room.member\",\n state_key: \"@alice\",\n sender: \"@alice\",\n origin_server_ts: 10,\n content: {}\n });\n assert.strictEqual(updates.length, 1);\n assert.strictEqual(updates[0]?.origin_server_ts, 10);\n let removed = false;\n value.setRemoveCallback(() => removed = true);\n unsubscribe();\n assert(removed);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventEmitter} from \"../../utils/EventEmitter\";\nimport {RoomSummary} from \"./RoomSummary.js\";\nimport {GapWriter} from \"./timeline/persistence/GapWriter.js\";\nimport {RelationWriter} from \"./timeline/persistence/RelationWriter.js\";\nimport {Timeline} from \"./timeline/Timeline.js\";\nimport {FragmentIdComparer} from \"./timeline/FragmentIdComparer.js\";\nimport {WrappedError} from \"../error.js\"\nimport {fetchOrLoadMembers, fetchOrLoadMember} from \"./members/load.js\";\nimport {MemberList} from \"./members/MemberList.js\";\nimport {Heroes} from \"./members/Heroes.js\";\nimport {EventEntry} from \"./timeline/entries/EventEntry.js\";\nimport {ObservedEventMap} from \"./ObservedEventMap.js\";\nimport {DecryptionSource} from \"../e2ee/common\";\nimport {ensureLogItem} from \"../../logging/utils\";\nimport {PowerLevels} from \"./PowerLevels.js\";\nimport {RetainedObservableValue} from \"../../observable/value\";\nimport {TimelineReader} from \"./timeline/persistence/TimelineReader\";\nimport {ObservedStateTypeMap} from \"./state/ObservedStateTypeMap\";\nimport {ObservedStateKeyValue} from \"./state/ObservedStateKeyValue\";\n\nconst EVENT_ENCRYPTED_TYPE = \"m.room.encrypted\";\n\nexport class BaseRoom extends EventEmitter {\n constructor({roomId, storage, hsApi, mediaRepository, emitCollectionChange, user, createRoomEncryption, getSyncToken, platform}) {\n super();\n this._roomId = roomId;\n this._storage = storage;\n this._hsApi = hsApi;\n this._mediaRepository = mediaRepository;\n this._summary = new RoomSummary(roomId);\n this._fragmentIdComparer = new FragmentIdComparer([]);\n this._emitCollectionChange = emitCollectionChange;\n this._timeline = null;\n this._user = user;\n this._changedMembersDuringSync = null;\n this._memberList = null;\n this._createRoomEncryption = createRoomEncryption;\n this._roomEncryption = null;\n this._getSyncToken = getSyncToken;\n this._platform = platform;\n this._observedEvents = null;\n this._roomStateObservers = new Set();\n this._powerLevels = null;\n this._powerLevelLoading = null;\n this._observedMembers = null;\n this._timelineLoadPromise = null;\n }\n\n async observeStateType(type, txn = undefined) {\n const map = new ObservedStateTypeMap(type);\n await this._addStateObserver(map, txn);\n return map;\n }\n\n async observeStateTypeAndKey(type, stateKey, txn = undefined) {\n const value = new ObservedStateKeyValue(type, stateKey);\n await this._addStateObserver(value, txn);\n return value;\n }\n\n async _addStateObserver(stateObserver, txn) {\n if (!txn) {\n txn = await this._storage.readTxn([this._storage.storeNames.roomState]);\n }\n await stateObserver.load(this.id, txn);\n this._roomStateObservers.add(stateObserver);\n stateObserver.setRemoveCallback(() => {\n this._roomStateObservers.delete(stateObserver);\n });\n }\n\n async _eventIdsToEntries(eventIds, txn) {\n const retryEntries = [];\n await Promise.all(eventIds.map(async eventId => {\n const storageEntry = await txn.timelineEvents.getByEventId(this._roomId, eventId);\n if (storageEntry) {\n retryEntries.push(new EventEntry(storageEntry, this._fragmentIdComparer));\n }\n }));\n return retryEntries;\n }\n\n _getAdditionalTimelineRetryEntries(otherRetryEntries, roomKeys) {\n let retryTimelineEntries = this._roomEncryption.filterUndecryptedEventEntriesForKeys(this._timeline.remoteEntries, roomKeys);\n // filter out any entries already in retryEntries so we don't decrypt them twice\n const existingIds = otherRetryEntries.reduce((ids, e) => {ids.add(e.id); return ids;}, new Set());\n retryTimelineEntries = retryTimelineEntries.filter(e => !existingIds.has(e.id));\n return retryTimelineEntries;\n }\n\n /**\n * Used for retrying decryption from other sources than sync, like key backup.\n * @internal\n * @param {RoomKey} roomKey\n * @param {Array} eventIds any event ids that should be retried. There might be more in the timeline though for this key.\n * @return {Promise}\n */\n async notifyRoomKey(roomKey, eventIds, log) {\n if (!this._roomEncryption) {\n return;\n }\n const txn = await this._storage.readTxn([\n this._storage.storeNames.timelineEvents,\n this._storage.storeNames.inboundGroupSessions,\n ]);\n let retryEntries = await this._eventIdsToEntries(eventIds, txn);\n if (this._timeline) {\n const retryTimelineEntries = this._getAdditionalTimelineRetryEntries(retryEntries, [roomKey]);\n retryEntries = retryEntries.concat(retryTimelineEntries);\n }\n if (retryEntries.length) {\n const decryptRequest = this._decryptEntries(DecryptionSource.Retry, retryEntries, txn, log);\n // this will close txn while awaiting decryption\n await decryptRequest.complete();\n\n this._timeline?.replaceEntries(retryEntries);\n // we would ideally write the room summary in the same txn as the groupSessionDecryptions in the\n // _decryptEntries entries and could even know which events have been decrypted for the first\n // time from DecryptionChanges.write and only pass those to the summary. As timeline changes\n // are not essential to the room summary, it's fine to write this in a separate txn for now.\n const changes = this._summary.data.applyTimelineEntries(retryEntries, false, false);\n if (await this._summary.writeAndApplyData(changes, this._storage)) {\n this._emitUpdate();\n }\n }\n }\n\n _setEncryption(roomEncryption) {\n if (roomEncryption && !this._roomEncryption) {\n this._roomEncryption = roomEncryption;\n if (this._timeline) {\n this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));\n }\n return true;\n }\n return false;\n }\n\n /**\n * Used for decrypting when loading/filling the timeline, and retrying decryption,\n * not during sync, where it is split up during the multiple phases.\n */\n _decryptEntries(source, entries, inboundSessionTxn, log = null) {\n const request = new DecryptionRequest(async (r, log) => {\n if (!inboundSessionTxn) {\n inboundSessionTxn = await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);\n }\n if (r.cancelled) return;\n const events = entries.filter(entry => {\n return entry.eventType === EVENT_ENCRYPTED_TYPE;\n }).map(entry => entry.event);\n r.preparation = await this._roomEncryption.prepareDecryptAll(events, null, source, inboundSessionTxn);\n if (r.cancelled) return;\n const changes = await r.preparation.decrypt();\n r.preparation = null;\n if (r.cancelled) return;\n const stores = [this._storage.storeNames.groupSessionDecryptions];\n const isTimelineOpen = this._isTimelineOpen;\n if (isTimelineOpen) {\n // read to fetch devices if timeline is open\n stores.push(this._storage.storeNames.deviceKeys);\n }\n const writeTxn = await this._storage.readWriteTxn(stores);\n let decryption;\n try {\n decryption = await changes.write(writeTxn, log);\n if (isTimelineOpen) {\n await decryption.verifyKnownSenders(writeTxn);\n }\n } catch (err) {\n writeTxn.abort();\n throw err;\n }\n await writeTxn.complete();\n // TODO: log decryption errors here\n decryption.applyToEntries(entries);\n if (this._observedEvents) {\n this._observedEvents.updateEvents(entries);\n }\n if (isTimelineOpen && decryption.hasUnverifiedSenders) {\n // verify missing senders async and update timeline once done so we don't delay rendering with network requests\n log.wrapDetached(\"fetch unknown senders keys\", async log => {\n const newlyVerifiedDecryption = await decryption.fetchAndVerifyRemainingSenders(this._hsApi, log);\n const verifiedEntries = [];\n newlyVerifiedDecryption.applyToEntries(entries, entry => verifiedEntries.push(entry));\n this._timeline?.replaceEntries(verifiedEntries);\n this._observedEvents?.updateEvents(verifiedEntries);\n });\n }\n }, ensureLogItem(log));\n return request;\n }\n\n // TODO: move this to Room\n async _getSyncRetryDecryptEntries(newKeys, roomEncryption, txn) {\n const entriesPerKey = await Promise.all(newKeys.map(async key => {\n const retryEventIds = await roomEncryption.getEventIdsForMissingKey(key, txn);\n if (retryEventIds) {\n return this._eventIdsToEntries(retryEventIds, txn);\n }\n }));\n let retryEntries = entriesPerKey.reduce((allEntries, entries) => entries ? allEntries.concat(entries) : allEntries, []);\n // If we have the timeline open, see if there are more entries for the new keys\n // as we only store missing session information for synced events, not backfilled.\n // We want to decrypt all events we can though if the user is looking\n // at them when the timeline is open\n if (this._timeline) {\n const retryTimelineEntries = this._getAdditionalTimelineRetryEntries(retryEntries, newKeys);\n // make copies so we don't modify the original entry in writeSync, before the afterSync stage\n const retryTimelineEntriesCopies = retryTimelineEntries.map(e => e.clone());\n // add to other retry entries\n retryEntries = retryEntries.concat(retryTimelineEntriesCopies);\n }\n return retryEntries;\n }\n\n /** @package */\n async load(summary, txn, log) {\n log.set(\"id\", this.id);\n try {\n // if called from sync, there is no summary yet\n if (summary) {\n this._summary.load(summary);\n }\n if (this._summary.data.encryption) {\n const roomEncryption = this._createRoomEncryption(this, this._summary.data.encryption);\n this._setEncryption(roomEncryption);\n }\n // need to load members for name?\n if (this._summary.data.needsHeroes) {\n this._heroes = new Heroes(this._roomId);\n const changes = await this._heroes.calculateChanges(this._summary.data.heroes, [], txn);\n this._heroes.applyChanges(changes, this._summary.data, log);\n }\n } catch (err) {\n throw new WrappedError(`Could not load room ${this._roomId}`, err);\n }\n }\n\n async observeMember(userId) {\n if (!this._observedMembers) {\n this._observedMembers = new Map();\n }\n const mapMember = this._observedMembers.get(userId);\n if (mapMember) {\n // Hit, we're already observing this member\n return mapMember;\n }\n // Miss, load from storage/hs and set in map\n const member = await fetchOrLoadMember({\n summary: this._summary,\n roomId: this._roomId,\n userId,\n storage: this._storage,\n hsApi: this._hsApi\n }, this._platform.logger);\n if (!member) {\n return null;\n }\n const observableMember = new RetainedObservableValue(member, () => this._observedMembers.delete(userId));\n this._observedMembers.set(userId, observableMember);\n return observableMember;\n }\n\n\n /** @public */\n async loadMemberList(txn = undefined, log = null) {\n if (this._memberList) {\n // TODO: also await fetchOrLoadMembers promise here\n this._memberList.retain();\n return this._memberList;\n } else {\n const members = await fetchOrLoadMembers({\n summary: this._summary,\n roomId: this._roomId,\n hsApi: this._hsApi,\n storage: this._storage,\n // pass in a transaction if we know we won't need to fetch (which would abort the transaction)\n // and we want to make this operation part of the larger transaction\n txn,\n syncToken: this._getSyncToken(),\n // to handle race between /members and /sync\n setChangedMembersMap: map => this._changedMembersDuringSync = map,\n log,\n }, this._platform.logger);\n this._memberList = new MemberList({\n members,\n closeCallback: () => { this._memberList = null; }\n });\n return this._memberList;\n }\n } \n\n /** @public */\n fillGap(fragmentEntry, amount, log = null) {\n // TODO move some/all of this out of BaseRoom\n return this._platform.logger.wrapOrRun(log, \"fillGap\", async log => {\n log.set(\"id\", this.id);\n log.set(\"fragment\", fragmentEntry.fragmentId);\n log.set(\"dir\", fragmentEntry.direction.asApiString());\n if (fragmentEntry.edgeReached) {\n log.set(\"edgeReached\", true);\n return;\n }\n const response = await this._hsApi.messages(this._roomId, {\n from: fragmentEntry.token,\n dir: fragmentEntry.direction.asApiString(),\n limit: amount,\n filter: {\n lazy_load_members: true,\n include_redundant_members: true,\n }\n }, {log}).response();\n\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.pendingEvents,\n this._storage.storeNames.timelineEvents,\n this._storage.storeNames.timelineRelations,\n this._storage.storeNames.timelineFragments,\n ]);\n let extraGapFillChanges;\n let gapResult;\n try {\n // detect remote echos of pending messages in the gap\n extraGapFillChanges = await this._writeGapFill(response.chunk, txn, log);\n // write new events into gap\n const relationWriter = new RelationWriter({\n roomId: this._roomId,\n fragmentIdComparer: this._fragmentIdComparer,\n ownUserId: this._user.id,\n });\n const gapWriter = new GapWriter({\n roomId: this._roomId,\n storage: this._storage,\n fragmentIdComparer: this._fragmentIdComparer,\n relationWriter\n });\n gapResult = await gapWriter.writeFragmentFill(fragmentEntry, response, fragmentEntry.token, txn, log);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n if (this._roomEncryption) {\n const decryptRequest = this._decryptEntries(DecryptionSource.Timeline, gapResult.entries, null, log);\n await decryptRequest.complete();\n }\n // once txn is committed, update in-memory state & emit events\n for (const fragment of gapResult.fragments) {\n this._fragmentIdComparer.add(fragment);\n }\n if (extraGapFillChanges) {\n this._applyGapFill(extraGapFillChanges);\n }\n if (this._timeline) {\n // these should not be added if not already there\n this._timeline.replaceEntries(gapResult.updatedEntries);\n this._timeline.addEntries(gapResult.entries);\n }\n });\n }\n\n /**\n allow sub classes to integrate in the gap fill lifecycle.\n JoinedRoom uses this update remote echos.\n */\n // eslint-disable-next-line no-unused-vars\n async _writeGapFill(chunk, txn, log) {}\n _applyGapFill() {}\n\n /** @public */\n get name() {\n if (this._heroes) {\n return this._heroes.roomName;\n }\n const summaryData = this._summary.data;\n if (summaryData.name) {\n return summaryData.name;\n }\n if (summaryData.canonicalAlias) {\n return summaryData.canonicalAlias;\n }\n return null;\n }\n\n /** @public */\n get id() {\n return this._roomId;\n }\n\n get avatarUrl() {\n if (this._summary.data.avatarUrl) {\n return this._summary.data.avatarUrl;\n } else if (this._heroes) {\n return this._heroes.roomAvatarUrl;\n }\n return null;\n }\n\n /**\n * Retrieve the identifier that should be used to color\n * this room's avatar. By default this is the room's\n * ID, but DM rooms should be the same color as their\n * user's avatar.\n */\n get avatarColorId() {\n return this._roomId;\n }\n\n get lastMessageTimestamp() {\n return this._summary.data.lastMessageTimestamp;\n }\n\n get isLowPriority() {\n const tags = this._summary.data.tags;\n return !!(tags && tags['m.lowpriority']);\n }\n\n get isEncrypted() {\n return !!this._summary.data.encryption;\n }\n\n get isJoined() {\n return this.membership === \"join\";\n }\n\n get isLeft() {\n return this.membership === \"leave\";\n }\n\n get canonicalAlias() {\n return this._summary.data.canonicalAlias;\n }\n\n get joinedMemberCount() {\n return this._summary.data.joinCount;\n }\n\n get mediaRepository() {\n return this._mediaRepository;\n }\n\n get membership() {\n return this._summary.data.membership;\n }\n\n get user() {\n return this._user;\n }\n\n isDirectMessageForUserId(userId) {\n if (this._summary.data.dmUserId === userId) {\n return true;\n } else {\n // fall back to considering any room a DM containing heroes (e.g. no name) and 2 members,\n // on of which the userId we're looking for.\n // We need this because we're not yet processing m.direct account data correctly.\n const {heroes, joinCount, inviteCount} = this._summary.data;\n if (heroes && heroes.includes(userId) && (joinCount + inviteCount) === 2) {\n return true;\n }\n }\n return false;\n }\n\n async _loadPowerLevels() {\n const txn = await this._storage.readTxn([this._storage.storeNames.roomState]);\n const powerLevelsState = await txn.roomState.get(this._roomId, \"m.room.power_levels\", \"\");\n if (powerLevelsState) {\n return new PowerLevels({\n powerLevelEvent: powerLevelsState.event,\n ownUserId: this._user.id,\n membership: this.membership\n });\n }\n const createState = await txn.roomState.get(this._roomId, \"m.room.create\", \"\");\n if (createState) {\n return new PowerLevels({\n createEvent: createState.event,\n ownUserId: this._user.id,\n membership: this.membership\n });\n } else {\n const membership = this.membership;\n return new PowerLevels({ownUserId: this._user.id, membership});\n }\n }\n\n /**\n * Get the PowerLevels of the room.\n * Always subscribe to the value returned by this method.\n * @returns {RetainedObservableValue} PowerLevels of the room\n */\n async observePowerLevels() {\n if (this._powerLevelLoading) { await this._powerLevelLoading; }\n let observable = this._powerLevels;\n if (!observable) {\n this._powerLevelLoading = this._loadPowerLevels();\n const powerLevels = await this._powerLevelLoading;\n observable = new RetainedObservableValue(powerLevels, () => { this._powerLevels = null; });\n this._powerLevels = observable;\n this._powerLevelLoading = null;\n }\n return observable;\n }\n\n enableKeyBackup(keyBackup) {\n this._roomEncryption?.enableKeyBackup(keyBackup);\n // TODO: do we really want to do this every time you open the app?\n if (this._timeline && keyBackup) {\n this._platform.logger.run(\"enableKeyBackup\", log => {\n return this._roomEncryption.restoreMissingSessionsFromBackup(this._timeline.remoteEntries, log);\n });\n }\n }\n\n get _isTimelineOpen() {\n return !!this._timeline;\n }\n\n _emitUpdate() {\n // once for event emitter listeners\n this.emit(\"change\");\n // and once for collection listeners\n this._emitCollectionChange(this);\n }\n\n /** @public */\n async openTimeline(log = null) {\n return await this._platform.logger.wrapOrRun(log, \"open timeline\", async log => {\n if (this._timelineLoadPromise) {\n // This is to prevent races between multiple calls to this method\n await this._timelineLoadPromise;\n }\n let resolve;\n this._timelineLoadPromise = new Promise(r => {\n resolve = () => { \n this._timelineLoadPromise = null;\n r();\n };\n });\n log.set(\"id\", this.id);\n if (this._timeline) {\n log.log({ l: \"Returning existing timeline\" });\n resolve();\n this._timeline.retain();\n return this._timeline;\n }\n this._timeline = new Timeline({\n roomId: this.id,\n storage: this._storage,\n fragmentIdComparer: this._fragmentIdComparer,\n pendingEvents: this._getPendingEvents(),\n closeCallback: () => {\n this._timeline = null;\n if (this._roomEncryption) {\n this._roomEncryption.notifyTimelineClosed();\n }\n },\n clock: this._platform.clock,\n logger: this._platform.logger,\n powerLevelsObservable: await this.observePowerLevels(),\n hsApi: this._hsApi\n });\n try {\n if (this._roomEncryption) {\n this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));\n }\n await this._timeline.load(this._user, this.membership, log);\n } catch (err) {\n // this also clears this._timeline in the closeCallback\n this._timeline.dispose();\n throw err;\n } finally {\n resolve();\n }\n this._timeline.retain();\n return this._timeline;\n });\n }\n\n /* allow subclasses to provide an observable list with pending events when opening the timeline */\n _getPendingEvents() { return null; }\n\n observeEvent(eventId) {\n if (!this._observedEvents) {\n this._observedEvents = new ObservedEventMap(() => {\n this._observedEvents = null;\n });\n }\n let entry = null;\n if (this._timeline) {\n entry = this._timeline.getByEventId(eventId);\n }\n const observable = this._observedEvents.observe(eventId, entry);\n if (!entry) {\n // update in the background\n this._readEventById(eventId).then(entry => {\n observable.update(entry);\n }).catch(err => {\n console.warn(`could not load event ${eventId} from storage`, err);\n });\n }\n return observable;\n }\n\n async _readEventById(eventId) {\n const reader = new TimelineReader({ roomId: this._roomId, storage: this._storage, fragmentIdComparer: this._fragmentIdComparer });\n const entry = await reader.readById(eventId);\n return entry;\n }\n\n dispose() {\n this._roomEncryption?.dispose();\n }\n}\n\nclass DecryptionRequest {\n constructor(decryptFn, log) {\n this._cancelled = false;\n this.preparation = null;\n this._promise = log.wrap(\"decryptEntries\", log => decryptFn(this, log));\n }\n\n complete() {\n return this._promise;\n }\n\n get cancelled() {\n return this._cancelled;\n }\n\n dispose() {\n this._cancelled = true;\n if (this.preparation) {\n this.preparation.dispose();\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SortedArray} from \"../../../observable/list/SortedArray\";\nimport {ConnectionError} from \"../../error.js\";\nimport {PendingEvent, SendStatus} from \"./PendingEvent.js\";\nimport {makeTxnId, isTxnId} from \"../../common.js\";\nimport {REDACTION_TYPE} from \"../common\";\nimport {getRelationFromContent, getRelationTarget, setRelationTarget, REACTION_TYPE, ANNOTATION_RELATION_TYPE} from \"../timeline/relations.js\";\n\nexport class SendQueue {\n constructor({roomId, storage, hsApi, pendingEvents}) {\n pendingEvents = pendingEvents || [];\n this._roomId = roomId;\n this._storage = storage;\n this._hsApi = hsApi;\n this._pendingEvents = new SortedArray((a, b) => a.queueIndex - b.queueIndex);\n this._pendingEvents.setManyUnsorted(pendingEvents.map(data => this._createPendingEvent(data)));\n this._isSending = false;\n this._offline = false;\n this._roomEncryption = null;\n this._currentQueueIndex = 0;\n }\n\n _createPendingEvent(data, attachments = null) {\n const pendingEvent = new PendingEvent({\n data,\n remove: () => this._removeEvent(pendingEvent),\n emitUpdate: params => this._pendingEvents.update(pendingEvent, params),\n attachments\n });\n return pendingEvent;\n }\n\n enableEncryption(roomEncryption) {\n this._roomEncryption = roomEncryption;\n }\n\n _sendLoop(log) {\n this._isSending = true;\n this._sendLoopLogItem = log.runDetached(\"send queue flush\", async log => {\n try {\n for (const pendingEvent of this._pendingEvents) {\n await log.wrap(\"send event\", async log => {\n log.set(\"queueIndex\", pendingEvent.queueIndex);\n try {\n this._currentQueueIndex = pendingEvent.queueIndex;\n await this._sendEvent(pendingEvent, log);\n } catch(err) {\n if (err instanceof ConnectionError) {\n this._offline = true;\n log.set(\"offline\", true);\n pendingEvent.setWaiting();\n } else {\n log.catch(err);\n const isPermanentError = err.name === \"HomeServerError\" && (\n err.statusCode === 400 || // bad request, must be a bug on our end\n err.statusCode === 403 || // forbidden\n err.statusCode === 404 // not found\n );\n if (isPermanentError) {\n log.set(\"remove\", true);\n await pendingEvent.abort();\n } else {\n pendingEvent.setError(err);\n }\n }\n } finally {\n this._currentQueueIndex = 0;\n }\n });\n }\n } finally {\n this._isSending = false;\n this._sendLoopLogItem = null;\n }\n });\n }\n\n async _sendEvent(pendingEvent, log) {\n if (pendingEvent.needsUpload) {\n await log.wrap(\"upload attachments\", log => pendingEvent.uploadAttachments(this._hsApi, log));\n await this._tryUpdateEvent(pendingEvent);\n }\n if (pendingEvent.needsEncryption) {\n pendingEvent.setEncrypting();\n const encryptionContent = pendingEvent.contentForEncryption;\n const {type, content} = await log.wrap(\"encrypt\", log => this._roomEncryption.encrypt(\n pendingEvent.eventType, encryptionContent, this._hsApi, log));\n pendingEvent.setEncrypted(type, content);\n await this._tryUpdateEvent(pendingEvent);\n }\n if (pendingEvent.needsSending) {\n await pendingEvent.send(this._hsApi, log);\n // we now have a remoteId, but this pending event may be removed at any point in the future\n // (or past, so can't assume it still exists) once the remote echo comes in.\n // So if we have any related events that need to resolve the relatedTxnId to a related event id,\n // they need to do so now.\n // We ensure this by writing the new remote id for the pending event and all related events\n // with unresolved relatedTxnId in the queue in one transaction.\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);\n try {\n await this._tryUpdateEventWithTxn(pendingEvent, txn);\n await this._resolveRemoteIdInPendingRelations(\n pendingEvent.txnId, pendingEvent.remoteId, txn);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n }\n }\n\n async _resolveRemoteIdInPendingRelations(txnId, remoteId, txn) {\n const relatedEventWithoutRemoteId = this._pendingEvents.array.filter(pe => {\n return pe.relatedTxnId === txnId && pe.relatedEventId !== remoteId;\n });\n for (const relatedPE of relatedEventWithoutRemoteId) {\n relatedPE.setRelatedEventId(remoteId);\n await this._tryUpdateEventWithTxn(relatedPE, txn);\n }\n return relatedEventWithoutRemoteId;\n }\n\n async removeRemoteEchos(events, txn, parentLog) {\n const removed = [];\n for (const event of events) {\n const txnId = event.unsigned && event.unsigned.transaction_id;\n let idx;\n if (txnId) {\n idx = this._pendingEvents.array.findIndex(pe => pe.txnId === txnId);\n } else {\n idx = this._pendingEvents.array.findIndex(pe => pe.remoteId === event.event_id);\n }\n if (idx !== -1) {\n const pendingEvent = this._pendingEvents.get(idx);\n const remoteId = event.event_id;\n parentLog.log({l: \"removeRemoteEcho\", queueIndex: pendingEvent.queueIndex, remoteId, txnId});\n txn.pendingEvents.remove(pendingEvent.roomId, pendingEvent.queueIndex);\n removed.push(pendingEvent);\n await this._resolveRemoteIdInPendingRelations(txnId, remoteId, txn);\n }\n }\n return removed;\n }\n\n async _removeEvent(pendingEvent) {\n let hasEvent = this._pendingEvents.array.indexOf(pendingEvent) !== -1;\n if (hasEvent) {\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);\n try {\n txn.pendingEvents.remove(pendingEvent.roomId, pendingEvent.queueIndex);\n } catch (err) {\n txn.abort();\n }\n await txn.complete();\n // lookup index after async txn is complete,\n // to make sure we're not racing with anything\n const idx = this._pendingEvents.array.indexOf(pendingEvent);\n if (idx !== -1) {\n this._pendingEvents.remove(idx);\n }\n }\n pendingEvent.dispose();\n }\n\n emitRemovals(pendingEvents) {\n for (const pendingEvent of pendingEvents) {\n const idx = this._pendingEvents.array.indexOf(pendingEvent);\n if (idx !== -1) {\n this._pendingEvents.remove(idx);\n }\n pendingEvent.dispose();\n }\n }\n\n resumeSending(parentLog) {\n this._offline = false;\n if (this._pendingEvents.length) {\n parentLog.wrap(\"resumeSending\", log => {\n log.set(\"id\", this._roomId);\n log.set(\"pendingEvents\", this._pendingEvents.length);\n if (!this._isSending) {\n this._sendLoop(log);\n }\n if (this._sendLoopLogItem) {\n log.refDetached(this._sendLoopLogItem);\n }\n });\n }\n }\n\n async enqueueEvent(eventType, content, attachments, log) {\n const relation = getRelationFromContent(content);\n let relatedTxnId = null;\n if (relation) {\n const relationTarget = getRelationTarget(relation);\n if (isTxnId(relationTarget)) {\n relatedTxnId = relationTarget;\n setRelationTarget(relation, null);\n }\n if (relation.rel_type === ANNOTATION_RELATION_TYPE) {\n // Here we know the shape of the relation, and can use event_id safely\n const isAlreadyAnnotating = this._pendingEvents.array.some(pe => {\n const r = getRelationFromContent(pe.content);\n return pe.eventType === eventType && r && r.key === relation.key &&\n (pe.relatedTxnId === relatedTxnId || r.event_id === relation.event_id);\n });\n if (isAlreadyAnnotating) {\n log.set(\"already_annotating\", true);\n return;\n }\n }\n }\n return await this._enqueueEvent(eventType, content, attachments, relatedTxnId, null, log);\n }\n\n async _enqueueEvent(eventType, content, attachments, relatedTxnId, relatedEventId, log) {\n const pendingEvent = await this._createAndStoreEvent(eventType, content, relatedTxnId, relatedEventId, attachments);\n this._pendingEvents.set(pendingEvent);\n log.set(\"queueIndex\", pendingEvent.queueIndex);\n log.set(\"pendingEvents\", this._pendingEvents.length);\n if (!this._isSending && !this._offline) {\n this._sendLoop(log);\n }\n if (this._sendLoopLogItem) {\n log.refDetached(this._sendLoopLogItem);\n }\n return pendingEvent;\n }\n\n async enqueueRedaction(eventIdOrTxnId, reason, log) {\n const isAlreadyRedacting = this._pendingEvents.array.some(pe => {\n return pe.eventType === REDACTION_TYPE &&\n (pe.relatedTxnId === eventIdOrTxnId || pe.relatedEventId === eventIdOrTxnId);\n });\n if (isAlreadyRedacting) {\n log.set(\"already_redacting\", true);\n return;\n }\n let relatedTxnId;\n let relatedEventId;\n if (isTxnId(eventIdOrTxnId)) {\n relatedTxnId = eventIdOrTxnId;\n const txnId = eventIdOrTxnId;\n const pe = this._pendingEvents.array.find(pe => pe.txnId === txnId);\n if (pe && !pe.remoteId && pe.status !== SendStatus.Sending) {\n // haven't started sending this event yet,\n // just remove it from the queue\n log.set(\"remove\", relatedTxnId);\n await pe.abort();\n return;\n } else if (pe) {\n relatedEventId = pe.remoteId;\n } else {\n // we don't have the pending event anymore,\n // the remote echo must have arrived in the meantime.\n // we could look for it in the timeline, but for now\n // we don't do anything as this race is quite unlikely\n // and a bit complicated to fix.\n return;\n }\n } else {\n relatedEventId = eventIdOrTxnId;\n const pe = this._pendingEvents.array.find(pe => pe.remoteId === relatedEventId);\n if (pe) {\n // also set the txn id just in case that an event id was passed\n // for relating to a pending event that is still waiting for the remote echo\n relatedTxnId = pe.txnId;\n }\n }\n log.set(\"relatedTxnId\", relatedTxnId);\n log.set(\"relatedEventId\", relatedEventId);\n await this._enqueueEvent(REDACTION_TYPE, {reason}, null, relatedTxnId, relatedEventId, log);\n }\n\n get pendingEvents() {\n return this._pendingEvents;\n }\n\n async _tryUpdateEvent(pendingEvent) {\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);\n try {\n this._tryUpdateEventWithTxn(pendingEvent, txn);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n }\n\n async _tryUpdateEventWithTxn(pendingEvent, txn) {\n // pendingEvent might have been removed already here\n // by a racing remote echo, so check first so we don't recreate it\n if (await txn.pendingEvents.exists(pendingEvent.roomId, pendingEvent.queueIndex)) {\n txn.pendingEvents.update(pendingEvent.data);\n }\n }\n\n async _createAndStoreEvent(eventType, content, relatedTxnId, relatedEventId, attachments) {\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);\n let pendingEvent;\n try {\n const pendingEventsStore = txn.pendingEvents;\n const maxStorageQueueIndex = await pendingEventsStore.getMaxQueueIndex(this._roomId) || 0;\n // don't use the queueIndex of the pendingEvent currently waiting for /send to return\n // if the remote echo already removed the pendingEvent in storage, as the send loop\n // wouldn't be able to detect the remote echo already arrived and end up overwriting the new event\n const maxQueueIndex = Math.max(maxStorageQueueIndex, this._currentQueueIndex);\n const queueIndex = maxQueueIndex + 1;\n const needsEncryption = eventType !== REDACTION_TYPE &&\n eventType !== REACTION_TYPE &&\n !!this._roomEncryption;\n pendingEvent = this._createPendingEvent({\n roomId: this._roomId,\n queueIndex,\n eventType,\n content,\n relatedTxnId,\n relatedEventId,\n txnId: makeTxnId(),\n needsEncryption,\n needsUpload: !!attachments\n }, attachments);\n pendingEventsStore.add(pendingEvent.data);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n return pendingEvent;\n }\n\n dispose() {\n for (const pe of this._pendingEvents) {\n pe.dispose();\n }\n }\n}\n\nimport {HomeServer as MockHomeServer} from \"../../../mocks/HomeServer.js\";\nimport {createMockStorage} from \"../../../mocks/Storage\";\nimport {ListObserver} from \"../../../mocks/ListObserver.js\";\nimport {NullLogger, NullLogItem} from \"../../../logging/NullLogger\";\nimport {createEvent, withTextBody, withTxnId} from \"../../../mocks/event.js\";\nimport {poll} from \"../../../mocks/poll.js\";\nimport {createAnnotation} from \"../timeline/relations.js\";\n\nexport function tests() {\n const logger = new NullLogger();\n return {\n \"enqueue second message when remote echo of first arrives before /send returns\": async assert => {\n const storage = await createMockStorage();\n const hs = new MockHomeServer();\n // 1. enqueue and start send event 1\n const queue = new SendQueue({roomId: \"!abc\", storage, hsApi: hs.api});\n const event1 = withTextBody(\"message 1\", createEvent(\"m.room.message\", \"$123\"));\n await logger.run(\"event1\", log => queue.enqueueEvent(event1.type, event1.content, null, log));\n assert.equal(queue.pendingEvents.length, 1);\n const sendRequest1 = hs.requests.send[0];\n // 2. receive remote echo, before /send has returned\n const remoteEcho = withTxnId(sendRequest1.arguments[2], event1);\n const txn = await storage.readWriteTxn([storage.storeNames.pendingEvents]);\n const removal = await logger.run(\"remote echo\", log => queue.removeRemoteEchos([remoteEcho], txn, log));\n await txn.complete();\n assert.equal(removal.length, 1);\n queue.emitRemovals(removal);\n assert.equal(queue.pendingEvents.length, 0);\n // 3. now enqueue event 2\n const event2 = withTextBody(\"message 2\", createEvent(\"m.room.message\", \"$456\"));\n await logger.run(\"event2\", log => queue.enqueueEvent(event2.type, event2.content, null, log));\n // even though the first pending event has been removed by the remote echo,\n // the second should get the next index, as the send loop is still blocking on the first one\n assert.equal(Array.from(queue.pendingEvents)[0].queueIndex, 2);\n // 4. send for event 1 comes back\n sendRequest1.respond({event_id: event1.event_id});\n // 5. now expect second send request for event 2\n const sendRequest2 = await poll(() => hs.requests.send[1]);\n sendRequest2.respond({event_id: event2.event_id});\n await poll(() => !queue._isSending);\n },\n \"redaction of pending event that hasn't started sending yet aborts it\": async assert => {\n const queue = new SendQueue({\n roomId: \"!abc\",\n storage: await createMockStorage(),\n hsApi: new MockHomeServer().api\n });\n // first, enqueue a message that will be attempted to send, but we don't respond\n await queue.enqueueEvent(\"m.room.message\", {body: \"hello!\"}, null, new NullLogItem());\n\n const observer = new ListObserver();\n queue.pendingEvents.subscribe(observer);\n await queue.enqueueEvent(\"m.room.message\", {body: \"...world\"}, null, new NullLogItem());\n let txnId;\n {\n const {type, index, value} = await observer.next();\n assert.equal(type, \"add\");\n assert.equal(index, 1);\n assert.equal(typeof value.txnId, \"string\");\n txnId = value.txnId;\n }\n await queue.enqueueRedaction(txnId, null, new NullLogItem());\n {\n const {type, value, index} = await observer.next();\n assert.equal(type, \"remove\");\n assert.equal(index, 1);\n assert.equal(txnId, value.txnId);\n }\n },\n \"duplicate redaction gets dropped\": async assert => {\n const queue = new SendQueue({\n roomId: \"!abc\",\n storage: await createMockStorage(),\n hsApi: new MockHomeServer().api\n });\n assert.equal(queue.pendingEvents.length, 0);\n await queue.enqueueRedaction(\"!event\", null, new NullLogItem());\n assert.equal(queue.pendingEvents.length, 1);\n await queue.enqueueRedaction(\"!event\", null, new NullLogItem());\n assert.equal(queue.pendingEvents.length, 1);\n },\n \"duplicate reaction gets dropped\": async assert => {\n const queue = new SendQueue({\n roomId: \"!abc\",\n storage: await createMockStorage(),\n hsApi: new MockHomeServer().api\n });\n assert.equal(queue.pendingEvents.length, 0);\n await queue.enqueueEvent(\"m.reaction\", createAnnotation(\"!target\", \"🚀\"), null, new NullLogItem());\n assert.equal(queue.pendingEvents.length, 1);\n await queue.enqueueEvent(\"m.reaction\", createAnnotation(\"!target\", \"👋\"), null, new NullLogItem());\n assert.equal(queue.pendingEvents.length, 2);\n await queue.enqueueEvent(\"m.reaction\", createAnnotation(\"!target\", \"🚀\"), null, new NullLogItem());\n assert.equal(queue.pendingEvents.length, 2);\n },\n \n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {encryptAttachment} from \"../e2ee/attachment.js\";\n\nexport class AttachmentUpload {\n constructor({filename, blob, platform}) {\n this._filename = filename;\n // need to keep around for local preview while uploading\n this._unencryptedBlob = blob;\n this._transferredBlob = this._unencryptedBlob;\n this._platform = platform;\n this._mxcUrl = null;\n this._encryptionInfo = null;\n this._uploadRequest = null;\n this._aborted = false;\n this._error = null;\n this._sentBytes = 0;\n }\n\n /** important to call after encrypt() if encryption is needed */\n get size() {\n return this._transferredBlob.size;\n }\n\n get sentBytes() {\n return this._sentBytes;\n }\n\n abort() {\n this._uploadRequest?.abort();\n }\n\n get localPreview() {\n return this._unencryptedBlob;\n }\n\n /** @internal */\n async encrypt() {\n if (this._encryptionInfo) {\n throw new Error(\"already encrypted\");\n }\n const {info, blob} = await encryptAttachment(this._platform, this._transferredBlob);\n this._transferredBlob = blob;\n this._encryptionInfo = info;\n }\n\n /** @internal */\n async upload(hsApi, progressCallback, log) {\n this._uploadRequest = hsApi.uploadAttachment(this._transferredBlob, this._filename, {\n uploadProgress: sentBytes => {\n this._sentBytes = sentBytes;\n progressCallback();\n },\n log\n });\n const {content_uri} = await this._uploadRequest.response();\n this._mxcUrl = content_uri;\n }\n\n /** @internal */\n applyToContent(urlPath, content) {\n if (!this._mxcUrl) {\n throw new Error(\"upload has not finished\");\n }\n let prefix = urlPath.substr(0, urlPath.lastIndexOf(\"url\"));\n setPath(`${prefix}info.size`, content, this._transferredBlob.size);\n setPath(`${prefix}info.mimetype`, content, this._unencryptedBlob.mimeType);\n if (this._encryptionInfo) {\n setPath(`${prefix}file`, content, Object.assign(this._encryptionInfo, {\n mimetype: this._unencryptedBlob.mimeType,\n url: this._mxcUrl\n }));\n } else {\n setPath(`${prefix}url`, content, this._mxcUrl);\n }\n }\n\n dispose() {\n this._unencryptedBlob.dispose();\n this._transferredBlob.dispose();\n }\n}\n\nfunction setPath(path, content, value) {\n const parts = path.split(\".\");\n let obj = content;\n for (let i = 0; i < (parts.length - 1); i += 1) {\n const key = parts[i];\n if (!obj[key]) {\n obj[key] = {};\n }\n obj = obj[key];\n }\n const propKey = parts[parts.length - 1];\n obj[propKey] = value;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseRoom} from \"./BaseRoom.js\";\nimport {SyncWriter} from \"./timeline/persistence/SyncWriter.js\";\nimport {MemberWriter} from \"./timeline/persistence/MemberWriter.js\";\nimport {RelationWriter} from \"./timeline/persistence/RelationWriter.js\";\nimport {SendQueue} from \"./sending/SendQueue.js\";\nimport {WrappedError} from \"../error.js\"\nimport {Heroes} from \"./members/Heroes.js\";\nimport {AttachmentUpload} from \"./AttachmentUpload.js\";\nimport {DecryptionSource} from \"../e2ee/common\";\nimport {iterateResponseStateEvents} from \"./common\";\nimport {PowerLevels, EVENT_TYPE as POWERLEVELS_EVENT_TYPE } from \"./PowerLevels.js\";\n\nconst EVENT_ENCRYPTED_TYPE = \"m.room.encrypted\";\n\nexport class Room extends BaseRoom {\n constructor(options) {\n super(options);\n this._roomStateHandler = options.roomStateHandler;\n // TODO: pass pendingEvents to start like pendingOperations?\n const {pendingEvents} = options;\n const relationWriter = new RelationWriter({\n roomId: this.id,\n fragmentIdComparer: this._fragmentIdComparer,\n ownUserId: this._user.id\n });\n this._syncWriter = new SyncWriter({\n roomId: this.id,\n fragmentIdComparer: this._fragmentIdComparer,\n relationWriter,\n memberWriter: new MemberWriter(this.id)\n });\n this._sendQueue = new SendQueue({roomId: this.id, storage: this._storage, hsApi: this._hsApi, pendingEvents});\n }\n\n _setEncryption(roomEncryption) {\n if (super._setEncryption(roomEncryption)) {\n this._sendQueue.enableEncryption(this._roomEncryption);\n return true;\n }\n return false;\n }\n\n async prepareSync(roomResponse, membership, newKeys, txn, log) {\n log.set(\"id\", this.id);\n if (newKeys) {\n log.set(\"newKeys\", newKeys.length);\n }\n let summaryChanges = this._summary.data.applySyncResponse(roomResponse, membership, this._user.id);\n let roomEncryption = this._roomEncryption;\n // encryption is enabled in this sync\n if (!roomEncryption && summaryChanges.encryption) {\n log.set(\"enableEncryption\", true);\n roomEncryption = this._createRoomEncryption(this, summaryChanges.encryption);\n }\n\n let retryEntries;\n let decryptPreparation;\n if (roomEncryption) {\n let eventsToDecrypt = roomResponse?.timeline?.events || [];\n // when new keys arrive, also see if any older events can now be retried to decrypt\n if (newKeys) {\n // TODO: if a key is considered by roomEncryption.prepareDecryptAll to use for decryption,\n // key.eventIds will be set. We could somehow try to reuse that work, but retrying also needs\n // to happen if a key is not needed to decrypt this sync or there are indeed no encrypted messages\n // in this sync at all.\n retryEntries = await this._getSyncRetryDecryptEntries(newKeys, roomEncryption, txn);\n if (retryEntries.length) {\n log.set(\"retry\", retryEntries.length);\n eventsToDecrypt = eventsToDecrypt.concat(retryEntries.map(entry => entry.event));\n }\n }\n eventsToDecrypt = eventsToDecrypt.filter(event => {\n return event?.type === EVENT_ENCRYPTED_TYPE;\n });\n if (eventsToDecrypt.length) {\n decryptPreparation = await roomEncryption.prepareDecryptAll(\n eventsToDecrypt, newKeys, DecryptionSource.Sync, txn);\n }\n }\n\n return {\n roomEncryption,\n summaryChanges,\n decryptPreparation,\n decryptChanges: null,\n retryEntries\n };\n }\n\n async afterPrepareSync(preparation, parentLog) {\n if (preparation.decryptPreparation) {\n await parentLog.wrap(\"decrypt\", async log => {\n log.set(\"id\", this.id);\n preparation.decryptChanges = await preparation.decryptPreparation.decrypt();\n preparation.decryptPreparation = null;\n }, parentLog.level.Detail);\n }\n }\n\n /** @package */\n async writeSync(roomResponse, isInitialSync, {summaryChanges, decryptChanges, roomEncryption, retryEntries}, txn, log) {\n log.set(\"id\", this.id);\n const isRejoin = summaryChanges.isNewJoin(this._summary.data);\n if (isRejoin) {\n // remove all room state before calling syncWriter,\n // so no old state sticks around\n txn.roomState.removeAllForRoom(this.id);\n txn.roomMembers.removeAllForRoom(this.id);\n }\n const {entries: newEntries, updatedEntries, newLiveKey, memberChanges, memberSync} =\n await log.wrap(\"syncWriter\", log => this._syncWriter.writeSync(\n roomResponse, isRejoin, summaryChanges.hasFetchedMembers, txn, log), log.level.Detail);\n let decryption;\n if (decryptChanges) {\n decryption = await log.wrap(\"decryptChanges\", log => decryptChanges.write(txn, log));\n log.set(\"decryptionResults\", decryption.results.size);\n log.set(\"decryptionErrors\", decryption.errors.size);\n if (this._isTimelineOpen) {\n await decryption.verifyKnownSenders(txn);\n }\n decryption.applyToEntries(newEntries);\n if (retryEntries?.length) {\n decryption.applyToEntries(retryEntries);\n updatedEntries.push(...retryEntries);\n }\n }\n log.set(\"newEntries\", newEntries.length);\n log.set(\"updatedEntries\", updatedEntries.length);\n let encryptionChanges;\n // pass member changes to device tracker\n if (roomEncryption) {\n encryptionChanges = await roomEncryption.writeSync(roomResponse, memberChanges, txn, log);\n log.set(\"shouldFlushKeyShares\", encryptionChanges.shouldFlush);\n }\n const allEntries = newEntries.concat(updatedEntries);\n // also apply (decrypted) timeline entries to the summary changes\n summaryChanges = summaryChanges.applyTimelineEntries(\n allEntries, isInitialSync, !this._isTimelineOpen, this._user.id);\n \n // if we've have left the room, remove the summary\n if (summaryChanges.membership !== \"join\") {\n txn.roomSummary.remove(this.id);\n } else {\n // write summary changes, and unset if nothing was actually changed\n summaryChanges = this._summary.writeData(summaryChanges, txn);\n }\n if (summaryChanges) {\n log.set(\"summaryChanges\", summaryChanges.changedKeys(this._summary.data));\n }\n // fetch new members while we have txn open,\n // but don't make any in-memory changes yet\n let heroChanges;\n // if any hero changes their display name, the summary in the room response\n // is also updated, which will trigger a RoomSummary update\n // and make summaryChanges non-falsy here\n if (summaryChanges?.needsHeroes) {\n // room name disappeared, open heroes\n if (!this._heroes) {\n this._heroes = new Heroes(this._roomId);\n }\n heroChanges = await this._heroes.calculateChanges(summaryChanges.heroes, memberChanges, txn);\n }\n let removedPendingEvents;\n if (Array.isArray(roomResponse.timeline?.events)) {\n removedPendingEvents = await this._sendQueue.removeRemoteEchos(roomResponse.timeline.events, txn, log);\n }\n const powerLevelsEvent = this._getPowerLevelsEvent(roomResponse);\n await this._runRoomStateHandlers(roomResponse, memberSync, txn, log);\n return {\n roomResponse,\n summaryChanges,\n roomEncryption,\n newEntries,\n updatedEntries,\n newLiveKey,\n removedPendingEvents,\n memberChanges,\n heroChanges,\n powerLevelsEvent,\n encryptionChanges,\n decryption\n };\n }\n\n /**\n * @package\n * Called with the changes returned from `writeSync` to apply them and emit changes.\n * No storage or network operations should be done here.\n */\n afterSync(changes, log) {\n const {\n summaryChanges, newEntries, updatedEntries, newLiveKey,\n removedPendingEvents, memberChanges, powerLevelsEvent,\n heroChanges, roomEncryption, roomResponse, encryptionChanges\n } = changes;\n log.set(\"id\", this.id);\n this._syncWriter.afterSync(newLiveKey);\n this._setEncryption(roomEncryption);\n if (this._roomEncryption) {\n this._roomEncryption.afterSync(encryptionChanges);\n }\n if (memberChanges.size) {\n if (this._changedMembersDuringSync) {\n for (const [userId, memberChange] of memberChanges.entries()) {\n this._changedMembersDuringSync.set(userId, memberChange.member);\n }\n }\n if (this._memberList) {\n this._memberList.afterSync(memberChanges);\n }\n this._roomStateHandler.updateRoomMembers(this, memberChanges);\n if (this._observedMembers) {\n this._updateObservedMembers(memberChanges);\n }\n if (this._timeline) {\n for (const [userId, memberChange] of memberChanges.entries()) {\n if (userId === this._user.id) {\n this._timeline.updateOwnMember(memberChange.member);\n break;\n }\n }\n }\n }\n let emitChange = false;\n if (summaryChanges) {\n this._summary.applyChanges(summaryChanges);\n if (!this._summary.data.needsHeroes) {\n this._heroes = null;\n }\n emitChange = true;\n }\n if (this._heroes && heroChanges) {\n const oldName = this.name;\n this._heroes.applyChanges(heroChanges, this._summary.data, log);\n if (oldName !== this.name) {\n emitChange = true;\n }\n }\n if (powerLevelsEvent) {\n this._updatePowerLevels(powerLevelsEvent);\n }\n if (emitChange) {\n this._emitUpdate();\n }\n if (this._timeline) {\n // these should not be added if not already there\n this._timeline.replaceEntries(updatedEntries);\n this._timeline.addEntries(newEntries);\n }\n if (this._observedEvents) {\n this._observedEvents.updateEvents(updatedEntries);\n this._observedEvents.updateEvents(newEntries);\n }\n if (removedPendingEvents) {\n this._sendQueue.emitRemovals(removedPendingEvents);\n }\n this._emitSyncRoomState(roomResponse);\n }\n\n _updateObservedMembers(memberChanges) {\n for (const [userId, memberChange] of memberChanges) {\n const observableMember = this._observedMembers.get(userId);\n if (observableMember) {\n observableMember.set(memberChange.member);\n }\n }\n }\n\n _getPowerLevelsEvent(roomResponse) {\n let powerLevelEvent;\n iterateResponseStateEvents(roomResponse, event => {\n if(event.state_key === \"\" && event.type === POWERLEVELS_EVENT_TYPE) {\n powerLevelEvent = event;\n }\n\n });\n return powerLevelEvent;\n }\n\n _updatePowerLevels(powerLevelEvent) {\n if (this._powerLevels) {\n const newPowerLevels = new PowerLevels({\n powerLevelEvent,\n ownUserId: this._user.id,\n membership: this.membership,\n });\n this._powerLevels.set(newPowerLevels);\n }\n }\n\n /**\n * Only called if the result of writeSync had `needsAfterSyncCompleted` set.\n * Can be used to do longer running operations that resulted from the last sync,\n * like network operations.\n */\n async afterSyncCompleted({encryptionChanges, decryption, newEntries, updatedEntries}, log) {\n const shouldFlushKeys = encryptionChanges?.shouldFlush;\n const shouldFetchUnverifiedSenders = this._isTimelineOpen && decryption?.hasUnverifiedSenders;\n // only log rooms where we actually do something\n if (shouldFlushKeys || shouldFetchUnverifiedSenders) {\n await log.wrap({l: \"room\", id: this.id}, async log => {\n const promises = [];\n if (shouldFlushKeys) {\n promises.push(this._roomEncryption.flushPendingRoomKeyShares(this._hsApi, null, log));\n }\n if (shouldFetchUnverifiedSenders) {\n const promise = log.wrap(\"verify senders\", (async log => {\n const newlyVerifiedDecryption = await decryption.fetchAndVerifyRemainingSenders(this._hsApi, log);\n const verifiedEntries = [];\n const updateCallback = entry => verifiedEntries.push(entry);\n newlyVerifiedDecryption.applyToEntries(newEntries, updateCallback);\n newlyVerifiedDecryption.applyToEntries(updatedEntries, updateCallback);\n log.set(\"verifiedEntries\", verifiedEntries.length);\n this._timeline?.replaceEntries(verifiedEntries);\n this._observedEvents?.updateEvents(verifiedEntries);\n }));\n promises.push(promise);\n }\n await Promise.all(promises);\n });\n }\n }\n\n /** @package */\n start(pendingOperations, parentLog) {\n if (this._roomEncryption) {\n const roomKeyShares = pendingOperations?.get(\"share_room_key\");\n if (roomKeyShares) {\n // if we got interrupted last time sending keys to newly joined members\n parentLog.wrapDetached(\"flush room keys\", log => {\n log.set(\"id\", this.id);\n return this._roomEncryption.flushPendingRoomKeyShares(this._hsApi, roomKeyShares, log);\n });\n }\n }\n \n this._sendQueue.resumeSending(parentLog);\n }\n\n /** @package */\n async load(summary, txn, log) {\n try {\n await super.load(summary, txn, log);\n await this._syncWriter.load(txn, log);\n } catch (err) {\n throw new WrappedError(`Could not load room ${this._roomId}`, err);\n }\n }\n\n async _writeGapFill(gapChunk, txn, log) {\n const removedPendingEvents = await this._sendQueue.removeRemoteEchos(gapChunk, txn, log);\n return removedPendingEvents;\n }\n\n _applyGapFill(removedPendingEvents) {\n this._sendQueue.emitRemovals(removedPendingEvents);\n }\n\n /** @public */\n sendEvent(eventType, content, attachments, log = null) {\n return this._platform.logger.wrapOrRun(log, \"send\", log => {\n log.set(\"id\", this.id);\n return this._sendQueue.enqueueEvent(eventType, content, attachments, log);\n });\n }\n\n /** @public */\n sendRedaction(eventIdOrTxnId, reason, log = null) {\n return this._platform.logger.wrapOrRun(log, \"redact\", log => {\n log.set(\"id\", this.id);\n return this._sendQueue.enqueueRedaction(eventIdOrTxnId, reason, log);\n });\n }\n\n /** @public */\n async ensureMessageKeyIsShared(log = null) {\n if (!this._roomEncryption) {\n return;\n }\n return this._platform.logger.wrapOrRun(log, \"ensureMessageKeyIsShared\", log => {\n log.set(\"id\", this.id);\n return this._roomEncryption.ensureMessageKeyIsShared(this._hsApi, log);\n });\n }\n\n get avatarColorId() {\n return this._heroes?.roomAvatarColorId || this._roomId;\n }\n\n get isUnread() {\n return this._summary.data.isUnread;\n }\n\n get notificationCount() {\n return this._summary.data.notificationCount;\n }\n \n get highlightCount() {\n return this._summary.data.highlightCount;\n }\n\n get isTrackingMembers() {\n return this._summary.data.isTrackingMembers;\n }\n\n async _getLastEventId() {\n const lastKey = this._syncWriter.lastMessageKey;\n if (lastKey) {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.timelineEvents,\n ]);\n const eventEntry = await txn.timelineEvents.get(this._roomId, lastKey);\n return eventEntry?.event?.event_id;\n }\n }\n\n /**\n * Clear the unreaad count in the room, and optionally send a read receipt\n * @param {*} log Logger\n * @param {boolean} sendReceipt Should a receipt be sent.\n * @returns \n */\n async clearUnread(log = null, sendReceipt = true) {\n if (this.isUnread || this.notificationCount) {\n return await this._platform.logger.wrapOrRun(log, \"clearUnread\", async log => {\n log.set(\"id\", this.id);\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.roomSummary,\n ]);\n let data;\n try {\n data = this._summary.writeClearUnread(txn);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n this._summary.applyChanges(data);\n this._emitUpdate();\n \n try {\n const lastEventId = sendReceipt && await this._getLastEventId();\n if (lastEventId) {\n await this._hsApi.receipt(this._roomId, \"m.read\", lastEventId);\n }\n } catch (err) {\n // ignore ConnectionError\n if (err.name !== \"ConnectionError\") {\n throw err;\n }\n }\n });\n }\n }\n\n leave(log = null) {\n return this._platform.logger.wrapOrRun(log, \"leave room\", async log => {\n log.set(\"id\", this.id);\n await this._hsApi.leave(this.id, {log}).response();\n });\n }\n\n async inviteUser(userId, reason) {\n if (!userId) {\n throw new Error(\"userId is null/undefined\");\n }\n await this._hsApi.invite(this.id, userId, reason).response();\n }\n\n /* called by BaseRoom to pass pendingEvents when opening the timeline */\n _getPendingEvents() {\n return this._sendQueue.pendingEvents;\n }\n\n /** global room state handlers, run during writeSync step */\n _runRoomStateHandlers(roomResponse, memberSync, txn, log) {\n const promises = [];\n iterateResponseStateEvents(roomResponse, event => {\n promises.push(this._roomStateHandler.handleRoomState(this, event, memberSync, txn, log));\n });\n return Promise.all(promises);\n }\n\n /** local room state observers, run during afterSync step */\n _emitSyncRoomState(roomResponse) {\n iterateResponseStateEvents(roomResponse, event => {\n for (const handler of this._roomStateObservers) {\n handler.handleStateEvent(event);\n }\n });\n }\n\n /** @package */\n writeIsTrackingMembers(value, txn) {\n return this._summary.writeIsTrackingMembers(value, txn);\n }\n\n /** @package */\n applyIsTrackingMembersChanges(changes) {\n this._summary.applyChanges(changes);\n }\n\n createAttachment(blob, filename) {\n return new AttachmentUpload({blob, filename, platform: this._platform});\n }\n\n dispose() {\n super.dispose();\n this._sendQueue.dispose();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {iterateResponseStateEvents} from \"./common\";\nimport {BaseRoom} from \"./BaseRoom.js\";\nimport {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from \"./members/RoomMember.js\";\n\nexport class ArchivedRoom extends BaseRoom {\n constructor(options) {\n super(options);\n // archived rooms are reference counted,\n // as they are not kept in memory when not needed\n this._releaseCallback = options.releaseCallback;\n this._forgetCallback = options.forgetCallback;\n this._retentionCount = 1;\n /**\n Some details from our own member event when being kicked or banned.\n We can't get this from the member store, because we don't store the reason field there.\n */\n this._kickDetails = null;\n this._kickedBy = null;\n }\n\n retain() {\n this._retentionCount += 1;\n }\n\n release() {\n this._retentionCount -= 1;\n if (this._retentionCount === 0) {\n this._releaseCallback();\n }\n }\n\n async _getKickAuthor(sender, txn) {\n const senderMember = await txn.roomMembers.get(this.id, sender);\n if (senderMember) {\n return new RoomMember(senderMember);\n } else {\n return RoomMember.fromUserId(this.id, sender, \"join\");\n }\n }\n \n async load(archivedRoomSummary, txn, log) {\n const {summary, kickDetails} = archivedRoomSummary;\n this._kickDetails = kickDetails;\n if (this._kickDetails) {\n this._kickedBy = await this._getKickAuthor(this._kickDetails.sender, txn);\n }\n return super.load(summary, txn, log);\n }\n\n /** @package */\n async writeSync(joinedSummaryData, roomResponse, membership, txn, log) {\n log.set(\"id\", this.id);\n if (membership === \"leave\") {\n const newKickDetails = findKickDetails(roomResponse, this._user.id);\n if (newKickDetails || joinedSummaryData) {\n const kickDetails = newKickDetails || this._kickDetails;\n let kickedBy;\n if (newKickDetails) {\n kickedBy = await this._getKickAuthor(newKickDetails.sender, txn);\n }\n const summaryData = joinedSummaryData || this._summary.data;\n txn.archivedRoomSummary.set({\n summary: summaryData.serialize(),\n kickDetails,\n });\n return {kickDetails, kickedBy, summaryData};\n }\n } else if (membership === \"join\") {\n txn.archivedRoomSummary.remove(this.id);\n }\n // always return object\n return {};\n }\n\n /**\n * @package\n * Called with the changes returned from `writeSync` to apply them and emit changes.\n * No storage or network operations should be done here.\n */\n afterSync({summaryData, kickDetails, kickedBy}, log) {\n log.set(\"id\", this.id);\n if (summaryData) {\n this._summary.applyChanges(summaryData);\n }\n if (kickDetails) {\n this._kickDetails = kickDetails;\n }\n if (kickedBy) {\n this._kickedBy = kickedBy;\n }\n this._emitUpdate();\n }\n\n get isKicked() {\n return this._kickDetails?.membership === \"leave\";\n }\n\n get isBanned() {\n return this._kickDetails?.membership === \"ban\";\n }\n\n get kickedBy() {\n return this._kickedBy;\n }\n\n get kickReason() {\n return this._kickDetails?.reason;\n }\n\n isArchived() {\n return true;\n }\n\n forget(log = null) {\n return this._platform.logger.wrapOrRun(log, \"forget room\", async log => {\n log.set(\"id\", this.id);\n await this._hsApi.forget(this.id, {log}).response();\n const storeNames = this._storage.storeNames;\n const txn = await this._storage.readWriteTxn([\n storeNames.roomState,\n storeNames.archivedRoomSummary,\n storeNames.roomMembers,\n storeNames.timelineEvents,\n storeNames.timelineFragments,\n storeNames.timelineRelations,\n storeNames.pendingEvents,\n storeNames.inboundGroupSessions,\n storeNames.groupSessionDecryptions,\n storeNames.operations,\n ]);\n\n txn.roomState.removeAllForRoom(this.id);\n txn.archivedRoomSummary.remove(this.id);\n txn.roomMembers.removeAllForRoom(this.id);\n txn.timelineEvents.removeAllForRoom(this.id);\n txn.timelineFragments.removeAllForRoom(this.id);\n txn.timelineRelations.removeAllForRoom(this.id);\n txn.pendingEvents.removeAllForRoom(this.id);\n txn.inboundGroupSessions.removeAllForRoom(this.id);\n txn.groupSessionDecryptions.removeAllForRoom(this.id);\n await txn.operations.removeAllForScope(this.id);\n\n await txn.complete();\n\n this._retentionCount = 0;\n this._releaseCallback();\n \n this._forgetCallback(this.id);\n });\n }\n\n join(log = null) {\n return this._platform.logger.wrapOrRun(log, \"rejoin archived room\", async log => {\n await this._hsApi.join(this.id, {log}).response();\n });\n }\n}\n\nfunction findKickDetails(roomResponse, ownUserId) {\n let kickEvent;\n iterateResponseStateEvents(roomResponse, event => {\n if (event.type === MEMBER_EVENT_TYPE) {\n // did we get kicked?\n if (event.state_key === ownUserId && event.sender !== event.state_key) {\n kickEvent = event;\n }\n }\n });\n if (kickEvent) {\n return {\n // this is different from the room membership in the sync section, which can only be leave\n membership: kickEvent.content?.membership, // could be leave or ban\n reason: kickEvent.content?.reason,\n sender: kickEvent.sender,\n };\n }\n}\n\nexport function tests() {\n function createMemberEvent(sender, target, membership, reason) {\n return {\n sender,\n state_key: target,\n type: \"m.room.member\",\n content: { reason, membership }\n };\n }\n const bob = \"@bob:hs.tld\";\n const alice = \"@alice:hs.tld\";\n\n return {\n \"ban/kick sets kickDetails from state event\": assert => {\n const reason = \"Bye!\";\n const leaveEvent = createMemberEvent(alice, bob, \"ban\", reason);\n const kickDetails = findKickDetails({state: {events: [leaveEvent]}}, bob);\n assert.equal(kickDetails.membership, \"ban\");\n assert.equal(kickDetails.reason, reason);\n assert.equal(kickDetails.sender, alice);\n },\n \"ban/kick sets kickDetails from timeline state event, taking precedence over state\": assert => {\n const reason = \"Bye!\";\n const inviteEvent = createMemberEvent(alice, bob, \"invite\");\n const leaveEvent = createMemberEvent(alice, bob, \"ban\", reason);\n const kickDetails = findKickDetails({\n state: { events: [inviteEvent] },\n timeline: {events: [leaveEvent] }\n }, bob);\n assert.equal(kickDetails.membership, \"ban\");\n assert.equal(kickDetails.reason, reason);\n assert.equal(kickDetails.sender, alice);\n },\n \"leaving without being kicked doesn't produce kickDetails\": assert => {\n const leaveEvent = createMemberEvent(bob, bob, \"leave\");\n const kickDetails = findKickDetails({state: {events: [leaveEvent]}}, bob);\n assert.equal(kickDetails, null);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {HomeServerApi} from \"./net/HomeServerApi\";\nimport type {ILogItem} from \"../logging/types\";\n\nexport async function loadProfiles(userIds: string[], hsApi: HomeServerApi, log: ILogItem): Promise {\n const profiles = await Promise.all(userIds.map(async userId => {\n const response = await hsApi.profile(userId, {log}).response();\n return new Profile(userId, response.displayname as string, response.avatar_url as string);\n }));\n profiles.sort((a, b) => a.name.localeCompare(b.name));\n return profiles;\n}\n\nexport interface IProfile {\n get userId(): string;\n get displayName(): string | undefined;\n get avatarUrl(): string | undefined;\n get name(): string;\n}\n\nexport class Profile implements IProfile {\n constructor(\n public readonly userId: string,\n public readonly displayName: string,\n public readonly avatarUrl: string | undefined\n ) {}\n\n get name() { return this.displayName || this.userId; }\n}\n\nexport class UserIdProfile implements IProfile {\n constructor(public readonly userId: string) {}\n get displayName() { return undefined; }\n get name() { return this.userId; }\n get avatarUrl() { return undefined; }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {calculateRoomName} from \"./members/Heroes\";\nimport {createRoomEncryptionEvent} from \"../e2ee/common\";\nimport {MediaRepository} from \"../net/MediaRepository\";\nimport {EventEmitter} from \"../../utils/EventEmitter\";\nimport {AttachmentUpload} from \"./AttachmentUpload\";\nimport {loadProfiles, Profile, UserIdProfile} from \"../profile\";\nimport {RoomType, UnsentStateEvent} from \"./common\";\n\nimport type {HomeServerApi} from \"../net/HomeServerApi\";\nimport type {ILogItem} from \"../../logging/types\";\nimport type {Platform} from \"../../platform/web/Platform\";\nimport type {IBlobHandle} from \"../../platform/types/types\";\nimport type {User} from \"../User\";\nimport type {Storage} from \"../storage/idb/Storage\";\n\ntype CreateRoomPayload = {\n is_direct?: boolean;\n preset?: string;\n name?: string;\n topic?: string;\n invite?: string[];\n room_alias_name?: string;\n creation_content?: {\"m.federate\": boolean};\n initial_state: UnsentStateEvent[];\n power_level_content_override?: Record;\n}\n\ntype ImageInfo = {\n w: number;\n h: number;\n mimetype: string;\n size: number;\n}\n\ntype Avatar = {\n info: ImageInfo;\n blob: IBlobHandle;\n name: string;\n}\n\ntype Options = {\n type: RoomType;\n isEncrypted?: boolean;\n isFederationDisabled?: boolean;\n name?: string;\n topic?: string;\n invites?: string[];\n avatar?: Avatar;\n alias?: string;\n powerLevelContentOverride?: Record;\n}\n\nfunction defaultE2EEStatusForType(type: RoomType): boolean {\n switch (type) {\n case RoomType.DirectMessage:\n case RoomType.Private:\n return true;\n case RoomType.Public:\n return false;\n }\n}\n\nfunction presetForType(type: RoomType): string {\n switch (type) {\n case RoomType.DirectMessage:\n return \"trusted_private_chat\";\n case RoomType.Private:\n return \"private_chat\";\n case RoomType.Public:\n return \"public_chat\";\n }\n}\n\nexport class RoomBeingCreated extends EventEmitter<{change: never}> {\n private _roomId?: string;\n private profiles: Profile[] = [];\n\n public readonly isEncrypted: boolean;\n private _calculatedName: string;\n private _error?: Error;\n private _isCancelled = false;\n\n constructor(\n public readonly id: string,\n private readonly options: Options,\n private readonly updateCallback: (self: RoomBeingCreated, params: string | undefined) => void,\n public readonly mediaRepository: MediaRepository,\n public readonly platform: Platform,\n log: ILogItem\n ) {\n super();\n this.isEncrypted = options.isEncrypted === undefined ? defaultE2EEStatusForType(options.type) : options.isEncrypted;\n if (options.name) {\n this._calculatedName = options.name;\n } else {\n const summaryData = {\n joinCount: 1, // ourselves\n inviteCount: (options.invites?.length || 0)\n };\n const userIdProfiles = (options.invites || []).map(userId => new UserIdProfile(userId));\n this._calculatedName = calculateRoomName(userIdProfiles, summaryData, log);\n }\n }\n\n /** @internal */\n async create(hsApi: HomeServerApi, log: ILogItem): Promise {\n try {\n let avatarEventContent;\n if (this.options.avatar) {\n const {avatar} = this.options;\n const attachment = new AttachmentUpload({filename: avatar.name, blob: avatar.blob, platform: this.platform});\n await attachment.upload(hsApi, () => {}, log);\n avatarEventContent = {\n info: avatar.info\n };\n attachment.applyToContent(\"url\", avatarEventContent);\n }\n const createOptions: CreateRoomPayload = {\n is_direct: this.options.type === RoomType.DirectMessage,\n preset: presetForType(this.options.type),\n initial_state: []\n };\n if (this.options.name) {\n createOptions.name = this.options.name;\n }\n if (this.options.topic) {\n createOptions.topic = this.options.topic;\n }\n if (this.options.invites) {\n createOptions.invite = this.options.invites;\n }\n if (this.options.alias) {\n createOptions.room_alias_name = this.options.alias;\n }\n if (this.options.isFederationDisabled === true) {\n createOptions.creation_content = {\n \"m.federate\": false\n };\n }\n if (this.options.powerLevelContentOverride) {\n createOptions.power_level_content_override = this.options.powerLevelContentOverride;\n }\n if (this.isEncrypted) {\n createOptions.initial_state.push(createRoomEncryptionEvent());\n }\n if (avatarEventContent) {\n createOptions.initial_state.push({\n type: \"m.room.avatar\",\n state_key: \"\",\n content: avatarEventContent\n });\n }\n const response = await hsApi.createRoom(createOptions, {log}).response();\n this._roomId = response[\"room_id\"];\n } catch (err) {\n this._error = err;\n }\n this.emitChange();\n }\n\n /** requests the profiles of the invitees if needed to give an accurate\n * estimated room name in case an explicit room name is not set.\n * The room is being created in the background whether this is called\n * or not, and this just gives a more accurate name while that request\n * is running. */\n /** @internal */\n async loadProfiles(hsApi: HomeServerApi, log: ILogItem): Promise {\n try {\n // only load profiles if we need it for the room name and avatar\n if (!this.options.name && this.options.invites) {\n this.profiles = await loadProfiles(this.options.invites, hsApi, log);\n const summaryData = {\n joinCount: 1, // ourselves\n inviteCount: this.options.invites.length\n };\n this._calculatedName = calculateRoomName(this.profiles, summaryData, log);\n this.emitChange();\n }\n } catch (err) {} // swallow error, loading profiles is not essential\n }\n\n private emitChange(params?: string) {\n this.updateCallback(this, params);\n this.emit(\"change\");\n }\n\n get avatarColorId(): string { return this.options.invites?.[0] ?? this._roomId ?? this.id; }\n get avatarUrl(): string | undefined { return this.profiles?.[0]?.avatarUrl; }\n get avatarBlobUrl(): string | undefined { return this.options.avatar?.blob?.url; }\n get roomId(): string | undefined { return this._roomId; }\n get name() { return this._calculatedName; }\n get isBeingCreated(): boolean { return true; }\n get error(): Error | undefined { return this._error; }\n\n cancel() {\n if (!this._isCancelled) {\n this.dispose();\n this._isCancelled = true;\n this.emitChange(\"isCancelled\");\n }\n }\n // called from Session when updateCallback is invoked to remove it from the collection\n get isCancelled() { return this._isCancelled; }\n\n /** @internal */\n dispose() {\n if (this.options.avatar) {\n this.options.avatar.blob.dispose();\n }\n }\n\n async adjustDirectMessageMapIfNeeded(user: User, storage: Storage, hsApi: HomeServerApi, log: ILogItem): Promise {\n if (!this.options.invites || this.options.type !== RoomType.DirectMessage) {\n return;\n }\n const userId = this.options.invites[0];\n const DM_MAP_TYPE = \"m.direct\";\n await log.wrap(\"set \" + DM_MAP_TYPE, async log => {\n try {\n const txn = await storage.readWriteTxn([storage.storeNames.accountData]);\n let mapEntry;\n try {\n mapEntry = await txn.accountData.get(DM_MAP_TYPE);\n if (!mapEntry) {\n mapEntry = {type: DM_MAP_TYPE, content: {}};\n }\n const map = mapEntry.content;\n let userRooms = map[userId];\n if (!userRooms) {\n map[userId] = userRooms = [];\n }\n // this is a new room id so no need to check if it's already there\n userRooms.push(this._roomId);\n txn.accountData.set(mapEntry);\n await txn.complete();\n } catch (err) {\n txn.abort();\n throw err;\n }\n await hsApi.setAccountData(user.id, DM_MAP_TYPE, mapEntry.content, {log}).response();\n } catch (err) {\n // we can't really do anything else but logging here\n log.catch(err);\n }\n });\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventEmitter} from \"../../utils/EventEmitter\";\nimport {SummaryData, processStateEvent} from \"./RoomSummary.js\";\nimport {Heroes} from \"./members/Heroes.js\";\nimport {MemberChange, RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from \"./members/RoomMember.js\";\n\nexport class Invite extends EventEmitter {\n constructor({roomId, user, hsApi, mediaRepository, emitCollectionRemove, emitCollectionUpdate, platform}) {\n super();\n this._roomId = roomId;\n this._user = user;\n this._hsApi = hsApi;\n this._emitCollectionRemove = emitCollectionRemove;\n this._emitCollectionUpdate = emitCollectionUpdate;\n this._mediaRepository = mediaRepository;\n this._platform = platform;\n this._inviteData = null;\n this._accepting = false;\n this._rejecting = false;\n this._accepted = false;\n this._rejected = false;\n }\n\n get isInvite() {\n return true;\n }\n\n get id() {\n return this._roomId;\n }\n\n get name() {\n return this._inviteData.name || this._inviteData.canonicalAlias;\n }\n\n get isDirectMessage() {\n return this._inviteData.isDirectMessage;\n }\n\n get avatarUrl() {\n return this._inviteData.avatarUrl;\n }\n\n /** @see BaseRoom.avatarColorId */\n get avatarColorId() {\n return this._inviteData.avatarColorId || this.id;\n }\n\n get timestamp() {\n return this._inviteData.timestamp;\n }\n\n get isEncrypted() {\n return this._inviteData.isEncrypted;\n }\n\n get inviter() {\n return this._inviter;\n }\n\n isDirectMessageForUserId(userId) {\n return this.isDirectMessage && this._inviter.userId === userId;\n }\n\n get isPublic() {\n return this._inviteData.joinRule === \"public\";\n }\n\n get canonicalAlias() {\n return this._inviteData.canonicalAlias;\n }\n\n async accept(log = null) {\n await this._platform.logger.wrapOrRun(log, \"acceptInvite\", async log => {\n this._accepting = true;\n this._emitChange(\"accepting\");\n await this._hsApi.join(this._roomId, {log}).response();\n });\n }\n\n async reject(log = null) {\n await this._platform.logger.wrapOrRun(log, \"rejectInvite\", async log => {\n this._rejecting = true;\n this._emitChange(\"rejecting\");\n await this._hsApi.leave(this._roomId, {log}).response();\n });\n }\n\n get accepting() {\n return this._accepting;\n }\n\n get accepted() {\n return this._accepted;\n }\n\n get rejecting() {\n return this._rejecting;\n }\n\n get rejected() {\n return this._rejected;\n }\n\n get mediaRepository() {\n return this._mediaRepository;\n }\n\n _emitChange(params) {\n this.emit(\"change\");\n this._emitCollectionUpdate(this, params);\n }\n\n load(inviteData, log) {\n log.set(\"id\", this.id);\n this._inviteData = inviteData;\n this._inviter = inviteData.inviter ? new RoomMember(inviteData.inviter) : null;\n }\n\n async writeSync(membership, roomResponse, txn, log) {\n if (membership === \"invite\") {\n log.set(\"id\", this.id);\n log.set(\"add\", true);\n const inviteState = roomResponse[\"invite_state\"]?.events;\n if (!Array.isArray(inviteState)) {\n return null;\n }\n const summaryData = this._createSummaryData(inviteState);\n let heroes;\n if (!summaryData.name && !summaryData.canonicalAlias) {\n heroes = await this._createHeroes(inviteState, log);\n }\n const myInvite = this._getMyInvite(inviteState);\n if (!myInvite) {\n return null;\n }\n const inviter = this._getInviter(myInvite, inviteState);\n const inviteData = this._createData(inviteState, myInvite, inviter, summaryData, heroes);\n txn.invites.set(inviteData);\n return {inviteData, inviter};\n } else {\n log.set(\"id\", this.id);\n log.set(\"membership\", membership);\n txn.invites.remove(this.id);\n return {removed: true, membership};\n }\n }\n\n afterSync(changes, log) {\n log.set(\"id\", this.id);\n if (changes) {\n if (changes.removed) {\n this._accepting = false;\n this._rejecting = false;\n if (changes.membership === \"join\") {\n this._accepted = true;\n } else {\n this._rejected = true;\n }\n this.emit(\"change\");\n } else {\n // no emit change, adding to the collection is done by sync\n this._inviteData = changes.inviteData;\n this._inviter = changes.inviter;\n }\n }\n }\n\n _createData(inviteState, myInvite, inviter, summaryData, heroes) {\n const name = heroes ? heroes.roomName : summaryData.name;\n const avatarUrl = heroes ? heroes.roomAvatarUrl : summaryData.avatarUrl;\n const avatarColorId = heroes?.roomAvatarColorId || this.id;\n return {\n roomId: this.id,\n isEncrypted: !!summaryData.encryption,\n isDirectMessage: summaryData.isDirectMessage,\n// type: \n name,\n avatarUrl,\n avatarColorId,\n canonicalAlias: summaryData.canonicalAlias,\n timestamp: this._platform.clock.now(),\n joinRule: this._getJoinRule(inviteState),\n inviter: inviter?.serialize(),\n };\n }\n\n _createSummaryData(inviteState) {\n return inviteState.reduce((data, event) => processStateEvent(data, event, this._user.id), new SummaryData(null, this.id));\n }\n\n async _createHeroes(inviteState, log) {\n const members = inviteState.filter(e => e.type === MEMBER_EVENT_TYPE);\n const otherMembers = members.filter(e => e.state_key !== this._user.id);\n const memberChanges = otherMembers.reduce((map, e) => {\n const member = RoomMember.fromMemberEvent(this.id, e);\n map.set(member.userId, new MemberChange(member, null));\n return map;\n }, new Map());\n const otherUserIds = otherMembers.map(e => e.state_key);\n const heroes = new Heroes(this.id);\n const changes = await heroes.calculateChanges(otherUserIds, memberChanges, null);\n // we don't get an actual lazy-loading m.heroes summary on invites,\n // so just count the members by hand\n const countSummary = new SummaryData(null, this.id);\n countSummary.joinCount = members.reduce((sum, e) => sum + (e.content?.membership === \"join\" ? 1 : 0), 0);\n countSummary.inviteCount = members.reduce((sum, e) => sum + (e.content?.membership === \"invite\" ? 1 : 0), 0);\n heroes.applyChanges(changes, countSummary, log);\n return heroes;\n }\n\n _getMyInvite(inviteState) {\n return inviteState.find(e => e.type === MEMBER_EVENT_TYPE && e.state_key === this._user.id);\n }\n\n _getInviter(myInvite, inviteState) {\n const inviterMemberEvent = inviteState.find(e => e.type === MEMBER_EVENT_TYPE && e.state_key === myInvite.sender);\n if (inviterMemberEvent) {\n return RoomMember.fromMemberEvent(this.id, inviterMemberEvent);\n }\n }\n\n _getJoinRule(inviteState) {\n const event = inviteState.find(e => e.type === \"m.room.join_rules\");\n if (event) {\n return event.content?.join_rule;\n }\n return null;\n }\n}\n\nimport {NullLogItem} from \"../../logging/NullLogger\";\nimport {Clock as MockClock} from \"../../mocks/Clock.js\";\nimport {default as roomInviteFixture} from \"../../fixtures/matrix/invites/room.js\";\nimport {default as dmInviteFixture} from \"../../fixtures/matrix/invites/dm.js\";\n\nexport function tests() {\n\n function createStorage() {\n const invitesMap = new Map();\n return {\n invitesMap,\n invites: {\n set(invite) {\n invitesMap.set(invite.roomId, invite);\n },\n remove(roomId) {\n invitesMap.delete(roomId);\n }\n }\n }\n }\n\n const roomId = \"!123:hs.tld\";\n const aliceAvatarUrl = \"mxc://hs.tld/def456\";\n const roomAvatarUrl = \"mxc://hs.tld/roomavatar\";\n\n return {\n \"invite for room has correct fields\": async assert => {\n const invite = new Invite({\n roomId,\n platform: {clock: new MockClock(1001)},\n user: {id: \"@bob:hs.tld\"}\n });\n const txn = createStorage();\n const changes = await invite.writeSync(\"invite\", roomInviteFixture, txn, new NullLogItem());\n assert.equal(txn.invitesMap.get(roomId).roomId, roomId);\n invite.afterSync(changes, new NullLogItem());\n assert.equal(invite.name, \"Invite example\");\n assert.equal(invite.avatarUrl, roomAvatarUrl);\n assert.equal(invite.isPublic, false);\n assert.equal(invite.timestamp, 1001);\n assert.equal(invite.isEncrypted, false);\n assert.equal(invite.isDirectMessage, false);\n assert(invite.inviter);\n assert.equal(invite.inviter.userId, \"@alice:hs.tld\");\n assert.equal(invite.inviter.displayName, \"Alice\");\n assert.equal(invite.inviter.avatarUrl, aliceAvatarUrl);\n },\n \"invite for encrypted DM has correct fields\": async assert => {\n const invite = new Invite({\n roomId,\n platform: {clock: new MockClock(1003)},\n user: {id: \"@bob:hs.tld\"}\n });\n const txn = createStorage();\n const changes = await invite.writeSync(\"invite\", dmInviteFixture, txn, new NullLogItem());\n assert.equal(txn.invitesMap.get(roomId).roomId, roomId);\n invite.afterSync(changes, new NullLogItem());\n assert.equal(invite.name, \"Alice\");\n assert.equal(invite.avatarUrl, aliceAvatarUrl);\n assert.equal(invite.timestamp, 1003);\n assert.equal(invite.isEncrypted, true);\n assert.equal(invite.isDirectMessage, true);\n assert(invite.inviter);\n assert.equal(invite.inviter.userId, \"@alice:hs.tld\");\n assert.equal(invite.inviter.displayName, \"Alice\");\n assert.equal(invite.inviter.avatarUrl, aliceAvatarUrl);\n },\n \"load persisted invite has correct fields\": async assert => {\n const writeInvite = new Invite({\n roomId,\n platform: {clock: new MockClock(1003)},\n user: {id: \"@bob:hs.tld\"}\n });\n const txn = createStorage();\n await writeInvite.writeSync(\"invite\", dmInviteFixture, txn, new NullLogItem());\n const invite = new Invite({roomId});\n invite.load(txn.invitesMap.get(roomId), new NullLogItem());\n assert.equal(invite.name, \"Alice\");\n assert.equal(invite.avatarUrl, aliceAvatarUrl);\n assert.equal(invite.timestamp, 1003);\n assert.equal(invite.isEncrypted, true);\n assert.equal(invite.isDirectMessage, true);\n assert(invite.inviter);\n assert.equal(invite.inviter.userId, \"@alice:hs.tld\");\n assert.equal(invite.inviter.displayName, \"Alice\");\n assert.equal(invite.inviter.avatarUrl, aliceAvatarUrl);\n },\n \"syncing join sets accepted\": async assert => {\n let changeEmitCount = 0;\n const invite = new Invite({\n roomId,\n platform: {clock: new MockClock(1003)},\n user: {id: \"@bob:hs.tld\"},\n });\n invite.on(\"change\", () => { changeEmitCount += 1; });\n const txn = createStorage();\n const changes = await invite.writeSync(\"invite\", dmInviteFixture, txn, new NullLogItem());\n assert.equal(txn.invitesMap.get(roomId).roomId, roomId);\n invite.afterSync(changes, new NullLogItem());\n const joinChanges = await invite.writeSync(\"join\", null, txn, new NullLogItem());\n assert.strictEqual(changeEmitCount, 0);\n invite.afterSync(joinChanges, new NullLogItem());\n assert.strictEqual(changeEmitCount, 1);\n assert.equal(txn.invitesMap.get(roomId), undefined);\n assert.equal(invite.rejected, false);\n assert.equal(invite.accepted, true);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {HomeServerApi} from \"../net/HomeServerApi.js\";\nimport type {ILogItem} from \"../../logging/types\";\n\nexport interface IPusherDescription {\n kind: \"http\" | \"email\" | \"null\";\n lang: string;\n device_display_name: string;\n app_display_name: string;\n app_id: string;\n pushkey: string;\n data: IPusherData;\n append?: boolean;\n profile_tag?: string;\n}\n\ninterface IPusherData {\n format?: string;\n url?: string;\n endpoint?: PushSubscriptionJSON[\"endpoint\"];\n keys?: PushSubscriptionJSON[\"keys\"];\n}\n\nexport class Pusher {\n private readonly _description: IPusherDescription;\n\n constructor(description: IPusherDescription) {\n this._description = description;\n }\n\n static httpPusher(host: string, appId: string, pushkey: string, data: IPusherData): Pusher {\n return new Pusher({\n kind: \"http\",\n append: true, // as pushkeys are shared between multiple users on one origin\n data: Object.assign({}, data, {url: host + \"/_matrix/push/v1/notify\"}),\n pushkey,\n app_id: appId,\n app_display_name: \"Hydrogen\",\n device_display_name: \"Hydrogen\",\n lang: \"en\"\n });\n }\n\n static createDefaultPayload(sessionId: string): {session_id: string} {\n return {session_id: sessionId};\n }\n\n async enable(hsApi: HomeServerApi, log: ILogItem): Promise {\n try {\n log.set(\"endpoint\", new URL(this._description.data.endpoint!).host);\n } catch {\n log.set(\"endpoint\", null);\n }\n await hsApi.setPusher(this._description, {log}).response();\n }\n\n async disable(hsApi: HomeServerApi, log: ILogItem): Promise {\n const deleteDescription = Object.assign({}, this._description, {kind: null});\n await hsApi.setPusher(deleteDescription, {log}).response();\n }\n\n serialize(): IPusherDescription {\n return this._description;\n }\n\n equals(pusher): boolean {\n if (this._description.app_id !== pusher._description.app_id) {\n return false;\n }\n if (this._description.pushkey !== pusher._description.pushkey) {\n return false;\n }\n return JSON.stringify(this._description.data) === JSON.stringify(pusher._description.data);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {OLM_ALGORITHM} from \"./e2ee/common\";\nimport {countBy, groupBy} from \"../utils/groupBy\";\nimport {LRUCache} from \"../utils/LRUCache\";\nimport {EventEmitter} from \"../utils/EventEmitter\";\n\nexport class DeviceMessageHandler extends EventEmitter{\n constructor({storage, callHandler}) {\n super();\n this._storage = storage;\n this._olmDecryption = null;\n this._megolmDecryption = null;\n this._callHandler = callHandler;\n this._senderDeviceCache = new LRUCache(10, di => di.curve25519Key);\n }\n\n enableEncryption({olmDecryption, megolmDecryption}) {\n this._olmDecryption = olmDecryption;\n this._megolmDecryption = megolmDecryption;\n }\n\n obtainSyncLock(toDeviceEvents) {\n return this._olmDecryption?.obtainDecryptionLock(toDeviceEvents);\n }\n\n async prepareSync(toDeviceEvents, lock, txn, log) {\n log.set(\"messageTypes\", countBy(toDeviceEvents, e => e.type));\n const encryptedEvents = toDeviceEvents.filter(e => e.type === \"m.room.encrypted\");\n this._emitUnencryptedEvents(toDeviceEvents);\n if (!this._olmDecryption) {\n log.log(\"can't decrypt, encryption not enabled\", log.level.Warn);\n return;\n }\n // only know olm for now\n const olmEvents = encryptedEvents.filter(e => e.content?.algorithm === OLM_ALGORITHM);\n if (olmEvents.length) {\n const olmDecryptChanges = await this._olmDecryption.decryptAll(olmEvents, lock, txn);\n log.set(\"decryptedTypes\", countBy(olmDecryptChanges.results, r => r.event?.type));\n for (const err of olmDecryptChanges.errors) {\n log.child(\"decrypt_error\").catch(err);\n }\n const newRoomKeys = this._megolmDecryption.roomKeysFromDeviceMessages(olmDecryptChanges.results, log);\n \n // TODO: somehow include rooms that received a call to_device message in the sync state?\n // or have updates flow through event emitter?\n // well, we don't really need to update the room other then when a call starts or stops\n // any changes within the call will be emitted on the call object?\n return new SyncPreparation(olmDecryptChanges, newRoomKeys);\n }\n }\n\n /** check that prep is not undefined before calling this */\n async writeSync(prep, txn) {\n // write olm changes\n prep.olmDecryptChanges.write(txn);\n const didWriteValues = await Promise.all(prep.newRoomKeys.map(key => this._megolmDecryption.writeRoomKey(key, txn)));\n const hasNewRoomKeys = didWriteValues.some(didWrite => !!didWrite);\n return {\n hasNewRoomKeys,\n decryptionResults: prep.olmDecryptChanges.results\n };\n }\n\n async afterSyncCompleted(decryptionResults, deviceTracker, hsApi, log) {\n await log.wrap(\"Verifying fingerprint of encrypted toDevice messages\", async (log) => {\n for (const result of decryptionResults) {\n const sender = result.event.sender;\n const device = await deviceTracker.deviceForCurveKey(\n sender,\n result.senderCurve25519Key,\n hsApi,\n log\n );\n result.setDevice(device);\n if (result.isVerified) {\n this.emit(\"message\", { encrypted: result });\n }\n else {\n log.log({\n l: \"could not verify olm fingerprint key matches, ignoring\",\n ed25519Key: result.device.ed25519Key,\n claimedEd25519Key: result.claimedEd25519Key,\n deviceId: device.deviceId,\n userId: device.userId,\n });\n }\n }\n });\n // todo: Refactor the following to use to device messages \n if (this._callHandler) {\n // if we don't have a device, we need to fetch the device keys the message claims\n // and check the keys, and we should only do network requests during\n // sync processing in the afterSyncCompleted step.\n const callMessages = decryptionResults.filter(dr => this._callHandler.handlesDeviceMessageEventType(dr.event?.type));\n if (callMessages.length) {\n await log.wrap(\"process call signalling messages\", async log => {\n for (const dr of callMessages) {\n // serialize device loading, so subsequent messages for the same device take advantage of the cache\n const device = await deviceTracker.deviceForId(dr.event.sender, dr.event.content.device_id, hsApi, log);\n dr.setDevice(device);\n if (dr.isVerified) {\n this._callHandler.handleDeviceMessage(dr.event, dr.userId, dr.deviceId, log);\n } else {\n log.log({\n l: \"could not verify olm fingerprint key matches, ignoring\",\n ed25519Key: dr.device.ed25519Key,\n claimedEd25519Key: dr.claimedEd25519Key,\n deviceId: device.deviceId,\n userId: device.userId,\n });\n }\n }\n });\n }\n }\n }\n\n _emitUnencryptedEvents(toDeviceEvents) {\n const unencryptedEvents = toDeviceEvents.filter(e => e.type !== \"m.room.encrypted\");\n for (const event of unencryptedEvents) {\n this.emit(\"message\", { unencrypted: event });\n }\n }\n\n}\n\nclass SyncPreparation {\n constructor(olmDecryptChanges, newRoomKeys) {\n this.olmDecryptChanges = olmDecryptChanges;\n this.newRoomKeys = newRoomKeys;\n this.newKeysByRoom = groupBy(newRoomKeys, r => r.roomId);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport anotherjson from \"another-json\";\nimport {SESSION_E2EE_KEY_PREFIX, OLM_ALGORITHM, MEGOLM_ALGORITHM} from \"./common\";\n\n// use common prefix so it's easy to clear properties that are not e2ee related during session clear\nconst ACCOUNT_SESSION_KEY = SESSION_E2EE_KEY_PREFIX + \"olmAccount\";\nconst DEVICE_KEY_FLAG_SESSION_KEY = SESSION_E2EE_KEY_PREFIX + \"areDeviceKeysUploaded\";\nconst SERVER_OTK_COUNT_SESSION_KEY = SESSION_E2EE_KEY_PREFIX + \"serverOTKCount\";\n\nasync function initiallyStoreAccount(account, pickleKey, areDeviceKeysUploaded, serverOTKCount, storage) {\n const pickledAccount = account.pickle(pickleKey);\n const txn = await storage.readWriteTxn([\n storage.storeNames.session\n ]);\n try {\n // add will throw if the key already exists\n // we would not want to overwrite olmAccount here\n txn.session.add(ACCOUNT_SESSION_KEY, pickledAccount);\n txn.session.add(DEVICE_KEY_FLAG_SESSION_KEY, areDeviceKeysUploaded);\n txn.session.add(SERVER_OTK_COUNT_SESSION_KEY, serverOTKCount);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n}\n\nexport class Account {\n static async load({olm, pickleKey, hsApi, userId, deviceId, olmWorker, txn}) {\n const pickledAccount = await txn.session.get(ACCOUNT_SESSION_KEY);\n if (pickledAccount) {\n const account = new olm.Account();\n const areDeviceKeysUploaded = await txn.session.get(DEVICE_KEY_FLAG_SESSION_KEY);\n account.unpickle(pickleKey, pickledAccount);\n const serverOTKCount = await txn.session.get(SERVER_OTK_COUNT_SESSION_KEY);\n return new Account({pickleKey, hsApi, account, userId,\n deviceId, areDeviceKeysUploaded, serverOTKCount, olm, olmWorker});\n }\n }\n\n static async adoptDehydratedDevice({olm, dehydratedDevice, pickleKey, hsApi, userId, olmWorker, storage}) {\n const account = dehydratedDevice.adoptUnpickledOlmAccount();\n const oneTimeKeys = JSON.parse(account.one_time_keys());\n // only one algorithm supported by olm atm, so hardcode its name\n const oneTimeKeysEntries = Object.entries(oneTimeKeys.curve25519);\n const serverOTKCount = oneTimeKeysEntries.length;\n const areDeviceKeysUploaded = true;\n await initiallyStoreAccount(account, pickleKey, areDeviceKeysUploaded, serverOTKCount, storage);\n return new Account({\n pickleKey, hsApi, account, userId,\n deviceId: dehydratedDevice.deviceId,\n areDeviceKeysUploaded, serverOTKCount, olm, olmWorker\n });\n }\n\n static async create({olm, pickleKey, hsApi, userId, deviceId, olmWorker, storage}) {\n const account = new olm.Account();\n if (olmWorker) {\n await olmWorker.createAccountAndOTKs(account, account.max_number_of_one_time_keys());\n } else {\n account.create();\n account.generate_one_time_keys(account.max_number_of_one_time_keys());\n }\n const areDeviceKeysUploaded = false;\n const serverOTKCount = 0;\n if (storage) {\n await initiallyStoreAccount(account, pickleKey, areDeviceKeysUploaded, serverOTKCount, storage);\n }\n return new Account({pickleKey, hsApi, account, userId,\n deviceId, areDeviceKeysUploaded, serverOTKCount, olm, olmWorker});\n }\n\n constructor({pickleKey, hsApi, account, userId, deviceId, areDeviceKeysUploaded, serverOTKCount, olm, olmWorker}) {\n this._olm = olm;\n this._pickleKey = pickleKey;\n this._hsApi = hsApi;\n this._account = account;\n this._userId = userId;\n this._deviceId = deviceId;\n this._areDeviceKeysUploaded = areDeviceKeysUploaded;\n this._serverOTKCount = serverOTKCount;\n this._olmWorker = olmWorker;\n this._identityKeys = JSON.parse(this._account.identity_keys());\n }\n\n get identityKeys() {\n return this._identityKeys;\n }\n\n setDeviceId(deviceId) {\n this._deviceId = deviceId;\n }\n\n async uploadKeys(storage, isDehydratedDevice, log) {\n const oneTimeKeys = JSON.parse(this._account.one_time_keys());\n // only one algorithm supported by olm atm, so hardcode its name\n const oneTimeKeysEntries = Object.entries(oneTimeKeys.curve25519);\n if (oneTimeKeysEntries.length || !this._areDeviceKeysUploaded) {\n const payload = {};\n if (!this._areDeviceKeysUploaded) {\n log.set(\"identity\", true);\n const identityKeys = JSON.parse(this._account.identity_keys());\n payload.device_keys = this._deviceKeysPayload(identityKeys);\n }\n if (oneTimeKeysEntries.length) {\n log.set(\"otks\", true);\n payload.one_time_keys = this._oneTimeKeysPayload(oneTimeKeysEntries);\n }\n const dehydratedDeviceId = isDehydratedDevice ? this._deviceId : undefined;\n const response = await this._hsApi.uploadKeys(dehydratedDeviceId, payload, {log}).response();\n this._serverOTKCount = response?.one_time_key_counts?.signed_curve25519;\n log.set(\"serverOTKCount\", this._serverOTKCount);\n // TODO: should we not modify this in the txn like we do elsewhere?\n // we'd have to pickle and unpickle the account to clone it though ...\n // and the upload has succeed at this point, so in-memory would be correct\n // but in-storage not if the txn fails. \n await this._updateSessionStorage(storage, sessionStore => {\n if (oneTimeKeysEntries.length) {\n this._account.mark_keys_as_published();\n sessionStore?.set(ACCOUNT_SESSION_KEY, this._account.pickle(this._pickleKey));\n sessionStore?.set(SERVER_OTK_COUNT_SESSION_KEY, this._serverOTKCount);\n }\n if (!this._areDeviceKeysUploaded) {\n this._areDeviceKeysUploaded = true;\n sessionStore?.set(DEVICE_KEY_FLAG_SESSION_KEY, this._areDeviceKeysUploaded);\n }\n });\n }\n }\n\n async generateOTKsIfNeeded(storage, log) {\n // We need to keep a pool of one time public keys on the server so that\n // other devices can start conversations with us. But we can only store\n // a finite number of private keys in the olm Account object.\n // To complicate things further there can be a delay between a device\n // claiming a public one time key from the server and it sending us a\n // message. We need to keep the corresponding private key locally until\n // we receive the message.\n // But that message might never arrive leaving us stuck with duff\n // private keys clogging up our local storage.\n // So we need some kind of engineering compromise to balance all of\n // these factors.\n \n // Check how many keys we can store in the Account object.\n const maxOTKs = this._account.max_number_of_one_time_keys();\n // Try to keep at most half that number on the server. This leaves the\n // rest of the slots free to hold keys that have been claimed from the\n // server but we haven't recevied a message for.\n // If we run out of slots when generating new keys then olm will\n // discard the oldest private keys first. This will eventually clean\n // out stale private keys that won't receive a message.\n const keyLimit = Math.floor(maxOTKs / 2);\n // does the server have insufficient OTKs?\n if (this._serverOTKCount < keyLimit) {\n const oneTimeKeys = JSON.parse(this._account.one_time_keys());\n const oneTimeKeysEntries = Object.entries(oneTimeKeys.curve25519);\n const unpublishedOTKCount = oneTimeKeysEntries.length;\n // we want to end up with maxOTKs / 2 key on the server,\n // so generate any on top of the remaining ones on the server and the unpublished ones\n // (we have generated before but haven't uploaded yet for some reason)\n // to get to that number.\n const newKeyCount = keyLimit - unpublishedOTKCount - this._serverOTKCount;\n if (newKeyCount > 0) {\n await log.wrap(\"generate otks\", log => {\n log.set(\"max\", maxOTKs);\n log.set(\"server\", this._serverOTKCount);\n log.set(\"unpublished\", unpublishedOTKCount);\n log.set(\"new\", newKeyCount);\n log.set(\"limit\", keyLimit);\n this._account.generate_one_time_keys(newKeyCount);\n this._updateSessionStorage(storage, sessionStore => {\n sessionStore.set(ACCOUNT_SESSION_KEY, this._account.pickle(this._pickleKey));\n });\n });\n }\n // even though we didn't generate any keys, we still have some unpublished ones that should be published\n return true;\n }\n return false;\n }\n\n createInboundOlmSession(senderKey, body) {\n const newSession = new this._olm.Session();\n try {\n newSession.create_inbound_from(this._account, senderKey, body);\n return newSession;\n } catch (err) {\n newSession.free();\n throw err;\n }\n }\n\n async createOutboundOlmSession(theirIdentityKey, theirOneTimeKey) {\n const newSession = new this._olm.Session();\n try {\n if (this._olmWorker) {\n await this._olmWorker.createOutboundOlmSession(this._account, newSession, theirIdentityKey, theirOneTimeKey);\n } else {\n newSession.create_outbound(this._account, theirIdentityKey, theirOneTimeKey);\n }\n return newSession;\n } catch (err) {\n newSession.free();\n throw err;\n }\n }\n\n writeRemoveOneTimeKey(session, txn) {\n // this is side-effecty and will have applied the change if the txn fails,\n // but don't want to clone the account for now\n // and it is not the worst thing to think we have used a OTK when\n // decrypting the message that actually used it threw for some reason.\n this._account.remove_one_time_keys(session);\n txn.session.set(ACCOUNT_SESSION_KEY, this._account.pickle(this._pickleKey));\n }\n\n writeSync(deviceOneTimeKeysCount, txn, log) {\n // we only upload signed_curve25519 otks\n const otkCount = deviceOneTimeKeysCount.signed_curve25519;\n if (Number.isSafeInteger(otkCount) && otkCount !== this._serverOTKCount) {\n txn.session.set(SERVER_OTK_COUNT_SESSION_KEY, otkCount);\n log.set(\"otkCount\", otkCount);\n return otkCount;\n }\n }\n\n afterSync(otkCount) {\n // could also be undefined\n if (Number.isSafeInteger(otkCount)) {\n this._serverOTKCount = otkCount;\n }\n }\n\n _keysAsSignableObject(identityKeys) {\n const obj = {\n user_id: this._userId,\n device_id: this._deviceId,\n algorithms: [OLM_ALGORITHM, MEGOLM_ALGORITHM],\n keys: {}\n };\n for (const [algorithm, pubKey] of Object.entries(identityKeys)) {\n obj.keys[`${algorithm}:${this._deviceId}`] = pubKey;\n }\n return obj;\n }\n\n getUnsignedDeviceKey() {\n const identityKeys = JSON.parse(this._account.identity_keys());\n return this._keysAsSignableObject(identityKeys);\n }\n\n _deviceKeysPayload(identityKeys) {\n const obj = this._keysAsSignableObject(identityKeys);\n this.signObject(obj);\n return obj;\n }\n\n _oneTimeKeysPayload(oneTimeKeysEntries) {\n const obj = {};\n for (const [keyId, pubKey] of oneTimeKeysEntries) {\n const keyObj = {\n key: pubKey \n };\n this.signObject(keyObj);\n obj[`signed_curve25519:${keyId}`] = keyObj;\n }\n return obj;\n }\n\n async _updateSessionStorage(storage, callback) {\n if (storage) {\n const txn = await storage.readWriteTxn([\n storage.storeNames.session\n ]);\n try {\n await callback(txn.session);\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n } else {\n await callback(undefined);\n }\n }\n\n signObject(obj) {\n const sigs = obj.signatures || {};\n const unsigned = obj.unsigned;\n\n delete obj.signatures;\n delete obj.unsigned;\n\n sigs[this._userId] = sigs[this._userId] || {};\n sigs[this._userId][\"ed25519:\" + this._deviceId] = \n this._account.sign(anotherjson.stringify(obj));\n obj.signatures = sigs;\n if (unsigned !== undefined) {\n obj.unsigned = unsigned;\n }\n }\n\n pickleWithKey(key) {\n return this._account.pickle(key);\n }\n\n dispose() {\n this._account.free();\n this._account = undefined;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {Platform} from \"../../platform/web/Platform.js\";\n\nexport type KeyDescriptionData = {\n algorithm: string;\n passphrase: {\n algorithm: string;\n iterations: number;\n salt: string;\n bits?: number;\n };\n mac: string;\n iv: string;\n}\n\nexport class KeyDescription {\n private readonly _id: string;\n private readonly _keyDescription: KeyDescriptionData;\n\n constructor(id: string, keyDescription: KeyDescriptionData) {\n this._id = id;\n this._keyDescription = keyDescription;\n }\n\n get id(): string {\n return this._id;\n }\n\n get passphraseParams(): KeyDescriptionData[\"passphrase\"] {\n return this._keyDescription?.passphrase;\n }\n\n get algorithm(): string {\n return this._keyDescription?.algorithm;\n }\n\n async isCompatible(key: Key, platform: Platform): Promise {\n if (this.algorithm === \"m.secret_storage.v1.aes-hmac-sha2\") {\n const kd = this._keyDescription;\n if (kd.mac) {\n const otherMac = await calculateKeyMac(key.binaryKey, kd.iv, platform);\n return kd.mac === otherMac;\n } else if (kd.passphrase) {\n const kdOther = key.description._keyDescription;\n if (!kdOther.passphrase) {\n return false;\n }\n return kd.passphrase.algorithm === kdOther.passphrase.algorithm && \n kd.passphrase.iterations === kdOther.passphrase.iterations && \n kd.passphrase.salt === kdOther.passphrase.salt;\n }\n }\n return false;\n }\n}\n\nexport class Key {\n private readonly _keyDescription: KeyDescription;\n private readonly _binaryKey: Uint8Array;\n\n constructor(keyDescription: KeyDescription, binaryKey: Uint8Array) {\n this._keyDescription = keyDescription;\n this._binaryKey = binaryKey;\n }\n\n withDescription(description: KeyDescription): Key {\n return new Key(description, this._binaryKey);\n }\n\n get description(): KeyDescription {\n return this._keyDescription;\n }\n\n get id(): string {\n return this._keyDescription.id;\n }\n\n get binaryKey(): Uint8Array {\n return this._binaryKey;\n }\n\n get algorithm(): string {\n return this._keyDescription.algorithm;\n }\n}\n\nasync function calculateKeyMac(key: BufferSource, ivStr: string, platform: Platform): Promise {\n const {crypto, encoding} = platform;\n const {utf8, base64} = encoding;\n const {derive, aes, hmac} = crypto;\n\n const iv = base64.decode(ivStr);\n\n // salt for HKDF, with 8 bytes of zeros\n const zerosalt = new Uint8Array(8);\n const ZERO_STR = \"\\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\";\n \n const info = utf8.encode(\"\");\n const keybits = await derive.hkdf(key, zerosalt, info, \"SHA-256\", 512);\n const aesKey = keybits.slice(0, 32);\n const hmacKey = keybits.slice(32);\n const ciphertext = await aes.encryptCTR({key: aesKey, iv, data: utf8.encode(ZERO_STR)});\n const mac = await hmac.compute(hmacKey, ciphertext, \"SHA-256\");\n\n return base64.encode(mac);\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Key} from \"./common\";\nimport type {KeyDescription} from \"./common\";\nimport type {Platform} from \"../../platform/web/Platform.js\";\n\nconst DEFAULT_ITERATIONS = 500000;\nconst DEFAULT_BITSIZE = 256;\n\n/**\n * @param {KeyDescription} keyDescription\n * @param {string} passphrase\n * @param {Platform} platform\n * @return {Key}\n */\nexport async function keyFromPassphrase(keyDescription: KeyDescription, passphrase: string, platform: Platform): Promise {\n const {passphraseParams} = keyDescription;\n if (!passphraseParams) {\n throw new Error(\"not a passphrase key\");\n }\n if (passphraseParams.algorithm !== \"m.pbkdf2\") {\n throw new Error(`Unsupported passphrase algorithm: ${passphraseParams.algorithm}`);\n }\n const {utf8} = platform.encoding;\n const keyBits = await platform.crypto.derive.pbkdf2(\n utf8.encode(passphrase),\n passphraseParams.iterations || DEFAULT_ITERATIONS,\n // salt is just a random string, not encoded in any way\n utf8.encode(passphraseParams.salt),\n \"SHA-512\",\n passphraseParams.bits || DEFAULT_BITSIZE);\n return new Key(keyDescription, keyBits);\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {Key} from \"./common\";\nimport {KeyDescription} from \"./common\";\nimport type {Platform} from \"../../platform/web/Platform.js\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nconst OLM_RECOVERY_KEY_PREFIX = [0x8B, 0x01] as const;\n\n/**\n * @param {Olm} olm\n * @param {KeyDescription} keyDescription\n * @param {string} recoveryKey\n * @return {Key}\n */\nexport function keyFromRecoveryKey(keyDescription: KeyDescription, recoveryKey: string, olm: Olm, platform: Platform): Key {\n const result = platform.encoding.base58.decode(recoveryKey.replace(/ /g, ''));\n\n let parity = 0;\n for (const b of result) {\n parity ^= b;\n }\n if (parity !== 0) {\n throw new Error(\"Incorrect parity\");\n }\n\n for (let i = 0; i < OLM_RECOVERY_KEY_PREFIX.length; ++i) {\n if (result[i] !== OLM_RECOVERY_KEY_PREFIX[i]) {\n throw new Error(\"Incorrect prefix\");\n }\n }\n\n if (\n result.length !==\n OLM_RECOVERY_KEY_PREFIX.length + olm.PRIVATE_KEY_LENGTH + 1\n ) {\n throw new Error(\"Incorrect length\");\n }\n\n const keyBits = Uint8Array.from(result.slice(\n OLM_RECOVERY_KEY_PREFIX.length,\n OLM_RECOVERY_KEY_PREFIX.length + olm.PRIVATE_KEY_LENGTH,\n ));\n\n return new Key(keyDescription, keyBits);\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {SecretStorage} from \"./SecretStorage\";\nimport type {SecretSharing} from \"./SecretSharing\";\n\n/**\n * This is a wrapper around SecretStorage and SecretSharing so that \n * you don't need to check both sources for a secret.\n */\nexport class SecretFetcher {\n public secretStorage: SecretStorage;\n public secretSharing: SecretSharing;\n\n async getSecret(name: string): Promise {\n /**\n * Note that we don't ask another device for secret here;\n * that should be done explicitly since it can take arbitrary\n * amounts of time to be fulfilled as the other devices may \n * be offline etc...\n */\n return await this.secretStorage?.readSecret(name) ??\n await this.secretSharing?.getLocallyStoredSecret(name);\n } \n\n setSecretStorage(storage: SecretStorage) {\n this.secretStorage = storage;\n }\n\n setSecretSharing(sharing: SecretSharing) {\n this.secretSharing = sharing;\n /**\n * SecretSharing also needs to respond to secret requests\n * from other devices, so it needs the secret fetcher as \n * well\n */\n this.secretSharing.setSecretFetcher(this);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {HomeServerApi} from \"../net/HomeServerApi\";\nimport type {Storage} from \"../storage/idb/Storage\";\nimport type {DeviceMessageHandler} from \"../DeviceMessageHandler.js\"\nimport type {DeviceTracker} from \"../e2ee/DeviceTracker\";\nimport type {ILogger, ILogItem} from \"../../logging/types\";\nimport type {Encryption as OlmEncryption} from \"../e2ee/olm/Encryption\";\nimport type {Crypto} from \"../../platform/web/dom/Crypto.js\";\nimport type {Encoding} from \"../../platform/web/utils/Encoding.js\";\nimport type {CrossSigning} from \"../verification/CrossSigning\";\nimport type {SecretFetcher} from \"./SecretFetcher\";\nimport type {ObservableValue} from \"../../observable/value\";\nimport type {DecryptionResult} from \"../e2ee/DecryptionResult\";\nimport {makeTxnId, formatToDeviceMessagesPayload} from \"../common.js\";\nimport {Deferred} from \"../../utils/Deferred\";\nimport {StoreNames} from \"../storage/common\";\nimport {SESSION_E2EE_KEY_PREFIX} from \"../e2ee/common\";\n\ntype Options = {\n hsApi: HomeServerApi;\n storage: Storage;\n deviceMessageHandler: DeviceMessageHandler;\n deviceTracker: DeviceTracker;\n ourUserId: string;\n olmEncryption: OlmEncryption;\n crypto: Crypto;\n encoding: Encoding;\n crossSigning: ObservableValue;\n logger: ILogger;\n};\n\nconst enum EVENT_TYPE {\n REQUEST = \"m.secret.request\",\n SEND = \"m.secret.send\",\n}\n\n\nconst STORAGE_KEY = \"secretRequestIds\";\n\nexport class SecretSharing {\n private readonly hsApi: HomeServerApi;\n private readonly storage: Storage;\n private readonly deviceMessageHandler: DeviceMessageHandler;\n private readonly deviceTracker: DeviceTracker;\n private readonly ourUserId: string;\n private readonly olmEncryption: OlmEncryption;\n private readonly waitMap: Map, name: string }> = new Map();\n private readonly encoding: Encoding;\n private readonly aesEncryption: AESEncryption;\n private readonly crossSigning: ObservableValue;\n private readonly logger: ILogger;\n private secretFetcher: SecretFetcher;\n\n constructor(options: Options) {\n this.hsApi = options.hsApi;\n this.storage = options.storage;\n this.deviceMessageHandler = options.deviceMessageHandler;\n this.deviceTracker = options.deviceTracker;\n this.ourUserId = options.ourUserId;\n this.olmEncryption = options.olmEncryption;\n this.encoding = options.encoding;\n this.crossSigning = options.crossSigning;\n this.logger = options.logger;\n this.aesEncryption = new AESEncryption(this.storage, options.crypto, this.encoding);\n }\n\n async load(): Promise {\n this.deviceMessageHandler.on(\"message\", async ({ encrypted }) => {\n const type: EVENT_TYPE = encrypted?.event.type;\n switch (type) {\n case EVENT_TYPE.REQUEST: {\n await this._respondToRequest(encrypted);\n break;\n }\n case EVENT_TYPE.SEND: {\n const {secret} = encrypted.event.content;\n const name = await this.shouldAcceptSecret(encrypted);\n if (name) {\n this.writeSecretToStorage(name, secret);\n }\n break;\n }\n }\n });\n await this.aesEncryption.load();\n }\n\n private async _respondToRequest(request): Promise {\n await this.logger.run(\"SharedSecret.respondToRequest\", async (log) => {\n if (!await this.shouldRespondToRequest(request, log)) {\n return;\n }\n const requestContent = request.event.content;\n const id = requestContent.request_id;\n const deviceId = requestContent.requesting_device_id;\n const name = requestContent.name;\n \n const secret = await this.secretFetcher.getSecret(name);\n if (!secret) {\n // Can't share a secret that we don't know about.\n log.log({ l: \"Secret not available to share\" });\n return;\n }\n\n const content = { secret, request_id: id };\n const device = await this.deviceTracker.deviceForId(this.ourUserId, deviceId, this.hsApi, log);\n if (!device) {\n log.log({ l: \"Cannot find device\", deviceId });\n return;\n }\n const messages = await log.wrap(\"olm encrypt\", log => this.olmEncryption.encrypt(\n EVENT_TYPE.SEND, content, [device], this.hsApi, log));\n const payload = formatToDeviceMessagesPayload(messages);\n await this.hsApi.sendToDevice(\"m.room.encrypted\", payload, makeTxnId(), {log}).response();\n });\n }\n\n private async shouldRespondToRequest(request: any, log: ILogItem): Promise {\n return log.wrap(\"SecretSharing.shouldRespondToRequest\", async () => {\n if (request.event.content.requesting_device_id === this.deviceTracker.ownDeviceId) {\n // This is the request that we sent, so ignore\n return false;\n }\n const crossSigning = this.crossSigning.get();\n if (!crossSigning) {\n // We're not in a position to respond to this request\n log.log({ crossSigningNotAvailable: true });\n return false;\n }\n\n const content = request.event.content;\n if (\n request.event.sender !== this.ourUserId ||\n !(\n content.name &&\n content.action &&\n content.requesting_device_id &&\n content.request_id\n ) ||\n content.action === \"request_cancellation\"\n ) {\n // 1. Ensure that the message came from the same user as us\n // 2. Validate message format\n // 3. Check if this is a cancellation \n return false;\n }\n\n // 3. Check that the device is verified\n const deviceId = content.requesting_device_id;\n const device = await this.deviceTracker.deviceForId(this.ourUserId, deviceId, this.hsApi, log);\n if (!device) {\n log.log({ l: \"Device could not be acquired\", deviceId });\n return false;\n }\n if (!await crossSigning.isOurUserDeviceTrusted(device, log)) {\n log.log({ l: \"Device not trusted, returning\" });\n return false;\n }\n return true;\n });\n }\n\n /**\n * Returns name of the secret if we can accept the response.\n * Returns undefined otherwise.\n * @param decryptionResult Encrypted to-device event that contains the secret\n */\n private async shouldAcceptSecret(decryptionResult: DecryptionResult): Promise {\n // 1. Check if we can trust this response\n const crossSigning = this.crossSigning.get();\n if (!crossSigning) {\n return;\n }\n const device = decryptionResult.device;\n if (!device) {\n return;\n }\n if (!await crossSigning.isOurUserDeviceTrusted(device)) {\n // We don't want to accept secrets from an untrusted device\n return;\n }\n const content = decryptionResult.event.content!;\n const requestId = content.request_id;\n // 2. Check if this request is in waitMap\n const obj = this.waitMap.get(requestId);\n if (obj) {\n const { name, deferred } = obj;\n deferred.resolve(decryptionResult);\n this.waitMap.delete(requestId);\n await this.removeStoredRequestId(requestId);\n return name;\n }\n // 3. Check if we've persisted the request to storage\n const txn = await this.storage.readTxn([this.storage.storeNames.session]);\n const storedIds = await txn.session.get(STORAGE_KEY);\n const name = storedIds?.[requestId];\n if (name) {\n await this.removeStoredRequestId(requestId);\n return name;\n }\n }\n\n private async removeStoredRequestId(requestId: string): Promise {\n const txn = await this.storage.readWriteTxn([this.storage.storeNames.session]);\n const storedIds = await txn.session.get(STORAGE_KEY);\n if (storedIds) {\n delete storedIds[requestId];\n txn.session.set(STORAGE_KEY, storedIds);\n }\n }\n\n async checkSecretValidity(log: ILogItem): Promise {\n const crossSigning = this.crossSigning.get();\n const needsDeleting = !await crossSigning?.areWeVerified(log);\n if (needsDeleting) {\n // User probably reset their cross-signing keys\n // Can't trust the secrets anymore!\n const txn = await this.storage.readWriteTxn([this.storage.storeNames.sharedSecrets]);\n txn.sharedSecrets.deleteAllSecrets();\n }\n }\n\n async getLocallyStoredSecret(name: string): Promise {\n const txn = await this.storage.readTxn([\n this.storage.storeNames.sharedSecrets,\n ]);\n const storedSecret = await txn.sharedSecrets.get(name);\n if (storedSecret) {\n const secret = await this.aesEncryption.decrypt(storedSecret.encrypted);\n return secret;\n }\n }\n\n // todo: this will break if two different pieces of code call this method\n requestSecret(name: string, log: ILogItem): Promise {\n return log.wrap(\"SharedSecret.requestSecret\", async (_log) => {\n const request_id = makeTxnId();\n const promise = this.trackSecretRequest(request_id, name);\n await this.sendRequestForSecret(name, request_id, _log);\n await this.writeRequestIdToStorage(request_id, name);\n const request = new SecretRequest(promise);\n return request;\n });\n }\n\n /**\n * We will store the request-id of every secret request that we send.\n * If a device responds to our secret request when we're offline and we receive\n * it via sync when we come online at some later time, we can use this persisted\n * request-id to determine if we should accept the secret.\n */\n private async writeRequestIdToStorage(requestId: string, name: string): Promise {\n const txn = await this.storage.readWriteTxn([\n this.storage.storeNames.session,\n ]);\n const txnIds = await txn.session.get(STORAGE_KEY) ?? {};\n txnIds[requestId] = name;\n txn.session.set(STORAGE_KEY, txnIds)\n }\n\n private async writeSecretToStorage(name:string, secret: any): Promise {\n const encrypted = await this.aesEncryption.encrypt(secret);\n const txn = await this.storage.readWriteTxn([StoreNames.sharedSecrets]);\n txn.sharedSecrets.set(name, { encrypted });\n }\n\n private trackSecretRequest(request_id: string, name: string): Promise {\n const deferred = new Deferred(); \n this.waitMap.set(request_id, { deferred, name });\n return deferred.promise;\n }\n \n private async sendRequestForSecret(name: string, request_id: string, log: ILogItem): Promise {\n const content = {\n action: \"request\",\n name,\n request_id,\n requesting_device_id: this.deviceTracker.ownDeviceId,\n }\n let devices = await this.deviceTracker.devicesForUsers([this.ourUserId], this.hsApi, log);\n devices = devices.filter(d => d.device_id !== this.deviceTracker.ownDeviceId);\n const messages = await log.wrap(\"olm encrypt\", log => this.olmEncryption.encrypt(\n EVENT_TYPE.REQUEST, content, devices, this.hsApi, log));\n const payload = formatToDeviceMessagesPayload(messages);\n await this.hsApi.sendToDevice(\"m.room.encrypted\", payload, makeTxnId(), {log}).response();\n } \n\n setSecretFetcher(secretFetcher: SecretFetcher): void {\n this.secretFetcher = secretFetcher;\n }\n}\n\nclass SecretRequest {\n constructor(private receivedSecretPromise: Promise) {\n }\n\n /**\n * Wait for any of your device to respond to this secret request.\n * If you're going to await this method, make sure you do that within a try catch block.\n * @param timeout The max time (in seconds) that we will wait, after which the promise rejects\n */\n async waitForResponse(timeout: number = 30): Promise {\n const timeoutPromise: Promise = new Promise((_, reject) => {\n setTimeout(reject, timeout * 1000);\n });\n const response = await Promise.race([this.receivedSecretPromise, timeoutPromise]);\n return response.event.content.secret;\n }\n}\n\n\n/**\n * The idea is to encrypt the secret with AES before persisting to storage.\n * The AES key is also in storage so this isn't really that much more secure.\n * But it's a tiny bit better than storing the secret in plaintext.\n */\n// todo: We could also encrypt the access-token using AES like element does\nclass AESEncryption {\n private key: JsonWebKey;\n private iv: Uint8Array;\n\n constructor(private storage: Storage, private crypto: Crypto, private encoding: Encoding) { };\n\n async load(): Promise {\n const storageKey = `${SESSION_E2EE_KEY_PREFIX}localAESKey`;\n // 1. Check if we're already storing the AES key\n const txn = await this.storage.readTxn([StoreNames.session]);\n let { key, iv } = await txn.session.get(storageKey) ?? {};\n\n // 2. If no key, create it and store in session store\n if (!key) {\n /**\n * Element creates the key as \"non-extractable\", meaning that it cannot\n * be exported through the crypto DOM API. But since it's going\n * to end up in indexeddb anyway, it really doesn't matter.\n */\n key = await this.crypto.aes.generateKey(\"jwk\");\n iv = await this.crypto.aes.generateIV();\n const txn = await this.storage.readWriteTxn([StoreNames.session]);\n txn.session.set(storageKey, { key, iv });\n }\n\n // 3. Set props\n this.key = key;\n this.iv = iv;\n }\n\n async encrypt(secret: string): Promise {\n const data = this.encoding.utf8.encode(secret);\n const encrypted = await this.crypto.aes.encryptCTR({\n jwkKey: this.key,\n iv: this.iv,\n data,\n });\n return encrypted;\n }\n\n async decrypt(ciphertext: Uint8Array): Promise {\n const buffer = await this.crypto.aes.decryptCTR({\n jwkKey: this.key,\n iv: this.iv,\n data: ciphertext,\n });\n const secret = this.encoding.utf8.decode(buffer);\n return secret;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {Key} from \"./common\";\nimport type {Platform} from \"../../platform/web/Platform.js\";\nimport type {Transaction} from \"../storage/idb/Transaction\";\nimport type {Storage} from \"../storage/idb/Storage\";\nimport type {AccountDataEntry} from \"../storage/idb/stores/AccountDataStore\";\n\ntype EncryptedData = {\n iv: string;\n ciphertext: string;\n mac: string;\n}\n\nexport enum DecryptionFailure {\n NotEncryptedWithKey,\n BadMAC,\n UnsupportedAlgorithm,\n}\n\nclass DecryptionError extends Error {\n constructor(msg: string, public readonly reason: DecryptionFailure) {\n super(msg);\n }\n}\n\nexport class SecretStorage {\n private readonly _key: Key;\n private readonly _platform: Platform;\n private readonly _storage: Storage;\n\n constructor({key, platform, storage}: {key: Key, platform: Platform, storage: Storage}) {\n this._key = key;\n this._platform = platform;\n this._storage = storage;\n }\n\n /** this method will auto-commit any indexeddb transaction because of its use of the webcrypto api */\n async hasValidKeyForAnyAccountData() {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.accountData,\n ]);\n const allAccountData = await txn.accountData.getAll();\n for (const accountData of allAccountData) {\n try {\n const secret = await this._decryptAccountData(accountData);\n return true; // decryption succeeded\n } catch (err) {\n if (err instanceof DecryptionError && err.reason !== DecryptionFailure.NotEncryptedWithKey) {\n throw err;\n } else {\n continue;\n }\n }\n }\n return false;\n }\n\n /** this method will auto-commit any indexeddb transaction because of its use of the webcrypto api */\n async readSecret(name: string): Promise {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.accountData,\n ]);\n const accountData = await txn.accountData.get(name);\n if (!accountData) {\n return;\n }\n return await this._decryptAccountData(accountData);\n }\n\n async _decryptAccountData(accountData: AccountDataEntry): Promise {\n const encryptedData = accountData?.content?.encrypted?.[this._key.id] as EncryptedData;\n if (!encryptedData) {\n throw new DecryptionError(`Secret ${accountData.type} is not encrypted for key ${this._key.id}`, DecryptionFailure.NotEncryptedWithKey);\n }\n\n if (this._key.algorithm === \"m.secret_storage.v1.aes-hmac-sha2\") {\n return await this._decryptAESSecret(accountData.type, encryptedData);\n } else {\n throw new DecryptionError(`Unsupported algorithm for key ${this._key.id}: ${this._key.algorithm}`, DecryptionFailure.UnsupportedAlgorithm);\n }\n }\n\n async _decryptAESSecret(type: string, encryptedData: EncryptedData): Promise {\n const {base64, utf8} = this._platform.encoding;\n // now derive the aes and mac key from the 4s key\n const hkdfKey = await this._platform.crypto.derive.hkdf(\n this._key.binaryKey,\n new Uint8Array(8).buffer, //zero salt\n utf8.encode(type), // info\n \"SHA-256\",\n 512 // 512 bits or 64 bytes\n );\n const aesKey = hkdfKey.slice(0, 32);\n const hmacKey = hkdfKey.slice(32);\n const ciphertextBytes = base64.decode(encryptedData.ciphertext);\n\n const isVerified = await this._platform.crypto.hmac.verify(\n hmacKey, base64.decode(encryptedData.mac),\n ciphertextBytes, \"SHA-256\");\n\n if (!isVerified) {\n throw new DecryptionError(\"Bad MAC\", DecryptionFailure.BadMAC);\n }\n\n const plaintextBytes = await this._platform.crypto.aes.decryptCTR({\n key: aesKey,\n iv: base64.decode(encryptedData.iv),\n data: ciphertextBytes\n });\n\n return utf8.decode(plaintextBytes);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {KeyDescription, Key} from \"./common\";\nimport {keyFromPassphrase} from \"./passphrase\";\nimport {keyFromRecoveryKey} from \"./recoveryKey\";\nimport {SESSION_E2EE_KEY_PREFIX} from \"../e2ee/common\";\nimport type {Storage} from \"../storage/idb/Storage\";\nimport type {Transaction} from \"../storage/idb/Transaction\";\nimport type {KeyDescriptionData} from \"./common\";\nimport type {Platform} from \"../../platform/web/Platform.js\";\nimport type * as OlmNamespace from \"@matrix-org/olm\"\n\n// Add exports for other classes\nexport {SecretFetcher} from \"./SecretFetcher\";\nexport {SecretSharing} from \"./SecretSharing\";\nexport {SecretStorage} from \"./SecretStorage\";\n\ntype Olm = typeof OlmNamespace;\n\nconst SSSS_KEY = `${SESSION_E2EE_KEY_PREFIX}ssssKey`;\nconst BACKUPVERSION_KEY = `${SESSION_E2EE_KEY_PREFIX}keyBackupVersion`;\n\nexport enum KeyType {\n \"RecoveryKey\",\n \"Passphrase\"\n}\n\nasync function readDefaultKeyDescription(storage: Storage): Promise {\n const txn = await storage.readTxn([\n storage.storeNames.accountData\n ]);\n const defaultKeyEvent = await txn.accountData.get(\"m.secret_storage.default_key\");\n const id = defaultKeyEvent?.content?.key;\n if (!id) {\n return;\n }\n const keyAccountData = await txn.accountData.get(`m.secret_storage.key.${id}`);\n if (!keyAccountData) {\n return;\n }\n return new KeyDescription(id, keyAccountData.content as KeyDescriptionData);\n}\n\nexport async function writeKey(key: Key, keyBackupVersion: number, txn: Transaction): Promise {\n const existingVersion: number | undefined = await txn.session.get(BACKUPVERSION_KEY);\n txn.session.set(BACKUPVERSION_KEY, keyBackupVersion);\n txn.session.set(SSSS_KEY, {id: key.id, binaryKey: key.binaryKey});\n return existingVersion;\n}\n\nexport async function readKey(txn: Transaction): Promise {\n const keyData = await txn.session.get(SSSS_KEY);\n if (!keyData) {\n return;\n }\n const keyAccountData = await txn.accountData.get(`m.secret_storage.key.${keyData.id}`);\n if (keyAccountData) {\n return new Key(new KeyDescription(keyData.id, keyAccountData.content as KeyDescriptionData), keyData.binaryKey);\n }\n}\n\n\nexport async function removeKey(txn: Transaction): Promise {\n txn.session.remove(SSSS_KEY);\n}\n\nexport async function keyFromCredential(type: KeyType, credential: string, storage: Storage, platform: Platform, olm: Olm): Promise {\n const keyDescription = await readDefaultKeyDescription(storage);\n if (!keyDescription) {\n throw new Error(\"Could not find a default secret storage key in account data\");\n }\n return await keyFromCredentialAndDescription(type, credential, keyDescription, platform, olm);\n}\n\nexport async function keyFromCredentialAndDescription(type: KeyType, credential: string, keyDescription: KeyDescription, platform: Platform, olm: Olm): Promise {\n let key: Key;\n if (type === KeyType.Passphrase) {\n key = await keyFromPassphrase(keyDescription, credential, platform);\n } else if (type === KeyType.RecoveryKey) {\n key = keyFromRecoveryKey(keyDescription, credential, olm, platform);\n } else {\n throw new Error(`Invalid type: ${type}`);\n }\n return key;\n}\n\nexport async function keyFromDehydratedDeviceKey(key: Key, storage: Storage, platform: Platform): Promise {\n const keyDescription = await readDefaultKeyDescription(storage);\n if (await keyDescription?.isCompatible(key, platform)) {\n return key.withDescription(keyDescription!);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nconst DEHYDRATION_LIBOLM_PICKLE_ALGORITHM = \"org.matrix.msc2697.v1.olm.libolm_pickle\"; \nimport {KeyDescription} from \"../ssss/common\";\nimport {keyFromCredentialAndDescription} from \"../ssss/index\";\n\nexport async function getDehydratedDevice(hsApi, olm, platform, log) {\n try {\n const response = await hsApi.getDehydratedDevice({log}).response();\n if (response.device_data.algorithm === DEHYDRATION_LIBOLM_PICKLE_ALGORITHM) {\n return new EncryptedDehydratedDevice(response, olm, platform);\n }\n } catch (err) {\n if (err.name !== \"HomeServerError\") {\n log.error = err;\n }\n return undefined;\n }\n}\n\nexport async function uploadAccountAsDehydratedDevice(account, hsApi, key, deviceDisplayName, log) {\n const response = await hsApi.createDehydratedDevice({\n device_data: {\n algorithm: DEHYDRATION_LIBOLM_PICKLE_ALGORITHM,\n account: account.pickleWithKey(key.binaryKey.slice()),\n passphrase: key.description?.passphraseParams || {},\n },\n initial_device_display_name: deviceDisplayName\n }).response();\n const deviceId = response.device_id;\n account.setDeviceId(deviceId);\n await account.uploadKeys(undefined, true, log);\n return deviceId;\n}\n\nclass EncryptedDehydratedDevice {\n constructor(dehydratedDevice, olm, platform) {\n this._dehydratedDevice = dehydratedDevice;\n this._olm = olm;\n this._platform = platform;\n }\n\n async decrypt(keyType, credential) {\n const keyDescription = new KeyDescription(\"dehydrated_device\", this._dehydratedDevice.device_data.passphrase);\n const key = await keyFromCredentialAndDescription(keyType, credential, keyDescription, this._platform, this._olm);\n const account = new this._olm.Account();\n try {\n const pickledAccount = this._dehydratedDevice.device_data.account;\n account.unpickle(key.binaryKey.slice(), pickledAccount);\n return new DehydratedDevice(this._dehydratedDevice, account, key);\n } catch (err) {\n account.free();\n if (err.message === \"OLM.BAD_ACCOUNT_KEY\") {\n return undefined;\n } else {\n throw err;\n }\n }\n }\n\n get deviceId() {\n return this._dehydratedDevice.device_id;\n }\n}\n\nclass DehydratedDevice {\n constructor(dehydratedDevice, account, key) {\n this._dehydratedDevice = dehydratedDevice;\n this._account = account;\n this._key = key;\n }\n\n async claim(hsApi, log) {\n try {\n const response = await hsApi.claimDehydratedDevice(this.deviceId, {log}).response();\n return response.success;\n } catch (err) {\n return false;\n }\n }\n\n // make it clear that ownership is transfered upon calling this\n adoptUnpickledOlmAccount() {\n const account = this._account;\n this._account = undefined;\n return account;\n }\n\n get deviceId() {\n return this._dehydratedDevice.device_id;\n }\n\n get key() {\n return this._key;\n }\n\n dispose() {\n this._account?.free();\n this._account = undefined;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport interface ILock {\n release(): void;\n}\n\nexport class Lock implements ILock {\n private _promise?: Promise;\n private _resolve?: (() => void);\n\n tryTake(): boolean {\n if (!this._promise) {\n this._promise = new Promise(resolve => {\n this._resolve = resolve;\n });\n return true;\n }\n return false;\n }\n\n async take(): Promise {\n while(!this.tryTake()) {\n await this.released();\n }\n }\n\n get isTaken(): boolean {\n return !!this._promise;\n }\n\n release(): void {\n if (this._resolve) {\n this._promise = undefined;\n const resolve = this._resolve;\n this._resolve = undefined;\n resolve();\n }\n }\n\n released(): Promise | undefined {\n return this._promise;\n }\n}\n\nexport class MultiLock implements ILock {\n\n constructor(public readonly locks: Lock[]) {\n }\n\n release(): void {\n for (const lock of this.locks) {\n lock.release();\n }\n }\n}\n\nexport function tests() {\n return {\n \"taking a lock twice returns false\": assert => {\n const lock = new Lock();\n assert.equal(lock.tryTake(), true);\n assert.equal(lock.isTaken, true);\n assert.equal(lock.tryTake(), false);\n },\n \"can take a released lock again\": assert => {\n const lock = new Lock();\n lock.tryTake();\n lock.release();\n assert.equal(lock.isTaken, false);\n assert.equal(lock.tryTake(), true);\n },\n \"2 waiting for lock, only first one gets it\": async assert => {\n const lock = new Lock();\n lock.tryTake();\n\n let first;\n lock.released()!.then(() => first = lock.tryTake());\n let second;\n lock.released()!.then(() => second = lock.tryTake());\n const promise = lock.released();\n lock.release();\n await promise;\n assert.strictEqual(first, true);\n assert.strictEqual(second, false);\n },\n \"await non-taken lock\": async assert => {\n const lock = new Lock();\n await lock.released();\n assert(true);\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {OlmSessionEntry} from \"../../storage/idb/stores/OlmSessionStore\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nexport function createSessionEntry(olmSession: Olm.Session, senderKey: string, timestamp: number, pickleKey: string): OlmSessionEntry {\n return {\n session: olmSession.pickle(pickleKey),\n sessionId: olmSession.session_id(),\n senderKey,\n lastUsed: timestamp,\n };\n}\n\nexport class Session {\n public isModified: boolean;\n\n constructor(\n public readonly data: OlmSessionEntry,\n private readonly pickleKey: string,\n private readonly olm: Olm,\n public isNew: boolean = false\n ) {\n this.isModified = isNew;\n }\n\n static create(senderKey: string, olmSession: Olm.Session, olm: Olm, pickleKey: string, timestamp: number): Session {\n const data = createSessionEntry(olmSession, senderKey, timestamp, pickleKey);\n return new Session(data, pickleKey, olm, true);\n }\n\n get id(): string {\n return this.data.sessionId;\n }\n\n load(): Olm.Session {\n const session = new this.olm.Session();\n session.unpickle(this.pickleKey, this.data.session);\n return session;\n }\n\n unload(olmSession: Olm.Session): void {\n olmSession.free();\n }\n\n save(olmSession: Olm.Session): void {\n this.data.session = olmSession.pickle(this.pickleKey);\n this.isModified = true;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n\n/**\n * @property {object} event the plaintext event (type and content property)\n * @property {string} senderCurve25519Key the curve25519 sender key of the olm event\n * @property {string} claimedEd25519Key The ed25519 fingerprint key retrieved from the decryption payload.\n * The sender of the olm event claims this is the ed25519 fingerprint key\n * that matches the curve25519 sender key.\n * The caller needs to check if this key does indeed match the senderKey\n * for a device with a valid signature returned from /keys/query,\n * see DeviceTracker\n */\n\nimport {getDeviceEd25519Key} from \"./common\";\nimport type {DeviceKey} from \"./common\";\nimport type {TimelineEvent} from \"../storage/types\";\n\ntype DecryptedEvent = {\n type?: string,\n content?: Record\n}\n\nexport class DecryptionResult {\n public device?: DeviceKey;\n\n constructor(\n public readonly event: DecryptedEvent,\n public readonly senderCurve25519Key: string,\n public readonly claimedEd25519Key: string,\n public readonly encryptedEvent?: TimelineEvent\n ) {}\n\n setDevice(device: DeviceKey): void {\n this.device = device;\n }\n\n get isVerified(): boolean {\n if (this.device) {\n const comesFromDevice = getDeviceEd25519Key(this.device) === this.claimedEd25519Key;\n return comesFromDevice;\n }\n return false;\n }\n\n get isUnverified(): boolean {\n if (this.device) {\n return !this.isVerified;\n } else {\n return true;\n }\n }\n\n get userId(): string | undefined {\n return this.device?.user_id;\n }\n\n get deviceId(): string | undefined {\n return this.device?.device_id;\n }\n\n get isVerificationUnknown(): boolean {\n return !this.device;\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {OLM_ALGORITHM} from \"../common\";\n\nexport const enum OlmPayloadType {\n PreKey = 0,\n Normal = 1\n}\n\nexport type OlmMessage = {\n type?: OlmPayloadType,\n body?: string\n}\n\nexport type OlmEncryptedMessageContent = {\n algorithm?: typeof OLM_ALGORITHM\n sender_key?: string,\n ciphertext?: {\n [deviceCurve25519Key: string]: OlmMessage\n }\n}\n\nexport type OlmEncryptedEvent = {\n type?: \"m.room.encrypted\",\n content?: OlmEncryptedMessageContent\n sender?: string\n}\n\nexport type OlmPayload = {\n type?: string;\n content?: Record;\n sender?: string;\n recipient?: string;\n recipient_keys?: {ed25519?: string};\n keys?: {ed25519?: string};\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {DecryptionError} from \"../common\";\nimport {groupBy} from \"../../../utils/groupBy\";\nimport {MultiLock, ILock} from \"../../../utils/Lock\";\nimport {Session} from \"./Session\";\nimport {DecryptionResult} from \"../DecryptionResult\";\nimport {OlmPayloadType} from \"./types\";\n\nimport type {OlmMessage, OlmPayload} from \"./types\";\nimport type {Account} from \"../Account\";\nimport type {LockMap} from \"../../../utils/LockMap\";\nimport type {Transaction} from \"../../storage/idb/Transaction\";\nimport type {OlmEncryptedEvent} from \"./types\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nconst SESSION_LIMIT_PER_SENDER_KEY = 4;\n\ntype DecryptionResults = {\n results: DecryptionResult[],\n errors: DecryptionError[],\n senderKeyDecryption: SenderKeyDecryption\n};\n\ntype CreateAndDecryptResult = {\n session: Session,\n plaintext: string\n};\n\nfunction sortSessions(sessions: Session[]): void {\n sessions.sort((a, b) => {\n return b.data.lastUsed - a.data.lastUsed;\n });\n}\n\nexport class Decryption {\n constructor(\n private readonly account: Account,\n private readonly pickleKey: string,\n private readonly now: () => number,\n private readonly ownUserId: string,\n private readonly olm: Olm,\n private readonly senderKeyLock: LockMap\n ) {}\n \n // we need to lock because both encryption and decryption can't be done in one txn,\n // so for them not to step on each other toes, we need to lock.\n // \n // the lock is release from 1 of 3 places, whichever comes first:\n // - decryptAll below fails (to release the lock as early as we can)\n // - DecryptionChanges.write succeeds\n // - Sync finishes the writeSync phase (or an error was thrown, in case we never get to DecryptionChanges.write) \n async obtainDecryptionLock(events: OlmEncryptedEvent[]): Promise {\n const senderKeys = new Set();\n for (const event of events) {\n const senderKey = event.content?.[\"sender_key\"];\n if (senderKey) {\n senderKeys.add(senderKey);\n }\n }\n // take a lock on all senderKeys so encryption or other calls to decryptAll (should not happen)\n // don't modify the sessions at the same time\n const locks = await Promise.all(Array.from(senderKeys).map(senderKey => {\n return this.senderKeyLock.takeLock(senderKey);\n }));\n return new MultiLock(locks);\n }\n\n // we need decryptAll because there is some parallelization we can do for decrypting different sender keys at once\n // but for the same sender key we need to do one by one\n // \n // also we want to store the room key, etc ... in the same txn as we remove the pending encrypted event\n // \n // so we need to decrypt events in a batch (so we can decide which ones can run in parallel and which one one by one)\n // and also can avoid side-effects before all can be stored this way\n // \n // doing it one by one would be possible, but we would lose the opportunity for parallelization\n // \n \n /**\n * It is importants the lock obtained from obtainDecryptionLock is for the same set of events as passed in here.\n * [decryptAll description]\n * @param {[type]} events\n * @return {Promise} [description]\n */\n async decryptAll(events: OlmEncryptedEvent[], lock: ILock, txn: Transaction): Promise {\n try {\n const eventsPerSenderKey = groupBy(events, (event: OlmEncryptedEvent) => event.content?.[\"sender_key\"]);\n const timestamp = this.now();\n // decrypt events for different sender keys in parallel\n const senderKeyOperations = await Promise.all(Array.from(eventsPerSenderKey.entries()).map(([senderKey, events]) => {\n return this._decryptAllForSenderKey(senderKey!, events, timestamp, txn);\n }));\n const results = senderKeyOperations.reduce((all, r) => all.concat(r.results), [] as DecryptionResult[]);\n const errors = senderKeyOperations.reduce((all, r) => all.concat(r.errors), [] as DecryptionError[]);\n const senderKeyDecryptions = senderKeyOperations.map(r => r.senderKeyDecryption);\n return new DecryptionChanges(senderKeyDecryptions, results, errors, this.account, lock);\n } catch (err) {\n // make sure the locks are release if something throws\n // otherwise they will be released in DecryptionChanges after having written\n // or after the writeSync phase in Sync\n lock.release();\n throw err;\n }\n }\n\n async _decryptAllForSenderKey(senderKey: string, events: OlmEncryptedEvent[], timestamp: number, readSessionsTxn: Transaction): Promise {\n const sessions = await this._getSessions(senderKey, readSessionsTxn);\n const senderKeyDecryption = new SenderKeyDecryption(senderKey, sessions, timestamp);\n const results: DecryptionResult[] = [];\n const errors: DecryptionError[] = [];\n // events for a single senderKey need to be decrypted one by one\n for (const event of events) {\n try {\n const result = this._decryptForSenderKey(senderKeyDecryption, event, timestamp);\n results.push(result);\n } catch (err) {\n errors.push(err);\n }\n }\n return {results, errors, senderKeyDecryption};\n }\n\n _decryptForSenderKey(senderKeyDecryption: SenderKeyDecryption, event: OlmEncryptedEvent, timestamp: number): DecryptionResult {\n const senderKey = senderKeyDecryption.senderKey;\n const message = this._getMessageAndValidateEvent(event);\n let plaintext: string | undefined;\n try {\n plaintext = senderKeyDecryption.decrypt(message);\n } catch (err) {\n // TODO: is it ok that an error on one session prevents other sessions from being attempted?\n throw new DecryptionError(\"OLM_BAD_ENCRYPTED_MESSAGE\", event, {senderKey, error: err.message});\n }\n // could not decrypt with any existing session\n if (typeof plaintext !== \"string\" && message.type === OlmPayloadType.PreKey) {\n let createResult: CreateAndDecryptResult;\n try {\n createResult = this._createSessionAndDecrypt(senderKey, message, timestamp);\n } catch (error) {\n throw new DecryptionError(`Could not create inbound olm session: ${error.message}`, event, {senderKey, error});\n }\n senderKeyDecryption.addNewSession(createResult.session);\n plaintext = createResult.plaintext;\n }\n if (typeof plaintext === \"string\") {\n let payload: OlmPayload;\n try {\n payload = JSON.parse(plaintext);\n } catch (error) {\n throw new DecryptionError(\"PLAINTEXT_NOT_JSON\", event, {plaintext, error});\n }\n this._validatePayload(payload, event);\n return new DecryptionResult(payload, senderKey, payload.keys!.ed25519!);\n } else {\n throw new DecryptionError(\"OLM_NO_MATCHING_SESSION\", event,\n {knownSessionIds: senderKeyDecryption.sessions.map(s => s.id)});\n }\n }\n\n // only for pre-key messages after having attempted decryption with existing sessions\n _createSessionAndDecrypt(senderKey: string, message: OlmMessage, timestamp: number): CreateAndDecryptResult {\n let plaintext;\n // if we have multiple messages encrypted with the same new session,\n // this could create multiple sessions as the OTK isn't removed yet\n // (this only happens in DecryptionChanges.write)\n // This should be ok though as we'll first try to decrypt with the new session\n const olmSession = this.account.createInboundOlmSession(senderKey, message.body);\n try {\n plaintext = olmSession.decrypt(message.type, message.body);\n const session = Session.create(senderKey, olmSession, this.olm, this.pickleKey, timestamp);\n session.unload(olmSession);\n return {session, plaintext};\n } catch (err) {\n olmSession.free();\n throw err;\n }\n }\n\n _getMessageAndValidateEvent(event: OlmEncryptedEvent): OlmMessage {\n const ciphertext = event.content?.ciphertext;\n if (!ciphertext) {\n throw new DecryptionError(\"OLM_MISSING_CIPHERTEXT\", event);\n }\n const message = ciphertext?.[this.account.identityKeys.curve25519];\n if (!message) {\n throw new DecryptionError(\"OLM_NOT_INCLUDED_IN_RECIPIENTS\", event);\n }\n\n return message;\n }\n\n async _getSessions(senderKey: string, txn: Transaction): Promise {\n const sessionEntries = await txn.olmSessions.getAll(senderKey);\n // sort most recent used sessions first\n const sessions = sessionEntries.map(s => new Session(s, this.pickleKey, this.olm));\n sortSessions(sessions);\n return sessions;\n }\n\n _validatePayload(payload: OlmPayload, event: OlmEncryptedEvent): void {\n if (payload.sender !== event.sender) {\n throw new DecryptionError(\"OLM_FORWARDED_MESSAGE\", event, {sentBy: event.sender, encryptedBy: payload.sender});\n }\n if (payload.recipient !== this.ownUserId) {\n throw new DecryptionError(\"OLM_BAD_RECIPIENT\", event, {recipient: payload.recipient});\n }\n if (payload.recipient_keys?.ed25519 !== this.account.identityKeys.ed25519) {\n throw new DecryptionError(\"OLM_BAD_RECIPIENT_KEY\", event, {key: payload.recipient_keys?.ed25519});\n }\n // TODO: check room_id\n if (!payload.type) {\n throw new DecryptionError(\"missing type on payload\", event, {payload});\n }\n if (typeof payload.keys?.ed25519 !== \"string\") {\n throw new DecryptionError(\"Missing or invalid claimed ed25519 key on payload\", event, {payload});\n }\n }\n}\n\n// decryption helper for a single senderKey\nclass SenderKeyDecryption {\n constructor(\n public readonly senderKey: string,\n public readonly sessions: Session[],\n private readonly timestamp: number\n ) {}\n\n addNewSession(session: Session): void {\n // add at top as it is most recent\n this.sessions.unshift(session);\n }\n\n decrypt(message: OlmMessage): string | undefined {\n for (const session of this.sessions) {\n const plaintext = this.decryptWithSession(session, message);\n if (typeof plaintext === \"string\") {\n // keep them sorted so will try the same session first for other messages\n // and so we can assume the excess ones are at the end\n // if they grow too large\n sortSessions(this.sessions);\n return plaintext;\n }\n }\n }\n\n getModifiedSessions(): Session[] {\n return this.sessions.filter(session => session.isModified);\n }\n\n get hasNewSessions(): boolean {\n return this.sessions.some(session => session.isNew);\n }\n\n // this could internally dispatch to a web-worker\n // and is why we unpickle/pickle on each iteration\n // if this turns out to be a real cost for IE11,\n // we could look into adding a less expensive serialization mechanism\n // for olm sessions to libolm\n private decryptWithSession(session: Session, message: OlmMessage): string | undefined {\n if (message.type === undefined || message.body === undefined) {\n throw new Error(\"Invalid message without type or body\");\n }\n const olmSession = session.load();\n try {\n if (message.type === OlmPayloadType.PreKey && !olmSession.matches_inbound(message.body)) {\n return;\n }\n try {\n const plaintext = olmSession.decrypt(message.type as number, message.body!);\n session.save(olmSession);\n session.data.lastUsed = this.timestamp;\n return plaintext;\n } catch (err) {\n if (message.type === OlmPayloadType.PreKey) {\n throw new Error(`Error decrypting prekey message with existing session id ${session.id}: ${err.message}`);\n }\n // decryption failed, bail out\n return;\n }\n } finally {\n session.unload(olmSession);\n }\n }\n}\n\n/**\n * @property {Array} results\n * @property {Array} errors see DecryptionError.event to retrieve the event that failed to decrypt.\n */\nclass DecryptionChanges {\n constructor(\n private readonly senderKeyDecryptions: SenderKeyDecryption[],\n public readonly results: DecryptionResult[],\n public readonly errors: DecryptionError[],\n private readonly account: Account,\n private readonly lock: ILock\n ) {}\n\n get hasNewSessions(): boolean {\n return this.senderKeyDecryptions.some(skd => skd.hasNewSessions);\n }\n\n write(txn: Transaction): void {\n try {\n for (const senderKeyDecryption of this.senderKeyDecryptions) {\n for (const session of senderKeyDecryption.getModifiedSessions()) {\n txn.olmSessions.set(session.data);\n if (session.isNew) {\n const olmSession = session.load();\n try {\n this.account.writeRemoveOneTimeKey(olmSession, txn);\n } finally {\n session.unload(olmSession);\n }\n }\n }\n if (senderKeyDecryption.sessions.length > SESSION_LIMIT_PER_SENDER_KEY) {\n const {senderKey, sessions} = senderKeyDecryption;\n // >= because index is zero-based\n for (let i = sessions.length - 1; i >= SESSION_LIMIT_PER_SENDER_KEY ; i -= 1) {\n const session = sessions[i];\n txn.olmSessions.remove(senderKey, session.id);\n }\n }\n }\n } finally {\n this.lock.release();\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {groupByWithCreator} from \"../../../utils/groupBy\";\nimport {verifyEd25519Signature, OLM_ALGORITHM, getDeviceCurve25519Key, getDeviceEd25519Key, SignatureVerification} from \"../common\";\nimport {createSessionEntry} from \"./Session\";\n\nimport type {OlmMessage, OlmPayload, OlmEncryptedMessageContent} from \"./types\";\nimport type {Account} from \"../Account\";\nimport type {LockMap} from \"../../../utils/LockMap\";\nimport {Lock, MultiLock, ILock} from \"../../../utils/Lock\";\nimport type {Storage} from \"../../storage/idb/Storage\";\nimport type {Transaction} from \"../../storage/idb/Transaction\";\nimport type {DeviceKey} from \"../common\";\nimport type {HomeServerApi} from \"../../net/HomeServerApi\";\nimport type {ILogItem} from \"../../../logging/types\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\ntype ClaimedOTKResponse = {\n [userId: string]: {\n [deviceId: string]: {\n [algorithmAndOtk: string]: {\n key: string,\n signatures: {\n [userId: string]: {\n [algorithmAndDevice: string]: string\n }\n }\n }\n }\n }\n};\n\nfunction findFirstSessionId(sessionIds) {\n return sessionIds.reduce((first, sessionId) => {\n if (!first || sessionId < first) {\n return sessionId;\n } else {\n return first;\n }\n }, null);\n}\n\nconst OTK_ALGORITHM = \"signed_curve25519\";\n// only encrypt this amount of olm messages at once otherwise we run out of wasm memory\n// with all the sessions loaded at the same time\n// See https://github.com/vector-im/hydrogen-web/issues/150 as well, which indicates the limit is 44,\n// but let's take a conservative limit as the megolm session cache also takes space\nconst MAX_BATCH_SIZE = 20;\n\nexport class Encryption {\n \n private _batchLocks: Array;\n\n constructor(\n private readonly account: Account,\n private readonly pickleKey: string,\n private readonly olm: Olm,\n private readonly storage: Storage,\n private readonly now: () => number,\n private readonly ownUserId: string,\n private readonly olmUtil: Olm.Utility,\n private readonly senderKeyLock: LockMap\n ) {\n this._batchLocks = new Array(MAX_BATCH_SIZE);\n for (let i = 0; i < MAX_BATCH_SIZE; i += 1) {\n this._batchLocks[i] = new Lock();\n }\n }\n\n /** A hack to prevent olm OOMing when `encrypt` is called several times concurrently,\n * which is the case when encrypting voip signalling message to send over to_device.\n * A better fix will be to extract the common bits from megolm/KeyLoader in a super class\n * and have some sort of olm/SessionLoader that is shared between encryption and decryption\n * and only keeps the olm session in wasm memory for a brief moment, like we already do for RoomKeys,\n * and get the benefit of an optimal cache at the same time.\n * */\n private async _takeBatchLock(amount: number): Promise {\n const locks = this._batchLocks.filter(l => !l.isTaken).slice(0, amount);\n if (locks.length < amount) {\n const takenLocks = this._batchLocks.filter(l => l.isTaken).slice(0, amount - locks.length);\n locks.push(...takenLocks);\n }\n await Promise.all(locks.map(l => l.take()));\n return new MultiLock(locks);\n }\n\n async encrypt(type: string, content: Record, devices: DeviceKey[], hsApi: HomeServerApi, log: ILogItem): Promise {\n let messages: EncryptedMessage[] = [];\n for (let i = 0; i < devices.length ; i += MAX_BATCH_SIZE) {\n const batchDevices = devices.slice(i, i + MAX_BATCH_SIZE);\n const batchLock = await this._takeBatchLock(batchDevices.length);\n try {\n const batchMessages = await this._encryptForMaxDevices(type, content, batchDevices, hsApi, log);\n messages = messages.concat(batchMessages);\n }\n finally {\n batchLock.release();\n }\n }\n return messages;\n }\n\n async _encryptForMaxDevices(type: string, content: Record, devices: DeviceKey[], hsApi: HomeServerApi, log: ILogItem): Promise {\n // TODO: see if we can only hold some of the locks until after the /keys/claim call (if needed) \n // take a lock on all senderKeys so decryption and other calls to encrypt (should not happen)\n // don't modify the sessions at the same time\n const locks = await Promise.all(devices.map(device => {\n return this.senderKeyLock.takeLock(getDeviceCurve25519Key(device));\n }));\n try {\n const {\n devicesWithoutSession,\n existingEncryptionTargets,\n } = await this._findExistingSessions(devices);\n \n const timestamp = this.now(); \n\n let encryptionTargets: EncryptionTarget[] = [];\n try {\n if (devicesWithoutSession.length) {\n const newEncryptionTargets = await log.wrap(\"create sessions\", log => this._createNewSessions(\n devicesWithoutSession, hsApi, timestamp, log));\n encryptionTargets = encryptionTargets.concat(newEncryptionTargets);\n }\n await this._loadSessions(existingEncryptionTargets);\n encryptionTargets = encryptionTargets.concat(existingEncryptionTargets);\n const encryptLog = {l: \"encrypt\", targets: encryptionTargets.length};\n const messages = log.wrap(encryptLog, () => encryptionTargets.map(target => {\n const encryptedContent = this._encryptForDevice(type, content, target);\n return new EncryptedMessage(encryptedContent, target.device);\n }));\n await this._storeSessions(encryptionTargets, timestamp);\n return messages;\n } finally {\n for (const target of encryptionTargets) {\n target.dispose();\n }\n }\n } finally {\n for (const lock of locks) {\n lock.release();\n }\n }\n }\n\n async _findExistingSessions(devices: DeviceKey[]): Promise<{devicesWithoutSession: DeviceKey[], existingEncryptionTargets: EncryptionTarget[]}> {\n const txn = await this.storage.readTxn([this.storage.storeNames.olmSessions]);\n const sessionIdsForDevice = await Promise.all(devices.map(async device => {\n return await txn.olmSessions.getSessionIds(getDeviceCurve25519Key(device));\n }));\n const devicesWithoutSession = devices.filter((_, i) => {\n const sessionIds = sessionIdsForDevice[i];\n return !(sessionIds?.length);\n });\n\n const existingEncryptionTargets = devices.map((device, i) => {\n const sessionIds = sessionIdsForDevice[i];\n if (sessionIds?.length > 0) {\n const sessionId = findFirstSessionId(sessionIds);\n return EncryptionTarget.fromSessionId(device, sessionId);\n }\n }).filter(target => !!target) as EncryptionTarget[];\n\n return {devicesWithoutSession, existingEncryptionTargets};\n }\n\n _encryptForDevice(type: string, content: Record, target: EncryptionTarget): OlmEncryptedMessageContent {\n const {session, device} = target;\n const plaintext = JSON.stringify(this._buildPlainTextMessageForDevice(type, content, device));\n const message = session!.encrypt(plaintext);\n const encryptedContent = {\n algorithm: OLM_ALGORITHM as typeof OLM_ALGORITHM,\n sender_key: this.account.identityKeys.curve25519,\n ciphertext: {\n [getDeviceCurve25519Key(device)]: message\n }\n };\n return encryptedContent;\n }\n\n _buildPlainTextMessageForDevice(type: string, content: Record, device: DeviceKey): OlmPayload {\n return {\n keys: {\n \"ed25519\": this.account.identityKeys.ed25519\n },\n recipient_keys: {\n \"ed25519\": getDeviceEd25519Key(device)\n },\n recipient: device.user_id,\n sender: this.ownUserId,\n content,\n type\n }\n }\n\n async _createNewSessions(devicesWithoutSession: DeviceKey[], hsApi: HomeServerApi, timestamp: number, log: ILogItem): Promise {\n const newEncryptionTargets = await log.wrap(\"claim\", log => this._claimOneTimeKeys(hsApi, devicesWithoutSession, log));\n try {\n for (const target of newEncryptionTargets) {\n const {device, oneTimeKey} = target;\n target.session = await this.account.createOutboundOlmSession(getDeviceCurve25519Key(device), oneTimeKey);\n }\n await this._storeSessions(newEncryptionTargets, timestamp);\n } catch (err) {\n for (const target of newEncryptionTargets) {\n target.dispose();\n }\n throw err;\n }\n return newEncryptionTargets;\n }\n\n async _claimOneTimeKeys(hsApi: HomeServerApi, deviceIdentities: DeviceKey[], log: ILogItem): Promise {\n // create a Map>\n const devicesByUser = groupByWithCreator(deviceIdentities,\n (device: DeviceKey) => device.user_id,\n (): Map => new Map(),\n (deviceMap: Map, device: DeviceKey) => deviceMap.set(device.device_id, device)\n );\n const oneTimeKeys = Array.from(devicesByUser.entries()).reduce((usersObj, [userId, deviceMap]) => {\n usersObj[userId] = Array.from(deviceMap.values()).reduce((devicesObj, device) => {\n devicesObj[device.device_id] = OTK_ALGORITHM;\n return devicesObj;\n }, {});\n return usersObj;\n }, {});\n const claimResponse = await hsApi.claimKeys({\n timeout: 10000,\n one_time_keys: oneTimeKeys\n }, {log}).response();\n if (Object.keys(claimResponse.failures).length) {\n log.log({l: \"failures\", servers: Object.keys(claimResponse.failures)}, log.level.Warn);\n }\n const userKeyMap = claimResponse?.[\"one_time_keys\"] as ClaimedOTKResponse;\n return this._verifyAndCreateOTKTargets(userKeyMap, devicesByUser, log);\n }\n\n _verifyAndCreateOTKTargets(userKeyMap: ClaimedOTKResponse, devicesByUser: Map>, log: ILogItem): EncryptionTarget[] {\n const verifiedEncryptionTargets: EncryptionTarget[] = [];\n for (const [userId, userSection] of Object.entries(userKeyMap)) {\n for (const [deviceId, deviceSection] of Object.entries(userSection)) {\n const [firstPropName, keySection] = Object.entries(deviceSection)[0];\n const [keyAlgorithm] = firstPropName.split(\":\");\n if (keyAlgorithm === OTK_ALGORITHM) {\n const device = devicesByUser.get(userId)?.get(deviceId);\n if (device) {\n const isValidSignature = verifyEd25519Signature(\n this.olmUtil, userId, deviceId, getDeviceEd25519Key(device), keySection, log) === SignatureVerification.Valid;\n if (isValidSignature) {\n const target = EncryptionTarget.fromOTK(device, keySection.key);\n verifiedEncryptionTargets.push(target);\n }\n }\n }\n } \n }\n return verifiedEncryptionTargets;\n }\n\n async _loadSessions(encryptionTargets: EncryptionTarget[]): Promise {\n const txn = await this.storage.readTxn([this.storage.storeNames.olmSessions]);\n // given we run loading in parallel, there might still be some\n // storage requests that will finish later once one has failed.\n // those should not allocate a session anymore.\n let failed = false;\n try {\n await Promise.all(encryptionTargets.map(async encryptionTarget => {\n const sessionEntry = await txn.olmSessions.get(\n getDeviceCurve25519Key(encryptionTarget.device), encryptionTarget.sessionId!);\n if (sessionEntry && !failed) {\n const olmSession = new this.olm.Session();\n olmSession.unpickle(this.pickleKey, sessionEntry.session);\n encryptionTarget.session = olmSession;\n }\n }));\n } catch (err) {\n failed = true;\n // clean up the sessions that did load\n for (const target of encryptionTargets) {\n target.dispose();\n }\n throw err;\n }\n }\n\n async _storeSessions(encryptionTargets: EncryptionTarget[], timestamp: number): Promise {\n const txn = await this.storage.readWriteTxn([this.storage.storeNames.olmSessions]);\n try {\n for (const target of encryptionTargets) {\n const sessionEntry = createSessionEntry(\n target.session!, getDeviceCurve25519Key(target.device), timestamp, this.pickleKey);\n txn.olmSessions.set(sessionEntry);\n }\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n }\n}\n\n// just a container needed to encrypt a message for a recipient device\n// it is constructed with either a oneTimeKey\n// (and later converted to a session) in case of a new session\n// or an existing session\nclass EncryptionTarget {\n \n public session: Olm.Session | null = null;\n\n constructor(\n public readonly device: DeviceKey, \n public readonly oneTimeKey: string | null,\n public readonly sessionId: string | null\n ) {}\n\n static fromOTK(device: DeviceKey, oneTimeKey: string): EncryptionTarget {\n return new EncryptionTarget(device, oneTimeKey, null);\n }\n\n static fromSessionId(device: DeviceKey, sessionId: string): EncryptionTarget {\n return new EncryptionTarget(device, null, sessionId);\n }\n\n dispose(): void {\n if (this.session) {\n this.session.free();\n }\n }\n}\n\nexport class EncryptedMessage {\n constructor(\n public readonly content: OlmEncryptedMessageContent,\n public readonly device: DeviceKey\n ) {}\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {DecryptionError} from \"../../common\";\n\nexport class DecryptionChanges {\n constructor(roomId, results, errors, replayEntries) {\n this._roomId = roomId;\n this._results = results;\n this._errors = errors;\n this._replayEntries = replayEntries;\n }\n\n /**\n * @type MegolmBatchDecryptionResult\n * @property {Map} results a map of event id to decryption result\n * @property {Map} errors event id -> errors\n * \n * Handle replay attack detection, and return result\n * @param {[type]} txn [description]\n * @return {MegolmBatchDecryptionResult}\n */\n async write(txn) {\n await Promise.all(this._replayEntries.map(async replayEntry => {\n try {\n this._handleReplayAttack(this._roomId, replayEntry, txn);\n } catch (err) {\n this._errors.set(replayEntry.eventId, err);\n }\n }));\n return {\n results: this._results,\n errors: this._errors\n };\n }\n\n // need to handle replay attack because\n // if we redecrypted the same message twice and showed it again\n // then it could be a malicious server admin replaying the word “yes”\n // to make you respond to a msg you didn’t say “yes” to, or something\n async _handleReplayAttack(roomId, replayEntry, txn) {\n const {messageIndex, sessionId, eventId, timestamp} = replayEntry;\n const decryption = await txn.groupSessionDecryptions.get(roomId, sessionId, messageIndex);\n\n if (decryption && decryption.eventId !== eventId) {\n // the one with the newest timestamp should be the attack\n const decryptedEventIsBad = decryption.timestamp < timestamp;\n const badEventId = decryptedEventIsBad ? eventId : decryption.eventId;\n // discard result\n this._results.delete(eventId);\n\n throw new DecryptionError(\"MEGOLM_REPLAYED_INDEX\", event, {\n messageIndex,\n badEventId,\n otherEventId: decryption.eventId\n });\n }\n\n if (!decryption) {\n txn.groupSessionDecryptions.set(roomId, sessionId, messageIndex, {\n eventId,\n timestamp\n });\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function mergeMap(src: Map | undefined, dst: Map): void {\n if (src) {\n for (const [key, value] of src.entries()) {\n dst.set(key, value);\n }\n }\n}\n\nexport function tests() {\n return {\n \"mergeMap with src\": assert => {\n const src = new Map();\n src.set(1, \"a\");\n const dst = new Map();\n dst.set(2, \"b\");\n mergeMap(src, dst);\n assert.equal(dst.get(1), \"a\");\n assert.equal(dst.get(2), \"b\");\n assert.equal(src.get(2), null);\n },\n \"mergeMap without src doesn't fail\": () => {\n mergeMap(undefined, new Map());\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {DecryptionChanges} from \"./DecryptionChanges.js\";\nimport {mergeMap} from \"../../../../utils/mergeMap\";\n\n/**\n * Class that contains all the state loaded from storage to decrypt the given events\n */\nexport class DecryptionPreparation {\n constructor(roomId, sessionDecryptions, errors) {\n this._roomId = roomId;\n this._sessionDecryptions = sessionDecryptions;\n this._initialErrors = errors;\n }\n\n async decrypt() {\n try {\n const errors = this._initialErrors;\n const results = new Map();\n const replayEntries = [];\n await Promise.all(this._sessionDecryptions.map(async sessionDecryption => {\n const sessionResult = await sessionDecryption.decryptAll();\n mergeMap(sessionResult.errors, errors);\n mergeMap(sessionResult.results, results);\n replayEntries.push(...sessionResult.replayEntries);\n }));\n return new DecryptionChanges(this._roomId, results, errors, replayEntries);\n } finally {\n this.dispose();\n }\n }\n\n dispose() {\n for (const sd of this._sessionDecryptions) {\n sd.dispose();\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {TimelineEvent} from \"../../../storage/types\";\n\nexport class ReplayDetectionEntry {\n public readonly sessionId: string;\n public readonly messageIndex: number;\n public readonly event: TimelineEvent;\n\n constructor(sessionId: string, messageIndex: number, event: TimelineEvent) {\n this.sessionId = sessionId;\n this.messageIndex = messageIndex;\n this.event = event;\n }\n\n get eventId(): string {\n return this.event.event_id;\n }\n\n get timestamp(): number {\n return this.event.origin_server_ts;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {DecryptionResult} from \"../../DecryptionResult\";\nimport {DecryptionError} from \"../../common\";\nimport {ReplayDetectionEntry} from \"./ReplayDetectionEntry\";\nimport type {RoomKey} from \"./RoomKey\";\nimport type {KeyLoader, OlmDecryptionResult} from \"./KeyLoader\";\nimport type {OlmWorker} from \"../../OlmWorker\";\nimport type {TimelineEvent} from \"../../../storage/types\";\n\ninterface DecryptAllResult {\n readonly results: Map;\n readonly errors?: Map;\n readonly replayEntries: ReplayDetectionEntry[];\n}\n/**\n * Does the actual decryption of all events for a given megolm session in a batch\n */\nexport class SessionDecryption {\n private decryptionRequests?: any[];\n\n constructor(\n private readonly key: RoomKey,\n private readonly events: TimelineEvent[],\n private readonly olmWorker: OlmWorker | undefined,\n private readonly keyLoader: KeyLoader\n ) {\n this.decryptionRequests = olmWorker ? [] : undefined;\n }\n\n async decryptAll(): Promise {\n const replayEntries: ReplayDetectionEntry[] = [];\n const results: Map = new Map();\n let errors: Map | undefined;\n\n await this.keyLoader.useKey(this.key, async session => {\n for (const event of this.events) {\n try {\n const ciphertext = event.content.ciphertext as string;\n let decryptionResult: OlmDecryptionResult | undefined;\n // TODO: pass all cipthertexts in one go to the megolm worker and don't deserialize the key until in the worker?\n if (this.olmWorker) {\n const request = this.olmWorker.megolmDecrypt(session, ciphertext);\n this.decryptionRequests!.push(request);\n decryptionResult = await request.response();\n } else {\n // the return type of Olm.InboundGroupSession::decrypt is likely wrong, message_index is a number and not a string AFAIK\n // getting it fixed upstream but fixing it like this for now.\n decryptionResult = session.decrypt(ciphertext) as unknown as OlmDecryptionResult;\n }\n const {plaintext} = decryptionResult!;\n let payload;\n try {\n payload = JSON.parse(plaintext);\n } catch (err) {\n throw new DecryptionError(\"PLAINTEXT_NOT_JSON\", event, {plaintext, err});\n }\n if (payload.room_id !== this.key.roomId) {\n throw new DecryptionError(\"MEGOLM_WRONG_ROOM\", event,\n {encryptedRoomId: payload.room_id, eventRoomId: this.key.roomId});\n }\n replayEntries.push(new ReplayDetectionEntry(this.key.sessionId, decryptionResult!.message_index, event));\n const result = new DecryptionResult(payload, this.key.senderKey, this.key.claimedEd25519Key, event);\n results.set(event.event_id, result);\n } catch (err) {\n // ignore AbortError from cancelling decryption requests in dispose method\n if (err.name === \"AbortError\") {\n return;\n }\n if (!errors) {\n errors = new Map();\n }\n errors.set(event.event_id, err);\n }\n }\n });\n\n return {results, errors, replayEntries};\n }\n\n dispose() {\n if (this.decryptionRequests) {\n for (const r of this.decryptionRequests) {\n r.abort();\n }\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {groupByWithCreator} from \"../../../../utils/groupBy\";\nimport type {TimelineEvent} from \"../../../storage/types\";\n\nfunction getSenderKey(event: TimelineEvent): string | undefined {\n return event.content?.[\"sender_key\"];\n}\n\nfunction getSessionId(event: TimelineEvent): string | undefined {\n return event.content?.[\"session_id\"];\n}\n\nfunction getCiphertext(event: TimelineEvent): string | undefined {\n return event.content?.ciphertext;\n}\n\nexport function validateEvent(event: TimelineEvent) {\n return typeof getSenderKey(event) === \"string\" &&\n typeof getSessionId(event) === \"string\" &&\n typeof getCiphertext(event) === \"string\";\n}\n\nexport class SessionKeyGroup {\n public readonly events: TimelineEvent[];\n constructor() {\n this.events = [];\n }\n\n get senderKey(): string | undefined {\n return getSenderKey(this.events[0]!);\n }\n\n get sessionId(): string | undefined {\n return getSessionId(this.events[0]!);\n }\n}\n\nexport function groupEventsBySession(events: TimelineEvent[]): Map {\n return groupByWithCreator(events,\n (event: TimelineEvent) => `${getSenderKey(event)}|${getSessionId(event)}`,\n () => new SessionKeyGroup(),\n (group: SessionKeyGroup, event: TimelineEvent) => group.events.push(event)\n );\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BackupStatus, KeySource} from \"../../../storage/idb/stores/InboundGroupSessionStore\";\nimport type {InboundGroupSessionEntry} from \"../../../storage/idb/stores/InboundGroupSessionStore\";\nimport type {Transaction} from \"../../../storage/idb/Transaction\";\nimport type {DecryptionResult} from \"../../DecryptionResult\";\nimport type {KeyLoader} from \"./KeyLoader\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nexport abstract class RoomKey {\n private _isBetter: boolean | undefined;\n\n isForSession(roomId: string, senderKey: string, sessionId: string) {\n return this.roomId === roomId && this.senderKey === senderKey && this.sessionId === sessionId;\n }\n\n abstract get roomId(): string;\n abstract get senderKey(): string;\n abstract get sessionId(): string;\n abstract get claimedEd25519Key(): string;\n abstract get serializationKey(): string;\n abstract get serializationType(): string;\n abstract get eventIds(): string[] | undefined;\n abstract loadInto(session: Olm.InboundGroupSession, pickleKey: string): void;\n /* Whether the key has been checked against storage (or is from storage)\n * to be the better key for a given session. Given that all keys are checked to be better\n * as part of writing, we can trust that when this returns true, it really is the best key\n * available between storage and cached keys in memory. This is why keys with this field set to\n * true are used by the key loader to return cached keys. Also see KeyOperation.isBest there. */\n get isBetter(): boolean | undefined { return this._isBetter; }\n // should only be set in key.checkBetterThanKeyInStorage\n set isBetter(value: boolean | undefined) { this._isBetter = value; }\n}\n\nexport function isBetterThan(newSession: Olm.InboundGroupSession, existingSession: Olm.InboundGroupSession) {\n return newSession.first_known_index() < existingSession.first_known_index();\n}\n\nexport abstract class IncomingRoomKey extends RoomKey {\n private _eventIds?: string[];\n \n checkBetterThanKeyInStorage(loader: KeyLoader, txn: Transaction): Promise {\n return this._checkBetterThanKeyInStorage(loader, undefined, txn);\n }\n\n async write(loader: KeyLoader, txn: Transaction): Promise {\n // we checked already and we had a better session in storage, so don't write\n let pickledSession: string | undefined;\n if (this.isBetter === undefined) {\n // if this key wasn't used to decrypt any messages in the same sync,\n // we haven't checked if this is the best key yet,\n // so do that now to not overwrite a better key.\n // while we have the key deserialized, also pickle it to store it later on here.\n await this._checkBetterThanKeyInStorage(loader, (session, pickleKey) => {\n pickledSession = session.pickle(pickleKey);\n }, txn);\n }\n if (this.isBetter === false) {\n return false;\n }\n // before calling write in parallel, we need to check loader.running is false so we are sure our transaction will not be closed\n if (!pickledSession) {\n pickledSession = await loader.useKey(this, (session, pickleKey) => session.pickle(pickleKey));\n }\n const sessionEntry = {\n roomId: this.roomId,\n senderKey: this.senderKey,\n sessionId: this.sessionId,\n session: pickledSession,\n backup: this.backupStatus,\n source: this.keySource,\n claimedKeys: {\"ed25519\": this.claimedEd25519Key},\n };\n txn.inboundGroupSessions.set(sessionEntry);\n return true;\n }\n\n get eventIds() { return this._eventIds; }\n\n private async _checkBetterThanKeyInStorage(loader: KeyLoader, callback: (((session: Olm.InboundGroupSession, pickleKey: string) => void) | undefined), txn: Transaction): Promise {\n if (this.isBetter !== undefined) {\n return this.isBetter;\n }\n let existingKey = loader.getCachedKey(this.roomId, this.senderKey, this.sessionId);\n if (!existingKey) {\n const storageKey = await keyFromStorage(this.roomId, this.senderKey, this.sessionId, txn);\n // store the event ids that can be decrypted with this key\n // before we overwrite them if called from `write`.\n if (storageKey) {\n if (storageKey.hasSession) {\n existingKey = storageKey;\n } else if (storageKey.eventIds) {\n this._eventIds = storageKey.eventIds;\n }\n }\n }\n if (existingKey) {\n const key = existingKey;\n await loader.useKey(this, async newSession => {\n await loader.useKey(key, (existingSession, pickleKey) => {\n // set isBetter as soon as possible, on both keys compared, \n // as it is is used to determine whether a key can be used for the cache\n this.isBetter = isBetterThan(newSession, existingSession);\n key.isBetter = !this.isBetter;\n if (this.isBetter && callback) {\n callback(newSession, pickleKey);\n }\n });\n });\n } else {\n // no previous key, so we're the best \\o/\n this.isBetter = true;\n }\n return this.isBetter!;\n }\n\n protected get backupStatus(): BackupStatus {\n return BackupStatus.NotBackedUp;\n }\n\n protected abstract get keySource(): KeySource;\n}\n\nclass DeviceMessageRoomKey extends IncomingRoomKey {\n private _decryptionResult: DecryptionResult;\n\n constructor(decryptionResult: DecryptionResult) {\n super();\n this._decryptionResult = decryptionResult;\n }\n\n get roomId() { return this._decryptionResult.event.content?.[\"room_id\"]; }\n get senderKey() { return this._decryptionResult.senderCurve25519Key; }\n get sessionId() { return this._decryptionResult.event.content?.[\"session_id\"]; }\n get claimedEd25519Key() { return this._decryptionResult.claimedEd25519Key; }\n get serializationKey(): string { return this._decryptionResult.event.content?.[\"session_key\"]; }\n get serializationType(): string { return \"create\"; }\n protected get keySource(): KeySource { return KeySource.DeviceMessage; }\n\n loadInto(session) {\n session.create(this.serializationKey);\n }\n}\n\n// a room key we send out ourselves,\n// here adapted to write it as an incoming key\n// as we don't send it to ourself with a to_device msg\nexport class OutboundRoomKey extends IncomingRoomKey {\n private _sessionKey: string;\n\n constructor(\n private readonly _roomId: string,\n private readonly outboundSession: Olm.OutboundGroupSession,\n private readonly identityKeys: {[algo: string]: string}\n ) {\n super();\n // this is a new key, so always better than what might be in storage, no need to check\n this.isBetter = true;\n // cache this, as it is used by key loader to find a matching key and\n // this calls into WASM so is not just reading a prop\n this._sessionKey = this.outboundSession.session_key();\n }\n\n get roomId(): string { return this._roomId; }\n get senderKey(): string { return this.identityKeys.curve25519; }\n get sessionId(): string { return this.outboundSession.session_id(); }\n get claimedEd25519Key(): string { return this.identityKeys.ed25519; }\n get serializationKey(): string { return this._sessionKey; }\n get serializationType(): string { return \"create\"; }\n protected get keySource(): KeySource { return KeySource.Outbound; }\n\n loadInto(session: Olm.InboundGroupSession) {\n session.create(this.serializationKey);\n }\n}\n\nclass BackupRoomKey extends IncomingRoomKey {\n constructor(private _roomId: string, private _sessionId: string, private _backupInfo: object) {\n super();\n }\n\n get roomId() { return this._roomId; }\n get senderKey() { return this._backupInfo[\"sender_key\"]; }\n get sessionId() { return this._sessionId; }\n get claimedEd25519Key() { return this._backupInfo[\"sender_claimed_keys\"]?.[\"ed25519\"]; }\n get serializationKey(): string { return this._backupInfo[\"session_key\"]; }\n get serializationType(): string { return \"import_session\"; }\n protected get keySource(): KeySource { return KeySource.Backup; }\n\n loadInto(session) {\n session.import_session(this.serializationKey);\n }\n\n protected get backupStatus(): BackupStatus {\n return BackupStatus.BackedUp;\n }\n}\n\nexport class StoredRoomKey extends RoomKey {\n private storageEntry: InboundGroupSessionEntry;\n\n constructor(storageEntry: InboundGroupSessionEntry) {\n super();\n this.isBetter = true; // usually the key in storage is the best until checks prove otherwise\n this.storageEntry = storageEntry;\n }\n\n get roomId() { return this.storageEntry.roomId; }\n get senderKey() { return this.storageEntry.senderKey; }\n get sessionId() { return this.storageEntry.sessionId; }\n get claimedEd25519Key() { return this.storageEntry.claimedKeys![\"ed25519\"]; }\n get eventIds() { return this.storageEntry.eventIds; }\n get serializationKey(): string { return this.storageEntry.session || \"\"; }\n get serializationType(): string { return \"unpickle\"; }\n \n loadInto(session, pickleKey) {\n session.unpickle(pickleKey, this.serializationKey);\n }\n\n get hasSession() {\n // sessions are stored before they are received\n // to keep track of events that need it to be decrypted.\n // This is used to retry decryption of those events once the session is received.\n return !!this.serializationKey;\n }\n}\n\nexport function keyFromDeviceMessage(dr: DecryptionResult): DeviceMessageRoomKey | undefined {\n const sessionKey = dr.event.content?.[\"session_key\"];\n const key = new DeviceMessageRoomKey(dr);\n if (\n typeof key.roomId === \"string\" && \n typeof key.sessionId === \"string\" && \n typeof key.senderKey === \"string\" &&\n typeof sessionKey === \"string\"\n ) {\n return key;\n }\n}\n\n/*\nsessionInfo is a response from key backup and has the following keys:\n algorithm\n forwarding_curve25519_key_chain\n sender_claimed_keys\n sender_key\n session_key\n */\nexport function keyFromBackup(roomId, sessionId, backupInfo): BackupRoomKey | undefined {\n const sessionKey = backupInfo[\"session_key\"];\n const senderKey = backupInfo[\"sender_key\"];\n // TODO: can we just trust this?\n const claimedEd25519Key = backupInfo[\"sender_claimed_keys\"]?.[\"ed25519\"];\n\n if (\n typeof roomId === \"string\" && \n typeof sessionId === \"string\" && \n typeof senderKey === \"string\" &&\n typeof sessionKey === \"string\" &&\n typeof claimedEd25519Key === \"string\"\n ) {\n return new BackupRoomKey(roomId, sessionId, backupInfo);\n }\n}\n\nexport async function keyFromStorage(roomId: string, senderKey: string, sessionId: string, txn: Transaction): Promise {\n const existingSessionEntry = await txn.inboundGroupSessions.get(roomId, senderKey, sessionId);\n if (existingSessionEntry) {\n return new StoredRoomKey(existingSessionEntry);\n }\n return;\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {DecryptionPreparation} from \"./decryption/DecryptionPreparation.js\";\nimport {SessionDecryption} from \"./decryption/SessionDecryption\";\nimport {DecryptionError, MEGOLM_ALGORITHM} from \"../common\";\nimport {validateEvent, groupEventsBySession} from \"./decryption/utils\";\nimport {keyFromStorage, keyFromDeviceMessage, keyFromBackup} from \"./decryption/RoomKey\";\nimport type {RoomKey, IncomingRoomKey} from \"./decryption/RoomKey\";\nimport type {KeyLoader} from \"./decryption/KeyLoader\";\nimport type {OlmWorker} from \"../OlmWorker\";\nimport type {Transaction} from \"../../storage/idb/Transaction\";\nimport type {TimelineEvent} from \"../../storage/types\";\nimport type {DecryptionResult} from \"../DecryptionResult\";\nimport type {ILogItem} from \"../../../logging/types\";\n\nexport class Decryption {\n private keyLoader: KeyLoader;\n private olmWorker?: OlmWorker;\n\n constructor(keyLoader: KeyLoader, olmWorker: OlmWorker | undefined) {\n this.keyLoader = keyLoader;\n this.olmWorker = olmWorker;\n }\n\n async addMissingKeyEventIds(roomId, senderKey, sessionId, eventIds, txn) {\n let sessionEntry = await txn.inboundGroupSessions.get(roomId, senderKey, sessionId);\n // we never want to overwrite an existing key\n if (sessionEntry?.session) {\n return;\n }\n if (sessionEntry) {\n const uniqueEventIds = new Set(sessionEntry.eventIds);\n for (const id of eventIds) {\n uniqueEventIds.add(id);\n }\n sessionEntry.eventIds = Array.from(uniqueEventIds);\n } else {\n sessionEntry = {roomId, senderKey, sessionId, eventIds};\n }\n txn.inboundGroupSessions.set(sessionEntry);\n }\n\n async getEventIdsForMissingKey(roomId, senderKey, sessionId, txn) {\n const sessionEntry = await txn.inboundGroupSessions.get(roomId, senderKey, sessionId);\n if (sessionEntry && !sessionEntry.session) {\n return sessionEntry.eventIds;\n }\n }\n\n async hasSession(roomId, senderKey, sessionId, txn) {\n const sessionEntry = await txn.inboundGroupSessions.get(roomId, senderKey, sessionId);\n const isValidSession = typeof sessionEntry?.session === \"string\";\n return isValidSession;\n }\n\n /**\n * Reads all the state from storage to be able to decrypt the given events.\n * Decryption can then happen outside of a storage transaction.\n * @param {[type]} roomId [description]\n * @param {[type]} events [description]\n * @param {RoomKey[]?} newKeys keys as returned from extractRoomKeys, but not yet committed to storage. May be undefined.\n * @param {[type]} sessionCache [description]\n * @param {[type]} txn [description]\n * @return {DecryptionPreparation}\n */\n async prepareDecryptAll(roomId: string, events: TimelineEvent[], newKeys: IncomingRoomKey[] | undefined, txn: Transaction) {\n const errors = new Map();\n const validEvents: TimelineEvent[] = [];\n\n for (const event of events) {\n if (validateEvent(event)) {\n validEvents.push(event);\n } else {\n errors.set(event.event_id, new DecryptionError(\"MEGOLM_INVALID_EVENT\", event))\n }\n }\n\n const eventsBySession = groupEventsBySession(validEvents);\n\n const sessionDecryptions: SessionDecryption[] = [];\n await Promise.all(Array.from(eventsBySession.values()).map(async group => {\n const key = await this.getRoomKey(roomId, group.senderKey!, group.sessionId!, newKeys, txn);\n if (key) {\n sessionDecryptions.push(new SessionDecryption(key, group.events, this.olmWorker, this.keyLoader));\n } else {\n for (const event of group.events) {\n errors.set(event.event_id, new DecryptionError(\"MEGOLM_NO_SESSION\", event));\n }\n }\n }));\n\n return new DecryptionPreparation(roomId, sessionDecryptions, errors);\n }\n\n private async getRoomKey(roomId: string, senderKey: string, sessionId: string, newKeys: IncomingRoomKey[] | undefined, txn: Transaction): Promise {\n if (newKeys) {\n const key = newKeys.find(k => k.isForSession(roomId, senderKey, sessionId));\n if (key && await key.checkBetterThanKeyInStorage(this.keyLoader, txn)) {\n return key;\n }\n }\n // look only in the cache after looking into newKeys as it may contains that are better\n const cachedKey = this.keyLoader.getCachedKey(roomId, senderKey, sessionId);\n if (cachedKey) {\n return cachedKey;\n }\n const storageKey = await keyFromStorage(roomId, senderKey, sessionId, txn);\n if (storageKey && storageKey.serializationKey) {\n return storageKey;\n }\n }\n\n /**\n * Writes the key as an inbound group session if there is not already a better key in the store\n */\n writeRoomKey(key: IncomingRoomKey, txn: Transaction): Promise {\n return key.write(this.keyLoader, txn);\n }\n\n /**\n * Extracts room keys from decrypted device messages.\n * The key won't be persisted yet, you need to call RoomKey.write for that.\n */\n roomKeysFromDeviceMessages(decryptionResults: DecryptionResult[], log: ILogItem): IncomingRoomKey[] {\n const keys: IncomingRoomKey[] = [];\n for (const dr of decryptionResults) {\n if (dr.event?.type !== \"m.room_key\" || dr.event.content?.algorithm !== MEGOLM_ALGORITHM) {\n continue;\n }\n log.wrap(\"room_key\", log => {\n const key = keyFromDeviceMessage(dr);\n if (key) {\n log.set(\"roomId\", key.roomId);\n log.set(\"id\", key.sessionId);\n keys.push(key);\n } else {\n log.logLevel = log.level.Warn;\n log.set(\"invalid\", true);\n }\n }, log.level.Detail);\n }\n return keys;\n }\n\n roomKeyFromBackup(roomId: string, sessionId: string, sessionInfo: string): IncomingRoomKey | undefined {\n return keyFromBackup(roomId, sessionId, sessionInfo);\n }\n\n dispose() {\n this.keyLoader.dispose();\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {isBetterThan, IncomingRoomKey} from \"./RoomKey\";\nimport {BaseLRUCache} from \"../../../../utils/LRUCache\";\nimport type {RoomKey} from \"./RoomKey\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nexport declare class OlmDecryptionResult {\n readonly plaintext: string;\n readonly message_index: number;\n}\n\n/*\nBecause Olm only has very limited memory available when compiled to wasm,\nwe limit the amount of sessions held in memory.\n*/\nexport class KeyLoader extends BaseLRUCache {\n\n private pickleKey: string;\n private olm: Olm;\n private resolveUnusedOperation?: () => void;\n private operationBecomesUnusedPromise?: Promise;\n\n constructor(olm: Olm, pickleKey: string, limit: number) {\n super(limit);\n this.pickleKey = pickleKey;\n this.olm = olm;\n }\n\n getCachedKey(roomId: string, senderKey: string, sessionId: string): RoomKey | undefined {\n const idx = this.findCachedKeyIndex(roomId, senderKey, sessionId);\n if (idx !== -1) {\n return this._getByIndexAndMoveUp(idx)!.key;\n }\n }\n\n async useKey(key: RoomKey, callback: (session: Olm.InboundGroupSession, pickleKey: string) => Promise | T): Promise {\n const keyOp = await this.allocateOperation(key);\n try {\n return await callback(keyOp.session, this.pickleKey);\n } finally {\n this.releaseOperation(keyOp);\n }\n }\n\n get running() {\n return this._entries.some(op => op.refCount !== 0);\n }\n\n dispose() {\n for (let i = 0; i < this._entries.length; i += 1) {\n this._entries[i].dispose();\n }\n // remove all entries\n this._entries.splice(0, this._entries.length);\n }\n\n private async allocateOperation(key: RoomKey): Promise {\n let idx;\n while((idx = this.findIndexForAllocation(key)) === -1) {\n await this.operationBecomesUnused();\n }\n if (idx < this.size) {\n const op = this._getByIndexAndMoveUp(idx)!;\n // cache hit\n if (op.isForKey(key)) {\n op.refCount += 1;\n return op;\n } else {\n // refCount should be 0 here\n op.refCount = 1;\n op.key = key;\n key.loadInto(op.session, this.pickleKey);\n }\n return op;\n } else {\n // create new operation\n const session = new this.olm.InboundGroupSession();\n key.loadInto(session, this.pickleKey);\n const op = new KeyOperation(key, session);\n this._set(op);\n return op;\n }\n }\n\n private releaseOperation(op: KeyOperation) {\n op.refCount -= 1;\n if (op.refCount <= 0 && this.resolveUnusedOperation) {\n this.resolveUnusedOperation();\n // promise is resolved now, we'll need a new one for next await so clear\n this.operationBecomesUnusedPromise = this.resolveUnusedOperation = undefined;\n }\n }\n\n private operationBecomesUnused(): Promise {\n if (!this.operationBecomesUnusedPromise) {\n this.operationBecomesUnusedPromise = new Promise(resolve => {\n this.resolveUnusedOperation = resolve;\n });\n }\n return this.operationBecomesUnusedPromise;\n }\n\n private findIndexForAllocation(key: RoomKey) {\n let idx = this.findIndexSameKey(key); // cache hit\n if (idx === -1) {\n if (this.size < this.limit) {\n idx = this.size;\n } else {\n idx = this.findIndexSameSessionUnused(key);\n if (idx === -1) {\n idx = this.findIndexOldestUnused();\n }\n }\n }\n return idx;\n }\n\n private findCachedKeyIndex(roomId: string, senderKey: string, sessionId: string): number {\n return this._entries.reduce((bestIdx, op, i, arr) => {\n const bestOp = bestIdx === -1 ? undefined : arr[bestIdx];\n // only operations that are the \"best\" for their session can be used, see comment on isBest\n if (op.isBest === true && op.isForSameSession(roomId, senderKey, sessionId)) {\n if (!bestOp || op.isBetter(bestOp)) {\n return i;\n }\n }\n return bestIdx;\n }, -1);\n }\n\n private findIndexSameKey(key: RoomKey): number {\n return this._entries.findIndex(op => {\n return op.isForSameSession(key.roomId, key.senderKey, key.sessionId) && op.isForKey(key);\n });\n }\n\n private findIndexSameSessionUnused(key: RoomKey): number {\n return this._entries.reduce((worstIdx, op, i, arr) => {\n const worst = worstIdx === -1 ? undefined : arr[worstIdx];\n // we try to pick the worst operation to overwrite, so the best one stays in the cache\n if (op.refCount === 0 && op.isForSameSession(key.roomId, key.senderKey, key.sessionId)) {\n if (!worst || !op.isBetter(worst)) {\n return i;\n }\n }\n return worstIdx;\n }, -1);\n }\n\n private findIndexOldestUnused(): number {\n for (let i = this._entries.length - 1; i >= 0; i -= 1) {\n const op = this._entries[i];\n if (op.refCount === 0) {\n return i;\n }\n }\n return -1;\n }\n}\n\nclass KeyOperation {\n session: Olm.InboundGroupSession;\n key: RoomKey;\n refCount: number;\n\n constructor(key: RoomKey, session: Olm.InboundGroupSession) {\n this.key = key;\n this.session = session;\n this.refCount = 1;\n }\n\n isForSameSession(roomId: string, senderKey: string, sessionId: string): boolean {\n return this.key.roomId === roomId && this.key.senderKey === senderKey && this.key.sessionId === sessionId;\n }\n\n // assumes isForSameSession is true\n isBetter(other: KeyOperation) {\n return isBetterThan(this.session, other.session);\n }\n\n isForKey(key: RoomKey) {\n return this.key.serializationKey === key.serializationKey &&\n this.key.serializationType === key.serializationType;\n }\n\n dispose() {\n this.session.free();\n this.session = undefined as any;\n }\n\n /** returns whether the key for this operation has been checked at some point against storage\n * and was determined to be the better key, undefined if it hasn't been checked yet.\n * Only keys that are the best keys can be returned by getCachedKey as returning a cache hit\n * will usually not check for a better session in storage. Also see RoomKey.isBetter. */\n get isBest(): boolean | undefined {\n return this.key.isBetter;\n }\n}\n\nimport {KeySource} from \"../../../storage/idb/stores/InboundGroupSessionStore\";\n\n\nexport function tests() {\n let instances = 0;\n\n class MockRoomKey extends IncomingRoomKey {\n private _roomId: string;\n private _senderKey: string;\n private _sessionId: string;\n private _firstKnownIndex: number;\n\n constructor(roomId: string, senderKey: string, sessionId: string, firstKnownIndex: number) {\n super();\n this._roomId = roomId;\n this._senderKey = senderKey;\n this._sessionId = sessionId;\n this._firstKnownIndex = firstKnownIndex;\n }\n\n get roomId(): string { return this._roomId; }\n get senderKey(): string { return this._senderKey; }\n get sessionId(): string { return this._sessionId; }\n get claimedEd25519Key(): string { return \"claimedEd25519Key\"; }\n get serializationKey(): string { return `key-${this.sessionId}-${this._firstKnownIndex}`; }\n get serializationType(): string { return \"type\"; }\n get eventIds(): string[] | undefined { return undefined; }\n get keySource(): KeySource { return KeySource.DeviceMessage; }\n\n loadInto(session: Olm.InboundGroupSession) {\n const mockSession = session as unknown as MockInboundSession;\n mockSession.sessionId = this.sessionId;\n mockSession.firstKnownIndex = this._firstKnownIndex;\n }\n }\n\n class MockInboundSession {\n public sessionId: string = \"\";\n public firstKnownIndex: number = 0;\n\n constructor() {\n instances += 1;\n }\n\n free(): void { instances -= 1; }\n pickle(key: string | Uint8Array): string { return `${this.sessionId}-pickled-session`; }\n unpickle(key: string | Uint8Array, pickle: string) {}\n create(session_key: string): string { return `${this.sessionId}-created-session`; }\n import_session(session_key: string): string { return \"\"; }\n decrypt(message: string): OlmDecryptionResult { return {} as OlmDecryptionResult; }\n session_id(): string { return this.sessionId; }\n first_known_index(): number { return this.firstKnownIndex; }\n export_session(message_index: number): string { return `${this.sessionId}-exported-session`; }\n }\n\n const PICKLE_KEY = \"🥒🔑\";\n const olm = {InboundGroupSession: MockInboundSession};\n const roomId = \"!abc:hs.tld\";\n const aliceSenderKey = \"abc\";\n const bobSenderKey = \"def\";\n const sessionId1 = \"s123\";\n const sessionId2 = \"s456\";\n \n return {\n \"load key gives correct session\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n let callback1Called = false;\n let callback2Called = false;\n const p1 = loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1), async session => {\n callback1Called = true;\n assert.equal(session.session_id(), sessionId1);\n assert.equal(session.first_known_index(), 1);\n await Promise.resolve(); // make sure they are busy in parallel\n });\n const p2 = loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId2, 2), async session => {\n callback2Called = true;\n assert.equal(session.session_id(), sessionId2);\n assert.equal(session.first_known_index(), 2);\n await Promise.resolve(); // make sure they are busy in parallel\n });\n assert.equal(loader.size, 2);\n await Promise.all([p1, p2]);\n assert(callback1Called);\n assert(callback2Called);\n },\n \"keys with different first index are kept separate\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n let callback1Called = false;\n let callback2Called = false;\n const p1 = loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1), async session => {\n callback1Called = true;\n assert.equal(session.session_id(), sessionId1);\n assert.equal(session.first_known_index(), 1);\n await Promise.resolve(); // make sure they are busy in parallel\n });\n const p2 = loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId1, 2), async session => {\n callback2Called = true;\n assert.equal(session.session_id(), sessionId1);\n assert.equal(session.first_known_index(), 2);\n await Promise.resolve(); // make sure they are busy in parallel\n });\n assert.equal(loader.size, 2);\n await Promise.all([p1, p2]);\n assert(callback1Called);\n assert(callback2Called);\n },\n \"useKey blocks as long as no free sessions are available\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 1);\n let resolve;\n let callbackCalled = false;\n loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1), async session => {\n await new Promise(r => resolve = r);\n });\n await Promise.resolve();\n assert.equal(loader.size, 1);\n const promise = loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId2, 1), session => {\n callbackCalled = true;\n });\n assert.equal(callbackCalled, false);\n resolve();\n await promise;\n assert.equal(callbackCalled, true);\n },\n \"cache hit while key in use, then replace (check refCount works properly)\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 1);\n let resolve1, resolve2;\n const key1 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1);\n const p1 = loader.useKey(key1, async session => {\n await new Promise(r => resolve1 = r);\n });\n const p2 = loader.useKey(key1, async session => {\n await new Promise(r => resolve2 = r);\n });\n await Promise.resolve();\n assert.equal(loader.size, 1);\n assert.equal(loader.running, true);\n resolve1();\n await p1;\n assert.equal(loader.running, true);\n resolve2();\n await p2;\n assert.equal(loader.running, false);\n let callbackCalled = false;\n await loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId2, 1), async session => {\n callbackCalled = true;\n assert.equal(session.session_id(), sessionId2);\n assert.equal(session.first_known_index(), 1);\n });\n assert.equal(loader.size, 1);\n assert.equal(callbackCalled, true);\n },\n \"cache hit while key not in use\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n let resolve1, resolve2, invocations = 0;\n const key1 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1);\n await loader.useKey(key1, async session => { invocations += 1; });\n key1.isBetter = true;\n assert.equal(loader.size, 1);\n const cachedKey = loader.getCachedKey(roomId, aliceSenderKey, sessionId1)!;\n assert.equal(cachedKey, key1);\n await loader.useKey(cachedKey, async session => { invocations += 1; });\n assert.equal(loader.size, 1);\n assert.equal(invocations, 2);\n },\n \"dispose calls free on all sessions\": async assert => {\n instances = 0;\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n await loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1), async session => {});\n await loader.useKey(new MockRoomKey(roomId, aliceSenderKey, sessionId2, 1), async session => {});\n assert.equal(instances, 2);\n assert.equal(loader.size, 2);\n loader.dispose();\n assert.strictEqual(instances, 0, \"instances\");\n assert.strictEqual(loader.size, 0, \"loader.size\");\n },\n \"checkBetterThanKeyInStorage false with cache\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n const key1 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 2);\n await loader.useKey(key1, async session => {});\n // fake we've checked with storage that this is the best key,\n // and as long is it remains the best key with newly added keys,\n // it will be returned from getCachedKey (as called from checkBetterThanKeyInStorage)\n key1.isBetter = true;\n const key2 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 3);\n // this will hit cache of key 1 so we pass in null as txn\n const isBetter = await key2.checkBetterThanKeyInStorage(loader, null as any);\n assert.strictEqual(isBetter, false);\n assert.strictEqual(key2.isBetter, false);\n },\n \"checkBetterThanKeyInStorage true with cache\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n const key1 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 2);\n key1.isBetter = true; // fake we've check with storage so far (not including key2) this is the best key\n await loader.useKey(key1, async session => {});\n const key2 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 1);\n // this will hit cache of key 1 so we pass in null as txn\n const isBetter = await key2.checkBetterThanKeyInStorage(loader, null as any);\n assert.strictEqual(isBetter, true);\n assert.strictEqual(key2.isBetter, true);\n },\n \"prefer to remove worst key for a session from cache\": async assert => {\n const loader = new KeyLoader(olm as any as Olm, PICKLE_KEY, 2);\n const key1 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 2);\n await loader.useKey(key1, async session => {});\n key1.isBetter = true; // set to true just so it gets returned from getCachedKey\n const key2 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 4);\n await loader.useKey(key2, async session => {});\n const key3 = new MockRoomKey(roomId, aliceSenderKey, sessionId1, 3);\n await loader.useKey(key3, async session => {});\n assert.strictEqual(loader.getCachedKey(roomId, aliceSenderKey, sessionId1), key1);\n },\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MEGOLM_ALGORITHM} from \"../../common\";\nimport type {RoomKey} from \"../decryption/RoomKey\";\n\nimport type {BaseBackupInfo, SignatureMap, SessionKeyInfo} from \"./types\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nexport const Algorithm = \"m.megolm_backup.v1.curve25519-aes-sha2\";\n\nexport type BackupInfo = BaseBackupInfo & {\n algorithm: typeof Algorithm,\n auth_data: AuthData,\n}\n\ntype AuthData = {\n public_key: string,\n signatures: SignatureMap\n}\n\nexport type SessionData = {\n ciphertext: string,\n mac: string,\n ephemeral: string,\n}\n\nexport class BackupEncryption {\n constructor(\n private encryption?: Olm.PkEncryption,\n private decryption?: Olm.PkDecryption\n ) {}\n\n static fromAuthData(authData: AuthData, privateKey: Uint8Array, olm: Olm): BackupEncryption {\n const expectedPubKey = authData.public_key;\n const decryption = new olm.PkDecryption();\n const encryption = new olm.PkEncryption();\n try {\n const pubKey = decryption.init_with_private_key(privateKey);\n if (pubKey !== expectedPubKey) {\n throw new Error(`Bad backup key, public key does not match. Calculated ${pubKey} but expected ${expectedPubKey}`);\n }\n encryption.set_recipient_key(pubKey);\n } catch(err) {\n decryption.free();\n encryption.free();\n throw err;\n }\n return new BackupEncryption(encryption, decryption);\n }\n\n decryptRoomKey(sessionData: SessionData): SessionKeyInfo {\n const sessionInfo = this.decryption!.decrypt(\n sessionData.ephemeral,\n sessionData.mac,\n sessionData.ciphertext,\n );\n return JSON.parse(sessionInfo) as SessionKeyInfo;\n }\n\n encryptRoomKey(key: RoomKey, sessionKey: string): SessionData {\n const sessionInfo: SessionKeyInfo = {\n algorithm: MEGOLM_ALGORITHM,\n sender_key: key.senderKey,\n sender_claimed_keys: {ed25519: key.claimedEd25519Key},\n forwarding_curve25519_key_chain: [],\n session_key: sessionKey\n };\n return this.encryption!.encrypt(JSON.stringify(sessionInfo)) as SessionData;\n }\n\n dispose() {\n this.decryption?.free();\n this.decryption = undefined;\n this.encryption?.free();\n this.encryption = undefined;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {StoreNames} from \"../../../storage/common\";\nimport {StoredRoomKey, keyFromBackup} from \"../decryption/RoomKey\";\nimport {MEGOLM_ALGORITHM} from \"../../common\";\nimport * as Curve25519 from \"./Curve25519\";\nimport {AbortableOperation} from \"../../../../utils/AbortableOperation\";\nimport {ObservableValue} from \"../../../../observable/value\";\nimport {Deferred} from \"../../../../utils/Deferred\";\nimport {EventEmitter} from \"../../../../utils/EventEmitter\";\n\nimport {SetAbortableFn} from \"../../../../utils/AbortableOperation\";\nimport type {BackupInfo, SessionData, SessionKeyInfo, SessionInfo, KeyBackupPayload} from \"./types\";\nimport type {HomeServerApi} from \"../../../net/HomeServerApi\";\nimport type {IncomingRoomKey, RoomKey} from \"../decryption/RoomKey\";\nimport type {KeyLoader} from \"../decryption/KeyLoader\";\nimport type {SecretStorage} from \"../../../ssss/SecretStorage\";\nimport type {Storage} from \"../../../storage/idb/Storage\";\nimport type {ILogItem} from \"../../../../logging/types\";\nimport type {Platform} from \"../../../../platform/web/Platform\";\nimport type {Transaction} from \"../../../storage/idb/Transaction\";\nimport type {IHomeServerRequest} from \"../../../net/HomeServerRequest\";\nimport type * as OlmNamespace from \"@matrix-org/olm\";\ntype Olm = typeof OlmNamespace;\n\nconst KEYS_PER_REQUEST = 200;\n\n// a set of fields we need to store once we've fetched\n// the backup info from the homeserver, which happens in start()\nclass BackupConfig {\n constructor(\n public readonly info: BackupInfo,\n public readonly crypto: Curve25519.BackupEncryption\n ) {}\n}\n\nexport class KeyBackup extends EventEmitter<{change: never}> {\n private _operationInProgress?: AbortableOperation, Progress>;\n private _stopped = false;\n private _needsNewKey = false;\n private _hasBackedUpAllKeys = false;\n private _error?: Error;\n private crypto?: Curve25519.BackupEncryption;\n private backupInfo?: BackupInfo;\n private privateKey?: Uint8Array;\n private backupConfigDeferred: Deferred = new Deferred();\n private backupInfoRequest?: IHomeServerRequest;\n\n constructor(\n private readonly hsApi: HomeServerApi,\n private readonly olm: Olm,\n private readonly keyLoader: KeyLoader,\n private readonly storage: Storage,\n private readonly platform: Platform,\n private readonly maxDelay: number = 10000\n ) {\n super();\n // doing the network request for getting the backup info\n // and hence creating the crypto instance depending on the chose algorithm\n // is delayed until start() is called, but we want to already take requests\n // for fetching the room keys, so put the crypto and backupInfo in a deferred.\n this.backupConfigDeferred = new Deferred();\n }\n\n get hasStopped(): boolean { return this._stopped; }\n get error(): Error | undefined { return this._error; }\n get version(): string | undefined { return this.backupConfigDeferred.value?.info?.version; }\n get needsNewKey(): boolean { return this._needsNewKey; }\n get hasBackedUpAllKeys(): boolean { return this._hasBackedUpAllKeys; }\n get operationInProgress(): AbortableOperation, Progress> | undefined { return this._operationInProgress; }\n\n async getRoomKey(roomId: string, sessionId: string, log: ILogItem): Promise {\n if (this.needsNewKey) {\n return;\n }\n const backupConfig = await this.backupConfigDeferred.promise;\n if (!backupConfig) {\n return;\n }\n const sessionResponse = await this.hsApi.roomKeyForRoomAndSession(backupConfig.info.version, roomId, sessionId, {log}).response();\n if (!sessionResponse.session_data) {\n return;\n }\n const sessionKeyInfo = backupConfig.crypto.decryptRoomKey(sessionResponse.session_data as SessionData);\n if (sessionKeyInfo?.algorithm === MEGOLM_ALGORITHM) {\n return keyFromBackup(roomId, sessionId, sessionKeyInfo);\n } else if (sessionKeyInfo?.algorithm) {\n log.set(\"unknown algorithm\", sessionKeyInfo.algorithm);\n }\n }\n\n markAllForBackup(txn: Transaction): Promise {\n return txn.inboundGroupSessions.markAllAsNotBackedUp();\n }\n\n async load(secretStorage: SecretStorage, log: ILogItem) {\n const base64PrivateKey = await secretStorage.readSecret(\"m.megolm_backup.v1\");\n if (base64PrivateKey) {\n this.privateKey = new Uint8Array(this.platform.encoding.base64.decode(base64PrivateKey));\n return true;\n } else {\n this.backupConfigDeferred.resolve(undefined);\n return false;\n }\n }\n\n async start(log: ILogItem) {\n await log.wrap(\"KeyBackup.start\", async log => {\n if (this.privateKey && !this.backupInfoRequest) {\n let backupInfo: BackupInfo;\n try {\n this.backupInfoRequest = this.hsApi.roomKeysVersion(undefined, {log});\n backupInfo = await this.backupInfoRequest.response() as BackupInfo;\n } catch (err) {\n if (err.name === \"AbortError\") {\n log.set(\"aborted\", true);\n return;\n } else {\n throw err;\n }\n } finally {\n this.backupInfoRequest = undefined;\n }\n // TODO: what if backupInfo is undefined or we get 404 or something?\n if (backupInfo.algorithm === Curve25519.Algorithm) {\n const crypto = Curve25519.BackupEncryption.fromAuthData(backupInfo.auth_data, this.privateKey, this.olm);\n this.backupConfigDeferred.resolve(new BackupConfig(backupInfo, crypto));\n this.emit(\"change\");\n } else {\n this.backupConfigDeferred.resolve(undefined);\n log.log({l: `Unknown backup algorithm`, algorithm: backupInfo.algorithm});\n }\n this.privateKey = undefined;\n }\n // fetch latest version\n this.flush(log);\n });\n }\n\n flush(log: ILogItem): void {\n if (!this._operationInProgress) {\n log.wrapDetached(\"flush key backup\", async log => {\n if (this._needsNewKey) {\n log.set(\"needsNewKey\", this._needsNewKey);\n return;\n }\n this._stopped = false;\n this._error = undefined;\n this._hasBackedUpAllKeys = false;\n const operation = this._runFlushOperation(log);\n this._operationInProgress = operation;\n this.emit(\"change\");\n try {\n await operation.result;\n this._hasBackedUpAllKeys = true;\n } catch (err) {\n this._stopped = true;\n if (err.name === \"HomeServerError\" && (err.errcode === \"M_WRONG_ROOM_KEYS_VERSION\" || err.errcode === \"M_NOT_FOUND\")) {\n log.set(\"wrong_version\", true);\n this._needsNewKey = true;\n } else {\n // TODO should really also use AbortError in storage\n if (err.name !== \"AbortError\" || (err.name === \"StorageError\" && err.errcode === \"AbortError\")) {\n this._error = err;\n }\n }\n log.catch(err);\n }\n this._operationInProgress = undefined;\n this.emit(\"change\");\n });\n }\n }\n\n private _runFlushOperation(log: ILogItem): AbortableOperation, Progress> {\n return new AbortableOperation(async (setAbortable, setProgress) => {\n const backupConfig = await this.backupConfigDeferred.promise;\n if (!backupConfig) {\n return;\n }\n let total = 0;\n let amountFinished = 0;\n while (true) {\n const waitMs = this.platform.random() * this.maxDelay;\n const timeout = this.platform.clock.createTimeout(waitMs);\n setAbortable(timeout);\n await timeout.elapsed();\n const txn = await this.storage.readTxn([StoreNames.inboundGroupSessions]);\n setAbortable(txn);\n // fetch total again on each iteration as while we are flushing, sync might be adding keys\n total = amountFinished + await txn.inboundGroupSessions.countNonBackedUpSessions();\n setProgress(new Progress(total, amountFinished));\n const keysNeedingBackup = (await txn.inboundGroupSessions.getFirstNonBackedUpSessions(KEYS_PER_REQUEST))\n .map(entry => new StoredRoomKey(entry));\n if (keysNeedingBackup.length === 0) {\n log.set(\"total\", total);\n return;\n }\n const payload = await this.encodeKeysForBackup(keysNeedingBackup, backupConfig.crypto);\n const uploadRequest = this.hsApi.uploadRoomKeysToBackup(backupConfig.info.version, payload, {log});\n setAbortable(uploadRequest);\n await uploadRequest.response();\n await this.markKeysAsBackedUp(keysNeedingBackup, setAbortable);\n amountFinished += keysNeedingBackup.length;\n setProgress(new Progress(total, amountFinished));\n }\n });\n }\n\n private async encodeKeysForBackup(roomKeys: RoomKey[], crypto: Curve25519.BackupEncryption): Promise {\n const payload: KeyBackupPayload = { rooms: {} };\n const payloadRooms = payload.rooms;\n for (const key of roomKeys) {\n let roomPayload = payloadRooms[key.roomId];\n if (!roomPayload) {\n roomPayload = payloadRooms[key.roomId] = { sessions: {} };\n }\n roomPayload.sessions[key.sessionId] = await this.encodeRoomKey(key, crypto);\n }\n return payload;\n }\n\n private async markKeysAsBackedUp(roomKeys: RoomKey[], setAbortable: SetAbortableFn) {\n const txn = await this.storage.readWriteTxn([\n StoreNames.inboundGroupSessions,\n ]);\n setAbortable(txn);\n try {\n await Promise.all(roomKeys.map(key => {\n return txn.inboundGroupSessions.markAsBackedUp(key.roomId, key.senderKey, key.sessionId);\n }));\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n }\n\n private async encodeRoomKey(roomKey: RoomKey, crypto: Curve25519.BackupEncryption): Promise {\n return await this.keyLoader.useKey(roomKey, session => {\n const firstMessageIndex = session.first_known_index();\n const sessionKey = session.export_session(firstMessageIndex);\n return {\n first_message_index: firstMessageIndex,\n forwarded_count: 0,\n is_verified: false,\n session_data: crypto.encryptRoomKey(roomKey, sessionKey)\n };\n });\n }\n\n dispose() {\n this.backupInfoRequest?.abort();\n this.backupConfigDeferred.value?.crypto?.dispose();\n }\n}\n\nexport class Progress {\n constructor(\n public readonly total: number,\n public readonly finished: number\n ) {}\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MEGOLM_ALGORITHM} from \"../common\";\nimport {OutboundRoomKey} from \"./decryption/RoomKey\";\n\nexport class Encryption {\n constructor({pickleKey, olm, account, keyLoader, storage, now, ownDeviceId}) {\n this._pickleKey = pickleKey;\n this._olm = olm;\n this._account = account;\n this._keyLoader = keyLoader;\n this._storage = storage;\n this._now = now;\n this._ownDeviceId = ownDeviceId;\n }\n\n discardOutboundSession(roomId, txn) {\n txn.outboundGroupSessions.remove(roomId);\n }\n\n async createRoomKeyMessage(roomId, txn) {\n let sessionEntry = await txn.outboundGroupSessions.get(roomId);\n if (sessionEntry) {\n const session = new this._olm.OutboundGroupSession();\n try {\n session.unpickle(this._pickleKey, sessionEntry.session);\n return this._createRoomKeyMessage(session, roomId);\n } finally {\n session.free();\n }\n }\n }\n\n createWithheldMessage(roomMessage, code, reason) {\n return {\n algorithm: roomMessage.algorithm,\n code,\n reason,\n room_id: roomMessage.room_id,\n sender_key: this._account.identityKeys.curve25519,\n session_id: roomMessage.session_id\n };\n }\n\n async ensureOutboundSession(roomId, encryptionParams) {\n let session = new this._olm.OutboundGroupSession();\n try {\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.inboundGroupSessions,\n this._storage.storeNames.outboundGroupSessions,\n ]);\n let roomKeyMessage;\n try {\n let sessionEntry = await txn.outboundGroupSessions.get(roomId);\n roomKeyMessage = await this._readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn);\n if (roomKeyMessage) {\n this._writeSession(this._now(), session, roomId, txn);\n }\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n return roomKeyMessage;\n } finally {\n session.free();\n }\n }\n\n async _readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn) {\n if (sessionEntry) {\n session.unpickle(this._pickleKey, sessionEntry.session);\n }\n if (!sessionEntry || this._needsToRotate(session, sessionEntry.createdAt, encryptionParams)) {\n // in the case of rotating, recreate a session as we already unpickled into it\n if (sessionEntry) {\n session.free();\n session = new this._olm.OutboundGroupSession();\n }\n session.create();\n const roomKeyMessage = this._createRoomKeyMessage(session, roomId);\n const roomKey = new OutboundRoomKey(roomId, session, this._account.identityKeys);\n await roomKey.write(this._keyLoader, txn);\n return roomKeyMessage;\n }\n }\n\n _writeSession(createdAt, session, roomId, txn) {\n txn.outboundGroupSessions.set({\n roomId,\n session: session.pickle(this._pickleKey),\n createdAt,\n });\n }\n\n /**\n * Encrypts a message with megolm\n * @param {string} roomId \n * @param {string} type event type to encrypt\n * @param {string} content content to encrypt\n * @param {object} encryptionParams the content of the m.room.encryption event\n * @return {Promise}\n */\n async encrypt(roomId, type, content, encryptionParams) {\n let session = new this._olm.OutboundGroupSession();\n try {\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.inboundGroupSessions,\n this._storage.storeNames.outboundGroupSessions,\n ]);\n let roomKeyMessage;\n let encryptedContent;\n try {\n let sessionEntry = await txn.outboundGroupSessions.get(roomId);\n roomKeyMessage = await this._readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn);\n encryptedContent = this._encryptContent(roomId, session, type, content);\n // update timestamp when a new session is created\n const createdAt = roomKeyMessage ? this._now() : sessionEntry.createdAt;\n this._writeSession(createdAt, session, roomId, txn);\n\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n return new EncryptionResult(encryptedContent, roomKeyMessage);\n } finally {\n if (session) {\n session.free();\n }\n }\n }\n\n _needsToRotate(session, createdAt, encryptionParams) {\n let rotationPeriodMs = 604800000; // default\n if (Number.isSafeInteger(encryptionParams?.rotation_period_ms)) {\n rotationPeriodMs = encryptionParams?.rotation_period_ms;\n }\n let rotationPeriodMsgs = 100; // default\n if (Number.isSafeInteger(encryptionParams?.rotation_period_msgs)) {\n rotationPeriodMsgs = encryptionParams?.rotation_period_msgs;\n }\n\n if (this._now() > (createdAt + rotationPeriodMs)) {\n return true;\n }\n if (session.message_index() >= rotationPeriodMsgs) {\n return true;\n } \n }\n\n _encryptContent(roomId, session, type, content) {\n const plaintext = JSON.stringify({\n room_id: roomId,\n type,\n content\n });\n const ciphertext = session.encrypt(plaintext);\n\n const encryptedContent = {\n algorithm: MEGOLM_ALGORITHM,\n sender_key: this._account.identityKeys.curve25519,\n ciphertext,\n session_id: session.session_id(),\n device_id: this._ownDeviceId\n };\n\n return encryptedContent;\n }\n\n _createRoomKeyMessage(session, roomId) {\n return {\n room_id: roomId,\n session_id: session.session_id(),\n session_key: session.session_key(),\n algorithm: MEGOLM_ALGORITHM,\n // chain_index is ignored by element-web if not all clients\n // but let's send it anyway, as element-web does so\n chain_index: session.message_index()\n }\n }\n}\n\n/**\n * @property {object?} roomKeyMessage if encrypting this message\n * created a new outbound session,\n * this contains the content of the m.room_key message\n * that should be sent out over olm.\n * @property {object} content the encrypted message as the content of\n * the m.room.encrypted event that should be sent out \n */\nclass EncryptionResult {\n constructor(content, roomKeyMessage) {\n this.content = content;\n this.roomKeyMessage = roomKeyMessage;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MEGOLM_ALGORITHM, DecryptionSource} from \"./common\";\nimport {groupEventsBySession} from \"./megolm/decryption/utils\";\nimport {mergeMap} from \"../../utils/mergeMap\";\nimport {groupBy} from \"../../utils/groupBy\";\nimport {makeTxnId, formatToDeviceMessagesPayload} from \"../common.js\";\nimport {iterateResponseStateEvents} from \"../room/common\";\n\nconst ENCRYPTED_TYPE = \"m.room.encrypted\";\nconst ROOM_HISTORY_VISIBILITY_TYPE = \"m.room.history_visibility\";\n// how often ensureMessageKeyIsShared can check if it needs to\n// create a new outbound session\n// note that encrypt could still create a new session\nconst MIN_PRESHARE_INTERVAL = 60 * 1000; // 1min\n\n// TODO: this class is a good candidate for splitting up into encryption and decryption, there doesn't seem to be much overlap\nexport class RoomEncryption {\n constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, keyBackup, notifyMissingMegolmSession, clock}) {\n this._room = room;\n this._deviceTracker = deviceTracker;\n this._olmEncryption = olmEncryption;\n this._megolmEncryption = megolmEncryption;\n this._megolmDecryption = megolmDecryption;\n // content of the m.room.encryption event\n this._encryptionParams = encryptionParams;\n // caches devices to verify events\n this._senderDeviceCache = new Map();\n this._storage = storage;\n this._keyBackup = keyBackup;\n this._notifyMissingMegolmSession = notifyMissingMegolmSession;\n this._clock = clock;\n this._isFlushingRoomKeyShares = false;\n this._lastKeyPreShareTime = null;\n this._keySharePromise = null;\n this._historyVisibility = undefined;\n this._disposed = false;\n }\n\n enableKeyBackup(keyBackup) {\n if (this._keyBackup && !!keyBackup) {\n return;\n }\n this._keyBackup = keyBackup;\n }\n\n async restoreMissingSessionsFromBackup(entries, log) {\n const events = entries.filter(e => e.isEncrypted && !e.isDecrypted && e.event).map(e => e.event);\n const eventsBySession = groupEventsBySession(events);\n const groups = Array.from(eventsBySession.values());\n const txn = await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);\n const hasSessions = await Promise.all(groups.map(async group => {\n return this._megolmDecryption.hasSession(this._room.id, group.senderKey, group.sessionId, txn);\n }));\n const missingSessions = groups.filter((_, i) => !hasSessions[i]);\n if (missingSessions.length) {\n // start with last sessions which should be for the last items in the timeline\n for (var i = missingSessions.length - 1; i >= 0; i--) {\n const session = missingSessions[i];\n await log.wrap(\"session\", log => this._requestMissingSessionFromBackup(session.senderKey, session.sessionId, log));\n }\n }\n }\n\n notifyTimelineClosed() {\n this._senderDeviceCache = new Map(); // purge the sender device cache\n }\n\n async writeSync(roomResponse, memberChanges, txn, log) {\n let historyVisibility = await this._loadHistoryVisibilityIfNeeded(this._historyVisibility, txn);\n const addedMembers = [];\n const removedMembers = [];\n // update the historyVisibility if needed\n await iterateResponseStateEvents(roomResponse, event => {\n // TODO: can the same state event appear twice? Hence we would be rewriting the useridentities twice...\n // we'll see in the logs\n if(event.state_key === \"\" && event.type === ROOM_HISTORY_VISIBILITY_TYPE) {\n const newHistoryVisibility = event?.content?.history_visibility;\n if (newHistoryVisibility !== historyVisibility) {\n return log.wrap({\n l: \"history_visibility changed\",\n from: historyVisibility,\n to: newHistoryVisibility\n }, async log => {\n historyVisibility = newHistoryVisibility;\n const result = await this._deviceTracker.writeHistoryVisibility(this._room, historyVisibility, txn, log);\n addedMembers.push(...result.added);\n removedMembers.push(...result.removed);\n });\n }\n }\n });\n // process member changes\n if (memberChanges.size) {\n const result = await this._deviceTracker.writeMemberChanges(\n this._room, memberChanges, historyVisibility, txn);\n addedMembers.push(...result.added);\n removedMembers.push(...result.removed);\n }\n // discard key if somebody (including ourselves) left\n if (removedMembers.length) {\n log.log({\n l: \"discardOutboundSession\",\n leftUsers: removedMembers,\n });\n this._megolmEncryption.discardOutboundSession(this._room.id, txn);\n }\n let shouldFlush = false;\n // add room to userIdentities if needed, and share the current key with them\n if (addedMembers.length) {\n shouldFlush = await this._addShareRoomKeyOperationForMembers(addedMembers, txn, log);\n }\n return {shouldFlush, historyVisibility};\n }\n\n afterSync({historyVisibility}) {\n this._historyVisibility = historyVisibility;\n }\n\n async _loadHistoryVisibilityIfNeeded(historyVisibility, txn = undefined) {\n if (!historyVisibility) {\n if (!txn) {\n txn = await this._storage.readTxn([this._storage.storeNames.roomState]);\n }\n const visibilityEntry = await txn.roomState.get(this._room.id, ROOM_HISTORY_VISIBILITY_TYPE, \"\");\n if (visibilityEntry) {\n return visibilityEntry.event?.content?.history_visibility;\n }\n }\n return historyVisibility;\n }\n\n async prepareDecryptAll(events, newKeys, source, txn) {\n const errors = new Map();\n const validEvents = [];\n for (const event of events) {\n if (event.redacted_because || event.unsigned?.redacted_because) {\n continue;\n }\n if (event.content?.algorithm !== MEGOLM_ALGORITHM) {\n errors.set(event.event_id, new Error(\"Unsupported algorithm: \" + event.content?.algorithm));\n }\n validEvents.push(event);\n }\n const preparation = await this._megolmDecryption.prepareDecryptAll(\n this._room.id, validEvents, newKeys, txn);\n return new DecryptionPreparation(preparation, errors, source, this, events);\n }\n\n async _processDecryptionResults(events, results, errors, source, txn, log) {\n const missingSessionEvents = events.filter(event => {\n const error = errors.get(event.event_id);\n return error?.code === \"MEGOLM_NO_SESSION\";\n });\n if (!missingSessionEvents.length) {\n return;\n }\n // store missing event ids if received from sync\n const missingEventsBySession = groupEventsBySession(missingSessionEvents);\n if (source === DecryptionSource.Sync) {\n await Promise.all(Array.from(missingEventsBySession.values()).map(async group => {\n const eventIds = group.events.map(e => e.event_id);\n return this._megolmDecryption.addMissingKeyEventIds(\n this._room.id, group.senderKey, group.sessionId, eventIds, txn);\n }));\n }\n \n if (!this._keyBackup) {\n return;\n }\n\n log.wrapDetached(\"check key backup\", async log => {\n // if the message came from sync, wait 10s to see if the room key arrives late,\n // and only after that proceed to request from backup\n log.set(\"source\", source);\n log.set(\"events\", missingSessionEvents.length);\n log.set(\"sessions\", missingEventsBySession.size);\n if (source === DecryptionSource.Sync) {\n await this._clock.createTimeout(10000).elapsed();\n if (this._disposed) {\n return;\n }\n // now check which sessions have been received already\n const txn = await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);\n await Promise.all(Array.from(missingEventsBySession).map(async ([key, group]) => {\n if (await this._megolmDecryption.hasSession(this._room.id, group.senderKey, group.sessionId, txn)) {\n missingEventsBySession.delete(key);\n }\n }));\n }\n await Promise.all(Array.from(missingEventsBySession.values()).map(group => {\n return log.wrap(\"session\", log => this._requestMissingSessionFromBackup(group.senderKey, group.sessionId, log));\n }));\n });\n }\n\n async _verifyDecryptionResults(results, txn) {\n await Promise.all(results.map(async result => {\n let device = this._senderDeviceCache.get(result.senderCurve25519Key);\n if (!device) {\n device = await this._deviceTracker.getDeviceByCurve25519Key(result.senderCurve25519Key, txn);\n this._senderDeviceCache.set(result.senderCurve25519Key, device);\n }\n if (device) {\n result.setDevice(device);\n }\n }));\n }\n\n /** fetches the devices that are not yet known locally from the homeserver to verify the sender of this message. */\n async _fetchKeyAndVerifyDecryptionResults(results, hsApi, log) {\n const resultsWithoutDevice = results.filter(r => r.isVerificationUnknown);\n if (resultsWithoutDevice.length) {\n return log.wrap(\"fetch unverified senders\", async log => {\n const sendersWithoutDevice = Array.from(resultsWithoutDevice.reduce((senders, r) => {\n return senders.add(r.encryptedEvent.sender);\n }, new Set()));\n log.set(\"senders\", sendersWithoutDevice);\n // Fetch the devices, ignore return value, and just reuse\n // _verifyDecryptionResults method so we only have one impl how to verify.\n // Use devicesForUsers rather than devicesForRoomMembers as the room might not be tracked yet\n await this._deviceTracker.devicesForUsers(sendersWithoutDevice, hsApi, log);\n // now that we've fetched the missing devices, try verifying the results again\n const txn = await this._storage.readTxn([this._storage.storeNames.deviceKeys]);\n await this._verifyDecryptionResults(resultsWithoutDevice, txn);\n const resultsWithFoundDevice = resultsWithoutDevice.filter(r => !r.isVerificationUnknown);\n const resultsToEventIdMap = resultsWithFoundDevice.reduce((map, r) => {\n map.set(r.encryptedEvent.event_id, r);\n return map;\n }, new Map());\n return new BatchDecryptionResult(resultsToEventIdMap, new Map(), this);\n });\n }\n return new BatchDecryptionResult(new Map(), new Map(), this);\n }\n\n async _requestMissingSessionFromBackup(senderKey, sessionId, log) {\n // show prompt to enable secret storage\n if (!this._keyBackup) {\n log.set(\"enabled\", false);\n this._notifyMissingMegolmSession();\n return;\n }\n log.set(\"id\", sessionId);\n log.set(\"senderKey\", senderKey);\n try {\n const roomKey = await this._keyBackup.getRoomKey(this._room.id, sessionId, log);\n if (roomKey) {\n if (roomKey.senderKey !== senderKey) {\n log.set(\"wrong_sender_key\", roomKey.senderKey);\n log.logLevel = log.level.Warn;\n return;\n }\n let keyIsBestOne = false;\n let retryEventIds;\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]);\n try {\n keyIsBestOne = await this._megolmDecryption.writeRoomKey(roomKey, txn);\n log.set(\"isBetter\", keyIsBestOne);\n if (keyIsBestOne) {\n retryEventIds = roomKey.eventIds;\n }\n } catch (err) {\n txn.abort();\n throw err;\n }\n await txn.complete();\n if (keyIsBestOne) {\n await log.wrap(\"retryDecryption\", log => this._room.notifyRoomKey(roomKey, retryEventIds || [], log));\n }\n }\n } catch (err) {\n if (!(err.name === \"HomeServerError\" && err.errcode === \"M_NOT_FOUND\")) {\n log.set(\"not_found\", true);\n } else {\n log.error = err;\n log.logLevel = log.level.Error;\n }\n }\n }\n\n /**\n * @param {RoomKey} roomKeys\n * @param {Transaction} txn\n * @return {Promise>} the event ids that should be retried to decrypt\n */\n getEventIdsForMissingKey(roomKey, txn) {\n return this._megolmDecryption.getEventIdsForMissingKey(this._room.id, roomKey.senderKey, roomKey.sessionId, txn);\n }\n\n /** shares the encryption key for the next message if needed */\n async ensureMessageKeyIsShared(hsApi, log) {\n if (this._lastKeyPreShareTime?.measure() < MIN_PRESHARE_INTERVAL) {\n return;\n }\n this._lastKeyPreShareTime = this._clock.createMeasure();\n try {\n this._keySharePromise = (async () => {\n const roomKeyMessage = await this._megolmEncryption.ensureOutboundSession(this._room.id, this._encryptionParams);\n if (roomKeyMessage) {\n this._keyBackup?.flush(log);\n await log.wrap(\"share key\", log => this._shareNewRoomKey(roomKeyMessage, hsApi, log));\n }\n })();\n await this._keySharePromise;\n } finally {\n this._keySharePromise = null;\n }\n }\n\n async encrypt(type, content, hsApi, log) {\n // ensureMessageKeyIsShared is still running,\n // wait for it to create and share a key if needed\n if (this._keySharePromise) {\n log.set(\"waitForRunningKeyShare\", true);\n await this._keySharePromise;\n }\n const megolmResult = await log.wrap(\"megolm encrypt\", () => this._megolmEncryption.encrypt(this._room.id, type, content, this._encryptionParams));\n if (megolmResult.roomKeyMessage) {\n this._keyBackup?.flush(log);\n await log.wrap(\"share key\", log => this._shareNewRoomKey(megolmResult.roomKeyMessage, hsApi, log));\n }\n return {\n type: ENCRYPTED_TYPE,\n content: megolmResult.content\n };\n }\n\n needsToShareKeys(memberChanges) {\n for (const m of memberChanges.values()) {\n if (m.hasJoined) {\n return true;\n }\n }\n return false;\n }\n\n async _shareNewRoomKey(roomKeyMessage, hsApi, log) {\n this._historyVisibility = await this._loadHistoryVisibilityIfNeeded(this._historyVisibility);\n await this._deviceTracker.trackRoom(this._room, this._historyVisibility, log);\n const devices = await this._deviceTracker.devicesForTrackedRoom(this._room.id, hsApi, log);\n const userIds = Array.from(devices.reduce((set, device) => set.add(device.user_id), new Set()));\n \n let writeOpTxn = await this._storage.readWriteTxn([this._storage.storeNames.operations]);\n let operation;\n try {\n operation = this._writeRoomKeyShareOperation(roomKeyMessage, userIds, writeOpTxn);\n } catch (err) {\n writeOpTxn.abort();\n throw err;\n }\n // TODO: at this point we have the room key stored, and the rest is sort of optional\n // it would be nice if we could signal SendQueue that any error from here on is non-fatal and\n // return the encrypted payload.\n await this._processShareRoomKeyOperation(operation, hsApi, log);\n }\n\n async _addShareRoomKeyOperationForMembers(userIds, txn, log) {\n const roomKeyMessage = await this._megolmEncryption.createRoomKeyMessage(\n this._room.id, txn);\n if (roomKeyMessage) {\n log.log({\n l: \"share key for new members\", userIds,\n id: roomKeyMessage.session_id,\n chain_index: roomKeyMessage.chain_index\n });\n this._writeRoomKeyShareOperation(roomKeyMessage, userIds, txn);\n return true;\n }\n return false;\n }\n\n async flushPendingRoomKeyShares(hsApi, operations, log) {\n // this has to be reentrant as it can be called from Room.start while still running\n if (this._isFlushingRoomKeyShares) {\n return;\n }\n this._isFlushingRoomKeyShares = true;\n try {\n if (!operations) {\n const txn = await this._storage.readTxn([this._storage.storeNames.operations]);\n operations = await txn.operations.getAllByTypeAndScope(\"share_room_key\", this._room.id);\n }\n for (const operation of operations) {\n // just to be sure\n if (operation.type !== \"share_room_key\") {\n continue;\n }\n await log.wrap(\"operation\", log => this._processShareRoomKeyOperation(operation, hsApi, log));\n }\n } finally {\n this._isFlushingRoomKeyShares = false;\n }\n }\n\n _writeRoomKeyShareOperation(roomKeyMessage, userIds, txn) {\n const id = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString();\n const operation = {\n id,\n type: \"share_room_key\",\n scope: this._room.id,\n userIds,\n roomKeyMessage,\n };\n txn.operations.add(operation);\n return operation;\n }\n\n async _processShareRoomKeyOperation(operation, hsApi, log) {\n log.set(\"id\", operation.id);\n this._historyVisibility = await this._loadHistoryVisibilityIfNeeded(this._historyVisibility);\n await this._deviceTracker.trackRoom(this._room, this._historyVisibility, log);\n const devices = await this._deviceTracker.devicesForRoomMembers(this._room.id, operation.userIds, hsApi, log);\n const messages = await log.wrap(\"olm encrypt\", log => this._olmEncryption.encrypt(\n \"m.room_key\", operation.roomKeyMessage, devices, hsApi, log));\n const missingDevices = devices.filter(d => !messages.some(m => m.device === d));\n await log.wrap(\"send\", log => this._sendMessagesToDevices(ENCRYPTED_TYPE, messages, hsApi, log));\n if (missingDevices.length) {\n await log.wrap(\"missingDevices\", async log => {\n log.set(\"devices\", missingDevices.map(d => d.device_id));\n const unsentUserIds = operation.userIds.filter(userId => missingDevices.some(d => d.user_id === userId));\n log.set(\"unsentUserIds\", unsentUserIds);\n operation.userIds = unsentUserIds;\n // first remove the users that we've sent the keys already from the operation,\n // so if anything fails, we don't send them again\n await this._updateOperationsStore(operations => operations.update(operation));\n // now, let the devices we could not claim their key\n const withheldMessage = this._megolmEncryption.createWithheldMessage(operation.roomKeyMessage, \"m.no_olm\", \"OTKs exhausted\");\n await this._sendSharedMessageToDevices(\"org.matrix.room_key.withheld\", withheldMessage, missingDevices, hsApi, log);\n });\n }\n await this._updateOperationsStore(operations => operations.remove(operation.id));\n }\n\n async _updateOperationsStore(callback) {\n const writeTxn = await this._storage.readWriteTxn([this._storage.storeNames.operations]);\n try {\n callback(writeTxn.operations);\n } catch (err) {\n writeTxn.abort();\n throw err;\n }\n await writeTxn.complete();\n }\n\n // TODO: make this use _sendMessagesToDevices\n async _sendSharedMessageToDevices(type, message, devices, hsApi, log) {\n const devicesByUser = groupBy(devices, device => device.user_id);\n const payload = {\n messages: Array.from(devicesByUser.entries()).reduce((userMap, [userId, devices]) => {\n userMap[userId] = devices.reduce((deviceMap, device) => {\n deviceMap[device.device_id] = message;\n return deviceMap;\n }, {});\n return userMap;\n }, {})\n };\n const txnId = makeTxnId();\n await hsApi.sendToDevice(type, payload, txnId, {log}).response();\n }\n\n async _sendMessagesToDevices(type, messages, hsApi, log) {\n log.set(\"messages\", messages.length);\n const payload = formatToDeviceMessagesPayload(messages);\n const txnId = makeTxnId();\n await hsApi.sendToDevice(type, payload, txnId, {log}).response();\n }\n\n filterUndecryptedEventEntriesForKeys(entries, keys) {\n return entries.filter(entry => {\n if (entry.isEncrypted && !entry.isDecrypted) {\n const {event} = entry;\n if (event) {\n const senderKey = event.content?.[\"sender_key\"];\n const sessionId = event.content?.[\"session_id\"];\n return keys.some(key => senderKey === key.senderKey && sessionId === key.sessionId);\n }\n }\n return false;\n });\n }\n\n dispose() {\n this._disposed = true;\n }\n}\n\n/**\n * wrappers around megolm decryption classes to be able to post-process\n * the decryption results before turning them\n */\nclass DecryptionPreparation {\n constructor(megolmDecryptionPreparation, extraErrors, source, roomEncryption, events) {\n this._megolmDecryptionPreparation = megolmDecryptionPreparation;\n this._extraErrors = extraErrors;\n this._source = source;\n this._roomEncryption = roomEncryption;\n this._events = events;\n }\n\n async decrypt() {\n return new DecryptionChanges(\n await this._megolmDecryptionPreparation.decrypt(),\n this._extraErrors,\n this._source,\n this._roomEncryption,\n this._events);\n }\n\n dispose() {\n this._megolmDecryptionPreparation.dispose();\n }\n}\n\nclass DecryptionChanges {\n constructor(megolmDecryptionChanges, extraErrors, source, roomEncryption, events) {\n this._megolmDecryptionChanges = megolmDecryptionChanges;\n this._extraErrors = extraErrors;\n this._source = source;\n this._roomEncryption = roomEncryption;\n this._events = events;\n }\n\n async write(txn, log) {\n const {results, errors} = await this._megolmDecryptionChanges.write(txn);\n mergeMap(this._extraErrors, errors);\n await this._roomEncryption._processDecryptionResults(this._events, results, errors, this._source, txn, log);\n return new BatchDecryptionResult(results, errors, this._roomEncryption);\n }\n}\n\nclass BatchDecryptionResult {\n constructor(results, errors, roomEncryption) {\n this.results = results;\n this.errors = errors;\n this._roomEncryption = roomEncryption;\n }\n\n applyToEntries(entries, callback = undefined) {\n for (const entry of entries) {\n const result = this.results.get(entry.id);\n if (result) {\n entry.setDecryptionResult(result);\n callback?.(entry);\n } else {\n const error = this.errors.get(entry.id);\n if (error) {\n entry.setDecryptionError(error);\n callback?.(entry);\n }\n }\n }\n }\n\n /** Verify the decryption results by looking for the corresponding device in local persistance\n * @returns {BatchDecryptionResult} a new batch result with the results for which we now found a device */\n verifyKnownSenders(txn) {\n return this._roomEncryption._verifyDecryptionResults(Array.from(this.results.values()), txn);\n }\n\n get hasUnverifiedSenders() {\n for (const r of this.results.values()) {\n if (r.isVerificationUnknown) {\n return true;\n }\n }\n return false;\n }\n\n /** Verify any decryption results for which we could not find a device when\n * calling `verifyKnownSenders` prior, by fetching them from the homeserver.\n * @returns {Promise} the results for which we found a device */\n fetchAndVerifyRemainingSenders(hsApi, log) {\n return this._roomEncryption._fetchKeyAndVerifyDecryptionResults(Array.from(this.results.values()), hsApi, log);\n }\n}\n\nimport {createMockStorage} from \"../../mocks/Storage\";\nimport {Clock as MockClock} from \"../../mocks/Clock\";\nimport {poll} from \"../../mocks/poll\";\nimport {Instance as NullLoggerInstance} from \"../../logging/NullLogger\";\nimport {HomeServer as MockHomeServer} from \"../../mocks/HomeServer.js\";\n\nexport function tests() {\n const roomId = \"!abc:hs.tld\";\n return {\n \"ensureMessageKeyIsShared tracks room and passes correct history visibility to deviceTracker\": async assert => {\n const storage = await createMockStorage();\n const megolmMock = {\n async ensureOutboundSession() { return { }; }\n };\n const olmMock = {\n async encrypt() { return []; }\n }\n let isRoomTracked = false;\n let isDevicesRequested = false;\n const deviceTracker = {\n async trackRoom(room, historyVisibility) {\n // only assert on first call\n if (isRoomTracked) { return; }\n assert(!isDevicesRequested);\n assert.equal(room.id, roomId);\n assert.equal(historyVisibility, \"invited\");\n isRoomTracked = true;\n },\n async devicesForTrackedRoom() {\n assert(isRoomTracked);\n isDevicesRequested = true;\n return [];\n },\n async devicesForRoomMembers() {\n return [];\n }\n }\n const writeTxn = await storage.readWriteTxn([storage.storeNames.roomState]);\n writeTxn.roomState.set(roomId, {state_key: \"\", type: ROOM_HISTORY_VISIBILITY_TYPE, content: {\n history_visibility: \"invited\"\n }});\n await writeTxn.complete();\n const roomEncryption = new RoomEncryption({\n room: {id: roomId},\n megolmEncryption: megolmMock,\n olmEncryption: olmMock,\n storage,\n deviceTracker,\n clock: new MockClock()\n });\n const homeServer = new MockHomeServer();\n const promise = roomEncryption.ensureMessageKeyIsShared(homeServer.api, NullLoggerInstance.item);\n // need to poll because sendToDevice isn't first async step\n const request = await poll(() => homeServer.requests.sendToDevice?.[0]);\n request.respond({});\n await promise;\n assert(isRoomTracked);\n assert(isDevicesRequested);\n },\n \"encrypt tracks room and passes correct history visibility to deviceTracker\": async assert => {\n const storage = await createMockStorage();\n const megolmMock = {\n async encrypt() { return { roomKeyMessage: {} }; }\n };\n const olmMock = {\n async encrypt() { return []; }\n }\n let isRoomTracked = false;\n let isDevicesRequested = false;\n const deviceTracker = {\n async trackRoom(room, historyVisibility) {\n // only assert on first call\n if (isRoomTracked) { return; }\n assert(!isDevicesRequested);\n assert.equal(room.id, roomId);\n assert.equal(historyVisibility, \"invited\");\n isRoomTracked = true;\n },\n async devicesForTrackedRoom() {\n assert(isRoomTracked);\n isDevicesRequested = true;\n return [];\n },\n async devicesForRoomMembers() {\n return [];\n }\n }\n const writeTxn = await storage.readWriteTxn([storage.storeNames.roomState]);\n writeTxn.roomState.set(roomId, {state_key: \"\", type: ROOM_HISTORY_VISIBILITY_TYPE, content: {\n history_visibility: \"invited\"\n }});\n await writeTxn.complete();\n const roomEncryption = new RoomEncryption({\n room: {id: roomId},\n megolmEncryption: megolmMock,\n olmEncryption: olmMock,\n storage,\n deviceTracker\n });\n const homeServer = new MockHomeServer();\n const promise = roomEncryption.encrypt(\"m.room.message\", {body: \"hello\"}, homeServer.api, NullLoggerInstance.item);\n // need to poll because sendToDevice isn't first async step\n const request = await poll(() => homeServer.requests.sendToDevice?.[0]);\n request.respond({});\n await promise;\n assert(isRoomTracked);\n assert(isDevicesRequested);\n },\n \"writeSync passes correct history visibility to deviceTracker\": async assert => {\n const storage = await createMockStorage();\n let isMemberChangesCalled = false;\n const deviceTracker = {\n async writeMemberChanges(room, memberChanges, historyVisibility) {\n assert.equal(historyVisibility, \"invited\");\n isMemberChangesCalled = true;\n return {removed: [], added: []};\n },\n async devicesForRoomMembers() {\n return [];\n }\n }\n const writeTxn = await storage.readWriteTxn([storage.storeNames.roomState]);\n writeTxn.roomState.set(roomId, {state_key: \"\", type: ROOM_HISTORY_VISIBILITY_TYPE, content: {\n history_visibility: \"invited\"\n }});\n const memberChanges = new Map([[\"@alice:hs.tld\", {}]]);\n const roomEncryption = new RoomEncryption({\n room: {id: roomId},\n storage,\n deviceTracker\n });\n const roomResponse = {};\n const txn = await storage.readWriteTxn([storage.storeNames.roomState]);\n await roomEncryption.writeSync(roomResponse, memberChanges, txn, NullLoggerInstance.item);\n assert(isMemberChangesCalled);\n },\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Lock} from \"./Lock\";\n\nexport class LockMap {\n private readonly _map: Map = new Map();\n\n async takeLock(key: T): Promise {\n let lock = this._map.get(key);\n if (lock) {\n await lock.take();\n } else {\n lock = new Lock();\n lock.tryTake();\n this._map.set(key, lock);\n }\n // don't leave old locks lying around\n lock.released()!.then(() => {\n // give others a chance to take the lock first\n Promise.resolve().then(() => {\n if (!lock!.isTaken) {\n this._map.delete(key);\n }\n });\n });\n return lock;\n }\n}\n\nexport function tests() {\n return {\n \"taking a lock on the same key blocks\": async assert => {\n const lockMap = new LockMap();\n const lock = await lockMap.takeLock(\"foo\");\n let second = false;\n const prom = lockMap.takeLock(\"foo\").then(() => {\n second = true;\n });\n assert.equal(second, false);\n // do a delay to make sure prom does not resolve on its own\n await Promise.resolve();\n lock.release();\n await prom;\n assert.equal(second, true);\n },\n \"lock is not cleaned up with second request\": async assert => {\n const lockMap = new LockMap();\n const lock = await lockMap.takeLock(\"foo\");\n let ranSecond = false;\n const prom = lockMap.takeLock(\"foo\").then(returnedLock => {\n ranSecond = true;\n assert.equal(returnedLock.isTaken, true);\n // peek into internals, naughty\n // @ts-ignore\n assert.equal(lockMap._map.get(\"foo\"), returnedLock);\n });\n lock.release();\n await prom;\n // double delay to make sure cleanup logic ran\n await Promise.resolve();\n await Promise.resolve();\n assert.equal(ranSecond, true);\n },\n \"lock is cleaned up without other request\": async assert => {\n const lockMap = new LockMap();\n const lock = await lockMap.takeLock(\"foo\");\n await Promise.resolve();\n lock.release();\n // double delay to make sure cleanup logic ran\n await Promise.resolve();\n await Promise.resolve();\n // @ts-ignore\n assert.equal(lockMap._map.has(\"foo\"), false);\n },\n \n };\n}\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2019 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n\n/**\n * This function is similar to Object.assign() but it assigns recursively and\n * allows you to ignore nullish values from the source\n *\n * @param {Object} target\n * @param {Object} source\n * @returns the target object\n */\nexport function recursivelyAssign(target: Object, source: Object, ignoreNullish = false): any {\n for (const [sourceKey, sourceValue] of Object.entries(source)) {\n if (target[sourceKey] instanceof Object && sourceValue) {\n recursivelyAssign(target[sourceKey], sourceValue);\n continue;\n }\n if ((sourceValue !== null && sourceValue !== undefined) || !ignoreNullish) {\n target[sourceKey] = sourceValue;\n continue;\n }\n }\n return target;\n}","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport interface Event {}\n\nexport interface MediaDevices {\n // filter out audiooutput\n enumerate(): Promise;\n // to assign to a video element, we downcast to WrappedTrack and use the stream property. \n getMediaTracks(audio: true | MediaDeviceInfo, video: boolean | MediaDeviceInfo): Promise;\n getScreenShareTrack(): Promise;\n createVolumeMeasurer(stream: Stream, callback: () => void): VolumeMeasurer;\n}\n\n// Typescript definitions derived from https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts\n/*! *****************************************************************************\nCopyright (c) Microsoft Corporation. All rights reserved.\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthis file except in compliance with the License. You may obtain a copy of the\nLicense at http://www.apache.org/licenses/LICENSE-2.0\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\nMERCHANTABLITY OR NON-INFRINGEMENT.\nSee the Apache Version 2.0 License for specific language governing permissions\nand limitations under the License.\n***************************************************************************** */\n\nexport interface StreamTrackEvent extends Event {\n readonly track: Track;\n}\n\nexport interface StreamEventMap {\n \"addtrack\": StreamTrackEvent;\n \"removetrack\": StreamTrackEvent;\n}\n\nexport interface Stream {\n getTracks(): ReadonlyArray;\n getAudioTracks(): ReadonlyArray;\n getVideoTracks(): ReadonlyArray;\n readonly id: string;\n clone(): Stream;\n addEventListener(type: K, listener: (this: Stream, ev: StreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\n removeEventListener(type: K, listener: (this: Stream, ev: StreamEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\n addTrack(track: Track);\n removeTrack(track: Track);\n}\n\nexport enum TrackKind {\n Video = \"video\",\n Audio = \"audio\"\n}\n\nexport interface Track {\n readonly kind: TrackKind;\n readonly label: string;\n readonly id: string;\n enabled: boolean;\n // getSettings(): MediaTrackSettings;\n stop(): void;\n}\n\nexport interface VolumeMeasurer {\n get isSpeaking(): boolean;\n setSpeakingThreshold(threshold: number): void;\n stop();\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ILogItem} from \"../../logging/types\";\nimport type {Track, Stream} from \"../../platform/types/MediaDevices\";\nimport {LocalMedia} from \"./LocalMedia\";\n\nexport function getStreamAudioTrack(stream: Stream | undefined): Track | undefined {\n return stream?.getAudioTracks()[0];\n}\n\nexport function getStreamVideoTrack(stream: Stream | undefined): Track | undefined {\n return stream?.getVideoTracks()[0];\n}\n\nexport function mute(localMedia: LocalMedia, localMuteSettings: MuteSettings, log: ILogItem) {\n return log.wrap(\"mute\", log => {\n log.set(\"cameraMuted\", localMuteSettings.camera);\n log.set(\"microphoneMuted\", localMuteSettings.microphone);\n\n // Mute audio\n const userMediaAudio = getStreamAudioTrack(localMedia.userMedia);\n if (userMediaAudio) {\n const enabled = !localMuteSettings.microphone;\n log.set(\"microphone enabled\", enabled);\n userMediaAudio.enabled = enabled;\n }\n\n // Mute video\n const userMediaVideo = getStreamVideoTrack(localMedia.userMedia);\n if (userMediaVideo) {\n const enabled = !localMuteSettings.camera;\n log.set(\"camera enabled\", enabled);\n userMediaVideo.enabled = enabled;\n }\n });\n}\n\nexport class MuteSettings {\n constructor (\n private readonly isMicrophoneMuted: boolean = false,\n private readonly isCameraMuted: boolean = false,\n private hasMicrophoneTrack: boolean = false,\n private hasCameraTrack: boolean = false,\n ) {}\n\n updateTrackInfo(userMedia: Stream | undefined) {\n this.hasMicrophoneTrack = !!getStreamAudioTrack(userMedia);\n this.hasCameraTrack = !!getStreamVideoTrack(userMedia);\n }\n\n get microphone(): boolean {\n return !this.hasMicrophoneTrack || this.isMicrophoneMuted;\n }\n\n get camera(): boolean {\n return !this.hasCameraTrack || this.isCameraMuted;\n }\n\n toggleCamera(): MuteSettings {\n return new MuteSettings(this.microphone, !this.camera, this.hasMicrophoneTrack, this.hasCameraTrack);\n }\n\n toggleMicrophone(): MuteSettings {\n return new MuteSettings(!this.microphone, this.camera, this.hasMicrophoneTrack, this.hasCameraTrack);\n }\n\n equals(other: MuteSettings) {\n return this.microphone === other.microphone && this.camera === other.camera;\n }\n}\n\nexport const CALL_LOG_TYPE = \"call\";\nexport const CALL_MEMBER_VALIDITY_PERIOD_MS = 3600 * 1000; // 1h\n","// allow non-camelcase as these are events type that go onto the wire\n/* eslint-disable camelcase */\nimport type {StateEvent} from \"../storage/types\";\nimport type {SessionDescription} from \"../../platform/types/WebRTC\";\nexport enum EventType {\n GroupCall = \"org.matrix.msc3401.call\",\n GroupCallMember = \"org.matrix.msc3401.call.member\",\n Invite = \"m.call.invite\",\n Candidates = \"m.call.candidates\",\n Answer = \"m.call.answer\",\n Hangup = \"m.call.hangup\",\n Reject = \"m.call.reject\",\n SelectAnswer = \"m.call.select_answer\",\n Negotiate = \"m.call.negotiate\",\n SDPStreamMetadataChanged = \"m.call.sdp_stream_metadata_changed\",\n SDPStreamMetadataChangedPrefix = \"org.matrix.call.sdp_stream_metadata_changed\",\n Replaces = \"m.call.replaces\",\n AssertedIdentity = \"m.call.asserted_identity\",\n AssertedIdentityPrefix = \"org.matrix.call.asserted_identity\",\n}\n\n// TODO: Change to \"sdp_stream_metadata\" when MSC3077 is merged\nexport const SDPStreamMetadataKey = \"org.matrix.msc3077.sdp_stream_metadata\";\n\nexport interface FocusConfig {\n user_id: string,\n device_id: string\n}\n\nexport interface CallDeviceMembership {\n device_id: string,\n session_id: string,\n [\"expires_ts\"]?: number,\n feeds?: Array<{purpose: string}>\n [\"m.foci.active\"]?: Array\n}\n\nexport interface CallMembership {\n [\"m.call_id\"]: string,\n [\"m.devices\"]: CallDeviceMembership[]\n}\n\nexport interface CallMemberContent {\n [\"m.calls\"]: CallMembership[];\n}\n\nexport enum SDPStreamMetadataPurpose {\n Usermedia = \"m.usermedia\",\n Screenshare = \"m.screenshare\",\n}\n\nexport interface SDPStreamMetadataObject {\n purpose: SDPStreamMetadataPurpose;\n audio_muted: boolean;\n video_muted: boolean;\n}\n\nexport interface SDPStreamMetadata {\n [key: string]: SDPStreamMetadataObject;\n}\n\nexport interface CallCapabilities {\n 'm.call.transferee': boolean;\n 'm.call.dtmf': boolean;\n}\n\nexport interface CallReplacesTarget {\n id: string;\n display_name: string;\n avatar_url: string;\n}\n\nexport type MCallBase = {\n call_id: string;\n version: string | number;\n}\n\nexport type MGroupCallBase = MCallBase & {\n conf_id: string;\n device_id: string;\n sender_session_id: string;\n dest_session_id: string;\n party_id: string; // Should not need this?\n seq: number;\n} \n\nexport type MCallAnswer = Base & {\n answer: SessionDescription;\n capabilities?: CallCapabilities;\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport type MCallSelectAnswer = Base & {\n selected_party_id: string;\n}\n\nexport type MCallInvite = Base & {\n offer: SessionDescription;\n lifetime: number;\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport type MCallNegotiate = Base & {\n description: SessionDescription;\n lifetime: number;\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport type MCallSDPStreamMetadataChanged = Base & {\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport type MCallReplacesEvent = Base & {\n replacement_id: string;\n target_user: CallReplacesTarget;\n create_call: string;\n await_call: string;\n target_room: string;\n}\n\nexport type MCAllAssertedIdentity = Base & {\n asserted_identity: {\n id: string;\n display_name: string;\n avatar_url: string;\n };\n}\n\nexport type MCallCandidates = Base & {\n candidates: RTCIceCandidate[];\n}\n\nexport type MCallHangupReject = Base & {\n reason?: CallErrorCode;\n}\n\nexport enum CallErrorCode {\n /** The user chose to end the call */\n UserHangup = 'user_hangup',\n\n /** An error code when the local client failed to create an offer. */\n LocalOfferFailed = 'local_offer_failed',\n /**\n * An error code when there is no local mic/camera to use. This may be because\n * the hardware isn't plugged in, or the user has explicitly denied access.\n */\n NoUserMedia = 'no_user_media',\n\n /**\n * Error code used when a call event failed to send\n * because unknown devices were present in the room\n */\n UnknownDevices = 'unknown_devices',\n\n /**\n * Error code used when we fail to send the invite\n * for some reason other than there being unknown devices\n */\n SendInvite = 'send_invite',\n\n /**\n * An answer could not be created\n */\n CreateAnswer = 'create_answer',\n\n /**\n * Error code used when we fail to send the answer\n * for some reason other than there being unknown devices\n */\n SendAnswer = 'send_answer',\n\n /**\n * The session description from the other side could not be set\n */\n SetRemoteDescription = 'set_remote_description',\n\n /**\n * The session description from this side could not be set\n */\n SetLocalDescription = 'set_local_description',\n\n /**\n * A different device answered the call\n */\n AnsweredElsewhere = 'answered_elsewhere',\n\n /**\n * No media connection could be established to the other party\n */\n IceFailed = 'ice_failed',\n\n /**\n * The invite timed out whilst waiting for an answer\n */\n InviteTimeout = 'invite_timeout',\n\n /**\n * The call was replaced by another call\n */\n Replaced = 'replaced',\n\n /**\n * Signalling for the call could not be sent (other than the initial invite)\n */\n SignallingFailed = 'signalling_timeout',\n\n /**\n * The remote party is busy\n */\n UserBusy = 'user_busy',\n\n /**\n * We transferred the call off to somewhere else\n */\n Transfered = 'transferred',\n\n /**\n * A call from the same user was found with a new session id\n */\n NewSession = 'new_session',\n}\n\nexport type SignallingMessage =\n {type: EventType.Invite, content: MCallInvite} |\n {type: EventType.Negotiate, content: MCallNegotiate} |\n {type: EventType.Answer, content: MCallAnswer} |\n {type: EventType.SDPStreamMetadataChanged | EventType.SDPStreamMetadataChangedPrefix, content: MCallSDPStreamMetadataChanged} |\n {type: EventType.Candidates, content: MCallCandidates} |\n {type: EventType.Hangup | EventType.Reject, content: MCallHangupReject};\n\nexport enum CallIntent {\n Ring = \"m.ring\",\n Prompt = \"m.prompt\",\n Room = \"m.room\",\n};\n\nexport enum CallType {\n Video = \"m.video\",\n Voice = \"m.voice\",\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableMap} from \"../../observable/map\";\nimport {BaseObservableValue} from \"../../observable/value\";\nimport {recursivelyAssign} from \"../../utils/recursivelyAssign\";\nimport {Disposables, Disposable, IDisposable} from \"../../utils/Disposables\";\nimport {WebRTC, PeerConnection, Transceiver, TransceiverDirection, Sender, Receiver, PeerConnectionEventMap} from \"../../platform/types/WebRTC\";\nimport {MediaDevices, Track, TrackKind, Stream, StreamTrackEvent} from \"../../platform/types/MediaDevices\";\nimport {getStreamVideoTrack, getStreamAudioTrack, MuteSettings, mute} from \"./common\";\nimport {\n SDPStreamMetadataKey,\n SDPStreamMetadataPurpose,\n EventType,\n CallErrorCode,\n} from \"./callEventTypes\";\n\nimport type {Room} from \"../room/Room\";\nimport type {StateEvent} from \"../storage/types\";\nimport type {ILogItem} from \"../../logging/types\";\nimport type {TimeoutCreator, Timeout} from \"../../platform/types/types\";\nimport type {LocalMedia} from \"./LocalMedia\";\nimport type {\n MCallBase,\n MCallInvite,\n MCallNegotiate,\n MCallAnswer,\n MCallSDPStreamMetadataChanged,\n MCallCandidates,\n MCallHangupReject,\n SDPStreamMetadata,\n SignallingMessage\n} from \"./callEventTypes\";\nimport type { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { AbortError } from \"../../utils/error\";\n\nexport type Options = {\n webRTC: WebRTC,\n forceTURN: boolean,\n turnServer: BaseObservableValue,\n createTimeout: TimeoutCreator,\n emitUpdate: (peerCall: PeerCall, params: any, log: ILogItem) => void;\n errorBoundary: ErrorBoundary; \n sendSignallingMessage: (message: SignallingMessage, log: ILogItem) => Promise;\n};\n\nexport enum IncomingMessageAction {\n InviteGlare,\n Handle,\n Ignore\n};\n\nexport class RemoteMedia {\n constructor(public userMedia?: Stream | undefined, public screenShare?: Stream | undefined) {}\n}\n\n// when sending, we need to encrypt message with olm. I think the flow of room => roomEncryption => olmEncryption as we already\n// do for sharing keys will be best as that already deals with room tracking.\n/**\n * Does WebRTC signalling for a single PeerConnection, and deals with WebRTC wrappers from platform\n * */\n/** Implements a call between two peers with the signalling state keeping, while still delegating the signalling message sending. Used by GroupCall.*/\nexport class PeerCall implements IDisposable {\n private readonly peerConnection: PeerConnection;\n private _state = CallState.Fledgling;\n private direction: CallDirection;\n // we don't own localMedia and should hence not call dispose on it from here\n private localMedia?: LocalMedia;\n private localMuteSettings?: MuteSettings;\n // TODO: this should go in member\n // A queue for candidates waiting to go out.\n // We try to amalgamate candidates into a single candidate message where\n // possible\n private candidateSendQueue: Array = [];\n // If candidates arrive before we've picked an opponent (which, in particular,\n // will happen if the opponent sends candidates eagerly before the user answers\n // the call) we buffer them up here so we can then add the ones from the party we pick\n private remoteCandidateBuffer? = new Map();\n\n private remoteSDPStreamMetadata?: SDPStreamMetadata;\n private responsePromiseChain?: Promise;\n private opponentPartyId?: PartyId;\n private hangupParty: CallParty;\n private disposables = new Disposables();\n private statePromiseMap = new Map void, promise: Promise}>();\n private _remoteTrackToStreamId = new Map();\n private _remoteStreams = new Map();\n // perfect negotiation flags\n private makingOffer: boolean = false;\n private ignoreOffer: boolean = false;\n\n private sentEndOfCandidates: boolean = false;\n private iceDisconnectedTimeout?: Timeout;\n\n private _dataChannel?: any;\n private _hangupReason?: CallErrorCode;\n private _remoteMedia: RemoteMedia;\n private _remoteMuteSettings = new MuteSettings();\n private flushCandidatesLog?: ILogItem;\n \n constructor(\n private callId: string,\n private readonly options: Options,\n private readonly logItem: ILogItem,\n ) {\n logItem.log({l: \"create PeerCall\", id: callId});\n this._remoteMedia = new RemoteMedia();\n this.peerConnection = options.webRTC.createPeerConnection(\n this.options.forceTURN,\n [this.options.turnServer.get()],\n 0\n );\n // update turn servers when they change (see TurnServerSource)\n this.disposables.track(this.options.turnServer.subscribe(turnServer => {\n this.logItem.log({l: \"updating turn server\", turnServer})\n this.peerConnection.setConfiguration({iceServers: [turnServer]});\n }));\n const listen = (type: K, listener: (ev: PeerConnectionEventMap[K]) => any, options?: boolean | EventListenerOptions): void => {\n const newListener = (e) => {\n this.options.errorBoundary.try(() => listener(e));\n };\n this.peerConnection.addEventListener(type, newListener);\n const dispose = () => {\n this.peerConnection.removeEventListener(type, newListener);\n };\n this.disposables.track(dispose);\n };\n\n listen(\"iceconnectionstatechange\", async () => {\n const state = this.peerConnection.iceConnectionState;\n await logItem.wrap({l: \"onIceConnectionStateChange\", status: state}, async log => {\n await this.onIceConnectionStateChange(state, log);\n });\n });\n listen(\"icecandidate\", async (event) => {\n await logItem.wrap(\"onLocalIceCandidate\", async log => {\n if (event.candidate) {\n await this.handleLocalIceCandidate(event.candidate, log);\n }\n });\n });\n listen(\"icegatheringstatechange\", async () => {\n const state = this.peerConnection.iceGatheringState;\n await logItem.wrap({l: \"onIceGatheringStateChange\", status: state}, async log => {\n await this.handleIceGatheringState(state, log);\n });\n });\n listen(\"track\", event => {\n logItem.wrap(\"onRemoteTrack\", log => {\n this.onRemoteTrack(event.track, event.streams, log);\n });\n });\n listen(\"datachannel\", event => {\n logItem.wrap(\"onRemoteDataChannel\", log => {\n this._dataChannel = event.channel;\n this.options.emitUpdate(this, undefined, log);\n });\n });\n listen(\"negotiationneeded\", () => {\n const signalingState = this.peerConnection.signalingState;\n const promiseCreator = () => {\n return logItem.wrap({l: \"onNegotiationNeeded\", signalingState}, log => {\n return this.handleNegotiation(log);\n });\n };\n this.responsePromiseChain = this.responsePromiseChain?.then(promiseCreator) ?? promiseCreator();\n this.responsePromiseChain.catch((e) =>\n this.options.errorBoundary.reportError(e)\n );\n });\n }\n\n get dataChannel(): any | undefined { return this._dataChannel; }\n\n get state(): CallState { return this._state; }\n\n get hangupReason(): CallErrorCode | undefined { return this._hangupReason; }\n\n get remoteMedia(): Readonly {\n return this._remoteMedia;\n }\n\n get remoteMuteSettings(): MuteSettings {\n return this._remoteMuteSettings;\n }\n\n call(localMedia: LocalMedia, localMuteSettings: MuteSettings, log: ILogItem): Promise {\n return log.wrap(\"call\", async log => {\n if (this._state !== CallState.Fledgling) {\n return;\n }\n log.set(\"signalingState\", this.peerConnection.signalingState);\n this.direction = CallDirection.Outbound;\n this.setState(CallState.CreateOffer, log);\n this.localMuteSettings = localMuteSettings;\n await this.updateLocalMedia(localMedia, log);\n if (this.localMedia?.dataChannelOptions) {\n this._dataChannel = this.peerConnection.createDataChannel(\"channel\", this.localMedia.dataChannelOptions);\n }\n // after adding the local tracks, and wait for handleNegotiation to be called,\n // or invite glare where we give up our invite and answer instead\n // TODO: we don't actually use this\n await this.waitForState([CallState.InviteSent, CallState.CreateAnswer]);\n });\n }\n\n answer(localMedia: LocalMedia, localMuteSettings: MuteSettings, log: ILogItem): Promise {\n return log.wrap(\"answer\", async log => {\n if (this._state !== CallState.Ringing) {\n return;\n }\n this.setState(CallState.CreateAnswer, log);\n this.localMuteSettings = localMuteSettings;\n await this.updateLocalMedia(localMedia, log);\n let myAnswer: RTCSessionDescriptionInit;\n try {\n myAnswer = await this.peerConnection.createAnswer();\n } catch (err) {\n await log.wrap(`Failed to create answer`, log => {\n log.catch(err);\n this.terminate(CallParty.Local, CallErrorCode.CreateAnswer, log);\n });\n return;\n }\n\n try {\n await this.peerConnection.setLocalDescription(myAnswer);\n this.setState(CallState.Connecting, log);\n } catch (err) {\n await log.wrap(`Error setting local description!`, log => {\n log.catch(err);\n this.terminate(CallParty.Local, CallErrorCode.SetLocalDescription, log);\n });\n return;\n }\n // Allow a short time for initial candidates to be gathered\n try { await this.delay(200); }\n catch (err) { return; }\n await this.sendAnswer(log);\n });\n }\n\n setMedia(localMedia: LocalMedia, log: ILogItem): Promise {\n return log.wrap(\"setMedia\", async log => {\n log.set(\"userMedia_audio\", !!getStreamAudioTrack(localMedia.userMedia));\n log.set(\"userMedia_video\", !!getStreamVideoTrack(localMedia.userMedia));\n log.set(\"screenShare_video\", !!getStreamVideoTrack(localMedia.screenShare));\n log.set(\"datachannel\", !!localMedia.dataChannelOptions);\n await this.updateLocalMedia(localMedia, log);\n const content: MCallSDPStreamMetadataChanged = {\n call_id: this.callId,\n version: 1,\n [SDPStreamMetadataKey]: this.getSDPMetadata()\n };\n await this.sendSignallingMessage({type: EventType.SDPStreamMetadataChangedPrefix, content}, log);\n });\n }\n\n setMuted(localMuteSettings: MuteSettings, log: ILogItem): Promise {\n return log.wrap(\"setMuted\", async log => {\n this.localMuteSettings = localMuteSettings;\n log.set(\"cameraMuted\", localMuteSettings.camera);\n log.set(\"microphoneMuted\", localMuteSettings.microphone);\n\n if (this.localMedia) {\n mute(this.localMedia, localMuteSettings, log);\n const content: MCallSDPStreamMetadataChanged = {\n call_id: this.callId,\n version: 1,\n [SDPStreamMetadataKey]: this.getSDPMetadata()\n };\n await this.sendSignallingMessage({type: EventType.SDPStreamMetadataChangedPrefix, content}, log);\n }\n });\n }\n\n hangup(errorCode: CallErrorCode, log: ILogItem): Promise {\n return log.wrap(\"hangup\", log => {\n return this._hangup(errorCode, log);\n });\n }\n\n private async _hangup(errorCode: CallErrorCode, log: ILogItem): Promise {\n if (this._state === CallState.Ended || this._state === CallState.Ending) {\n return;\n }\n this.setState(CallState.Ending, log);\n await this.sendHangupWithCallId(this.callId, errorCode, log);\n this.terminate(CallParty.Local, errorCode, log);\n }\n\n getMessageAction(message: SignallingMessage): IncomingMessageAction {\n const callIdMatches = this.callId === message.content.call_id;\n if (message.type === EventType.Invite && !callIdMatches) {\n return IncomingMessageAction.InviteGlare;\n } if (callIdMatches) {\n return IncomingMessageAction.Handle;\n } else {\n return IncomingMessageAction.Ignore;\n }\n }\n\n handleIncomingSignallingMessage(message: SignallingMessage, partyId: PartyId, log: ILogItem): ILogItem {\n // return logItem item immediately so it can be referenced by the sync log\n let logItem;\n log.wrap({\n l: \"receive signalling message\",\n type: message.type,\n callId: message.content.call_id,\n payload: message.content\n }, async log => {\n logItem = log;\n if (this.getMessageAction(message) !== IncomingMessageAction.Handle) {\n log.set(\"wrongCallId\", true);\n return;\n }\n switch (message.type) {\n case EventType.Invite:\n await this.handleFirstInvite(message.content, partyId, log);\n break;\n case EventType.Answer:\n await this.handleAnswer(message.content, partyId, log);\n break;\n case EventType.Negotiate:\n await this.onNegotiateReceived(message.content, log);\n break;\n case EventType.Candidates:\n await this.handleRemoteIceCandidates(message.content, partyId, log);\n break;\n case EventType.SDPStreamMetadataChanged:\n case EventType.SDPStreamMetadataChangedPrefix:\n this.updateRemoteSDPStreamMetadata(message.content[SDPStreamMetadataKey], log);\n break;\n case EventType.Hangup:\n // TODO: this is a bit hacky, double check its what we need\n log.set(\"reason\", message.content.reason);\n this.terminate(CallParty.Remote, message.content.reason ?? CallErrorCode.UserHangup, log);\n break;\n default:\n log.log(`Unknown event type for call: ${message.type}`);\n break;\n }\n });\n return logItem;\n }\n\n private sendHangupWithCallId(callId: string, reason: CallErrorCode | undefined, log: ILogItem): Promise {\n const content = {\n call_id: callId,\n version: 1,\n };\n // TODO: Don't send UserHangup reason to older clients\n if (reason) {\n content[\"reason\"] = reason;\n }\n return this.sendSignallingMessage({\n type: EventType.Hangup,\n content\n }, log);\n }\n\n // calls are serialized and deduplicated by responsePromiseChain\n private async handleNegotiation(log: ILogItem): Promise {\n this.makingOffer = true;\n try {\n try {\n await this.peerConnection.setLocalDescription();\n } catch (err) {\n log.log(`Error setting local description!`).catch(err);\n this.terminate(CallParty.Local, CallErrorCode.SetLocalDescription, log);\n return;\n }\n\n if (this.peerConnection.iceGatheringState === 'gathering') {\n // Allow a short time for initial candidates to be gathered\n try { await this.delay(200); }\n catch (err) { return; }\n }\n\n if (this._state === CallState.Ended) {\n return;\n }\n\n const offer = this.peerConnection.localDescription!;\n // Get rid of any candidates waiting to be sent: they'll be included in the local\n // description we just got and will send in the offer.\n log.set(\"includedCandidates\", this.candidateSendQueue.length);\n this.candidateSendQueue = [];\n\n // need to queue this\n if (this._state === CallState.CreateOffer) {\n const content = {\n call_id: this.callId,\n offer,\n [SDPStreamMetadataKey]: this.getSDPMetadata(),\n version: 1,\n lifetime: CALL_TIMEOUT_MS\n };\n await this.sendSignallingMessage({type: EventType.Invite, content}, log);\n this.setState(CallState.InviteSent, log);\n } else if (this._state === CallState.Connected || this._state === CallState.Connecting) {\n const content = {\n call_id: this.callId,\n description: offer,\n [SDPStreamMetadataKey]: this.getSDPMetadata(),\n version: 1,\n lifetime: CALL_TIMEOUT_MS\n };\n await this.sendSignallingMessage({type: EventType.Negotiate, content}, log);\n }\n } finally {\n this.makingOffer = false;\n }\n\n this.sendCandidateQueue(log);\n\n if (this._state === CallState.InviteSent) {\n const timeoutLog = this.logItem.child(\"invite timeout\");\n log.refDetached(timeoutLog);\n // don't await this, as it would block other negotationneeded events from being processed\n // as they are processed serially\n await timeoutLog.run(async log => {\n try { await this.delay(CALL_TIMEOUT_MS); }\n catch (err) { return; } // return when delay is cancelled by throwing an AbortError\n // @ts-ignore TS doesn't take the await above into account to know that the state could have changed in between\n if (this._state === CallState.InviteSent) {\n await this._hangup(CallErrorCode.InviteTimeout, log);\n }\n });\n }\n };\n\n /**\n * @returns {boolean} whether or not this call should be replaced\n * */\n handleInviteGlare(message: SignallingMessage, partyId: PartyId, log: ILogItem): {shouldReplace: boolean, log?: ILogItem} {\n if (message.type !== EventType.Invite) {\n return {shouldReplace: false};\n }\n\n const {content} = message;\n const newCallId = content.call_id;\n const shouldReplace = this.callId! > newCallId;\n\n let logItem;\n log.wrap(\"handling call glare\", async log => {\n logItem = log;\n if (shouldReplace) {\n log.log(\n \"Glare detected: answering incoming call \" + newCallId +\n \" and canceling outgoing call \"\n );\n // TODO: How do we interrupt `call()`? well, perhaps we need to not just await InviteSent but also CreateAnswer?\n if (this._state !== CallState.Fledgling && this._state !== CallState.CreateOffer) {\n await this.sendHangupWithCallId(this.callId, CallErrorCode.Replaced, log);\n }\n // since this method isn't awaited, we dispose ourselves once we hung up\n this.close(CallErrorCode.Replaced, log);\n this.dispose();\n } else {\n log.log(\n \"Glare detected: rejecting incoming call \" + newCallId +\n \" and keeping outgoing call \"\n );\n await this.sendHangupWithCallId(newCallId, CallErrorCode.Replaced, log);\n }\n });\n\n return {shouldReplace, log: logItem};\n }\n\n private handleHangupReceived(content: MCallHangupReject, log: ILogItem) {\n // party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen\n // a partner yet but we're treating the hangup as a reject as per VoIP v0)\n // if (this.state === CallState.Ringing) {\n // default reason is user_hangup\n this.terminate(CallParty.Remote, content.reason || CallErrorCode.UserHangup, log);\n // } else {\n // log.set(\"ignored\", true);\n // }\n };\n\n private async handleFirstInvite(content: MCallInvite, partyId: PartyId, log: ILogItem): Promise {\n if (this._state !== CallState.Fledgling || this.opponentPartyId !== undefined) {\n // TODO: hangup or ignore?\n return;\n }\n await this.handleInvite(content, partyId, log);\n }\n\n private async handleInvite(content: MCallInvite, partyId: PartyId, log: ILogItem): Promise {\n\n // we must set the party ID before await-ing on anything: the call event\n // handler will start giving us more call events (eg. candidates) so if\n // we haven't set the party ID, we'll ignore them.\n this.opponentPartyId = partyId;\n this.direction = CallDirection.Inbound;\n\n const sdpStreamMetadata = content[SDPStreamMetadataKey];\n if (sdpStreamMetadata) {\n this.updateRemoteSDPStreamMetadata(sdpStreamMetadata, log);\n } else {\n log.log(`Call did not get any SDPStreamMetadata! Can not send/receive multiple streams`);\n }\n\n try {\n // Q: Why do we set the remote description before accepting the call? To start creating ICE candidates?\n await this.peerConnection.setRemoteDescription(content.offer);\n await this.addBufferedIceCandidates(log);\n } catch (e) {\n await log.wrap(`Call failed to set remote description`, async log => {\n log.catch(e);\n return this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, log);\n });\n return;\n }\n\n // According to previous comments in this file, firefox at some point did not\n // add streams until media started arriving on them. Testing latest firefox\n // (81 at time of writing), this is no longer a problem, so let's do it the correct way.\n if (this.peerConnection.getReceivers().length === 0) {\n await log.wrap(`Call no remote stream or no tracks after setting remote description!`, async log => {\n return this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, log);\n });\n return;\n }\n\n this.setState(CallState.Ringing, log);\n\n try { await this.delay(content.lifetime ?? CALL_TIMEOUT_MS); }\n catch (err) { return; }\n // @ts-ignore TS doesn't take the await above into account to know that the state could have changed in between\n if (this._state === CallState.Ringing) {\n log.log(`Invite has expired. Hanging up.`);\n this.hangupParty = CallParty.Remote; // effectively\n this.setState(CallState.Ended, log);\n //this.localMedia?.dispose();\n //this.localMedia = undefined;\n if (this.peerConnection.signalingState != 'closed') {\n this.peerConnection.close();\n }\n }\n }\n\n private async handleAnswer(content: MCallAnswer, partyId: PartyId, log: ILogItem): Promise {\n if (this._state === CallState.Ended) {\n log.log(`Ignoring answer because call has ended`);\n return;\n }\n\n if (this.opponentPartyId !== undefined) {\n log.log(`Ignoring answer: we already have an answer/reject from ${this.opponentPartyId}`);\n return;\n }\n\n this.opponentPartyId = partyId;\n await this.addBufferedIceCandidates(log);\n\n this.setState(CallState.Connecting, log);\n\n const sdpStreamMetadata = content[SDPStreamMetadataKey];\n if (sdpStreamMetadata) {\n this.updateRemoteSDPStreamMetadata(sdpStreamMetadata, log);\n } else {\n log.log(`Did not get any SDPStreamMetadata! Can not send/receive multiple streams`);\n }\n\n try {\n await this.peerConnection.setRemoteDescription(content.answer);\n } catch (e) {\n await log.wrap(`Failed to set remote description`, log => {\n log.catch(e);\n this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, log);\n });\n return;\n }\n }\n\n private async handleIceGatheringState(state: RTCIceGatheringState, log: ILogItem) {\n if (state === 'complete' && !this.sentEndOfCandidates) {\n // If we didn't get an empty-string candidate to signal the end of candidates,\n // create one ourselves now gathering has finished.\n // We cast because the interface lists all the properties as required but we\n // only want to send 'candidate'\n // XXX: We probably want to send either sdpMid or sdpMLineIndex, as it's not strictly\n // correct to have a candidate that lacks both of these. We'd have to figure out what\n // previous candidates had been sent with and copy them.\n const c = {\n candidate: '',\n } as RTCIceCandidate;\n await this.queueCandidate(c, log);\n this.sentEndOfCandidates = true;\n }\n }\n\n private async handleLocalIceCandidate(candidate: RTCIceCandidate, log: ILogItem) {\n log.set(\"sdpMid\", candidate.sdpMid);\n log.set(\"candidate\", candidate.candidate);\n\n if (this._state === CallState.Ended) {\n return;\n }\n // As with the offer, note we need to make a copy of this object, not\n // pass the original: that broke in Chrome ~m43.\n if (candidate.candidate !== '' || !this.sentEndOfCandidates) {\n await this.queueCandidate(candidate, log);\n if (candidate.candidate === '') {\n this.sentEndOfCandidates = true;\n }\n }\n }\n\n private async handleRemoteIceCandidates(content: MCallCandidates, partyId: PartyId, log: ILogItem) {\n if (this.state === CallState.Ended) {\n log.log(\"Ignoring remote ICE candidate because call has ended\");\n return;\n }\n\n const candidates = content.candidates;\n if (!candidates) {\n log.log(`Ignoring candidates event with no candidates!`);\n return;\n }\n\n const fromPartyId = content.version === 0 ? null : partyId || null;\n\n if (this.opponentPartyId === undefined) {\n // we haven't picked an opponent yet so save the candidates\n log.log(`Buffering ${candidates.length} candidates until we pick an opponent`);\n const bufferedCandidates = this.remoteCandidateBuffer!.get(fromPartyId) || [];\n bufferedCandidates.push(...candidates);\n this.remoteCandidateBuffer!.set(fromPartyId, bufferedCandidates);\n return;\n }\n\n if (this.opponentPartyId !== partyId) {\n log.log(\n `Ignoring candidates from party ID ${partyId}: ` +\n `we have chosen party ID ${this.opponentPartyId}`\n );\n\n return;\n }\n\n await this.addIceCandidates(candidates, log);\n }\n\n private async onNegotiateReceived(content: MCallNegotiate, log: ILogItem): Promise {\n const description = content.description;\n if (!description || !description.sdp || !description.type) {\n log.log(`Ignoring invalid m.call.negotiate event`);\n return;\n }\n // Politeness always follows the direction of the call: in a glare situation,\n // we pick either the inbound or outbound call, so one side will always be\n // inbound and one outbound\n const polite = this.direction === CallDirection.Inbound;\n\n // Here we follow the perfect negotiation logic from\n // https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Perfect_negotiation\n const offerCollision = (\n (description.type === 'offer') &&\n (this.makingOffer || this.peerConnection.signalingState !== 'stable')\n );\n\n this.ignoreOffer = !polite && offerCollision;\n if (this.ignoreOffer) {\n log.log(`Ignoring colliding negotiate event because we're impolite`);\n return;\n }\n\n const sdpStreamMetadata = content[SDPStreamMetadataKey];\n if (sdpStreamMetadata) {\n this.updateRemoteSDPStreamMetadata(sdpStreamMetadata, log);\n } else {\n log.log(`Received negotiation event without SDPStreamMetadata!`);\n }\n\n try {\n await this.peerConnection.setRemoteDescription(description);\n if (description.type === 'offer') {\n await this.peerConnection.setLocalDescription();\n const content = {\n call_id: this.callId,\n description: this.peerConnection.localDescription!,\n [SDPStreamMetadataKey]: this.getSDPMetadata(),\n version: 1,\n lifetime: CALL_TIMEOUT_MS\n };\n await this.sendSignallingMessage({type: EventType.Negotiate, content}, log);\n }\n } catch (err) {\n log.log(`Failed to complete negotiation`).catch(err);\n }\n }\n\n private async sendAnswer(log: ILogItem): Promise {\n const localDescription = this.peerConnection.localDescription!;\n const answerContent: MCallAnswer = {\n call_id: this.callId,\n version: 1,\n answer: {\n sdp: localDescription.sdp,\n type: localDescription.type,\n },\n [SDPStreamMetadataKey]: this.getSDPMetadata(),\n };\n\n // We have just taken the local description from the peerConn which will\n // contain all the local candidates added so far, so we can discard any candidates\n // we had queued up because they'll be in the answer.\n log.log(`Discarding ${\n this.candidateSendQueue.length} candidates that will be sent in answer`);\n this.candidateSendQueue = [];\n\n try {\n await this.sendSignallingMessage({type: EventType.Answer, content: answerContent}, log);\n } catch (error) {\n this.terminate(CallParty.Local, CallErrorCode.SendAnswer, log);\n throw error;\n }\n\n // error handler re-throws so this won't happen on error, but\n // we don't want the same error handling on the candidate queue\n this.sendCandidateQueue(log);\n }\n\n private async queueCandidate(content: RTCIceCandidate, log: ILogItem): Promise {\n // We partially de-trickle candidates by waiting for `delay` before sending them\n // amalgamated, in order to avoid sending too many m.call.candidates events and hitting\n // rate limits in Matrix.\n // In practice, it'd be better to remove rate limits for m.call.*\n\n // N.B. this deliberately lets you queue and send blank candidates, which MSC2746\n // currently proposes as the way to indicate that candidate gathering is complete.\n // This will hopefully be changed to an explicit rather than implicit notification\n // shortly.\n this.candidateSendQueue.push(content);\n\n // Don't send the ICE candidates yet if the call is in the ringing state\n if (this._state === CallState.Ringing) return;\n\n\n this.flushCandidatesLog = this.flushCandidatesLog ?? this.logItem.child(\"flush candidate queue\");\n log.refDetached(this.flushCandidatesLog);\n const {flushCandidatesLog} = this;\n // MSC2746 recommends these values (can be quite long when calling because the\n // callee will need a while to answer the call)\n try { await this.delay(this.direction === CallDirection.Inbound ? 500 : 2000); }\n catch (err) { return; }\n this.sendCandidateQueue(flushCandidatesLog);\n this.flushCandidatesLog = undefined;\n }\n\n private async sendCandidateQueue(log: ILogItem): Promise {\n if (this.candidateSendQueue.length === 0 || this._state === CallState.Ended) {\n return;\n }\n const candidates = this.candidateSendQueue;\n this.candidateSendQueue = [];\n return log.wrap({l: \"send candidates\", size: candidates.length}, async log => {\n try {\n await this.sendSignallingMessage({\n type: EventType.Candidates,\n content: {\n call_id: this.callId,\n version: 1,\n candidates\n },\n }, log);\n // Try to send candidates again just in case we received more candidates while sending.\n await this.sendCandidateQueue(log);\n } catch (error) {\n log.catch(error);\n // don't retry this event: we'll send another one later as we might\n // have more candidates by then.\n // put all the candidates we failed to send back in the queue\n\n // TODO: terminate doesn't seem to vibe with the comment above?\n this.terminate(CallParty.Local, CallErrorCode.SignallingFailed, log);\n }\n });\n }\n\n private updateRemoteSDPStreamMetadata(metadata: SDPStreamMetadata, log: ILogItem): void {\n // this will accumulate all updates into one object, so we still have the old stream info when we change stream id\n this.remoteSDPStreamMetadata = recursivelyAssign(this.remoteSDPStreamMetadata || {}, metadata, true);\n this.updateRemoteMedia(log);\n \n }\n\n private async addBufferedIceCandidates(log: ILogItem): Promise {\n if (this.remoteCandidateBuffer && this.opponentPartyId) {\n const bufferedCandidates = this.remoteCandidateBuffer.get(this.opponentPartyId);\n if (bufferedCandidates) {\n log.log(`Adding ${\n bufferedCandidates.length} buffered candidates for opponent ${this.opponentPartyId}`);\n await this.addIceCandidates(bufferedCandidates, log);\n }\n this.remoteCandidateBuffer = undefined;\n }\n }\n\n private async addIceCandidates(candidates: RTCIceCandidate[], log: ILogItem): Promise {\n for (const candidate of candidates) {\n let logItem;\n if (\n (candidate.sdpMid === null || candidate.sdpMid === undefined) &&\n (candidate.sdpMLineIndex === null || candidate.sdpMLineIndex === undefined)\n ) {\n logItem = log.log(`Got remote end-of-ICE candidates`);\n }\n else {\n logItem = log.log(`Adding remote ICE ${candidate.sdpMid} candidate: ${candidate.candidate}`);\n }\n try {\n await this.peerConnection.addIceCandidate(candidate);\n } catch (err) {\n if (!this.ignoreOffer) {\n logItem.catch(err);\n }\n }\n }\n }\n\n private onIceConnectionStateChange = async (state: RTCIceConnectionState, log: ILogItem): Promise => {\n if (this._state === CallState.Ended) {\n return; // because ICE can still complete as we're ending the call\n }\n let logStats = false;\n // ideally we'd consider the call to be connected when we get media but\n // chrome doesn't implement any of the 'onstarted' events yet\n if (state == 'connected') {\n this.iceDisconnectedTimeout?.abort();\n this.iceDisconnectedTimeout = undefined;\n this.setState(CallState.Connected, log);\n } else if (state == 'failed') {\n logStats = true;\n this.iceDisconnectedTimeout?.abort();\n this.iceDisconnectedTimeout = undefined;\n await this._hangup(CallErrorCode.IceFailed, log);\n } else if (state == 'disconnected') {\n logStats = true;\n this.iceDisconnectedTimeout = this.options.createTimeout(30 * 1000);\n try {\n await this.iceDisconnectedTimeout.elapsed()\n await this._hangup(CallErrorCode.IceFailed, log);\n }\n catch (e){\n if (!(e instanceof AbortError)) {\n throw e; \n }\n }\n }\n if (logStats) {\n const stats = await this.peerConnection.getStats();\n const statsObj = {};\n stats.forEach((value, key) => {\n statsObj[key] = value;\n });\n log.set(\"peerConnectionStats\", statsObj);\n }\n };\n\n private setState(state: CallState, log: ILogItem): void {\n if (state !== this._state) {\n log.log({l: \"change state\", status: state, oldState: this._state});\n const oldState = this._state;\n this._state = state;\n let deferred = this.statePromiseMap.get(state);\n if (deferred) {\n deferred.resolve();\n this.statePromiseMap.delete(state);\n }\n this.options.emitUpdate(this, undefined, log);\n }\n }\n\n private waitForState(states: CallState[]): Promise {\n // TODO: rework this, do we need to clean up the promises?\n return Promise.race(states.map(state => {\n let deferred = this.statePromiseMap.get(state);\n if (!deferred) {\n let resolve;\n const promise = new Promise(r => {\n resolve = r;\n });\n deferred = {resolve, promise};\n this.statePromiseMap.set(state, deferred);\n }\n return deferred.promise;\n }));\n }\n\n private terminate(hangupParty: CallParty, hangupReason: CallErrorCode, log: ILogItem): void {\n if (this._state === CallState.Ended) {\n return;\n }\n\n this.hangupParty = hangupParty;\n this._hangupReason = hangupReason;\n this.setState(CallState.Ended, log);\n this.localMedia = undefined;\n\n // TODO: change signalingState to connectionState?\n if (this.peerConnection && this.peerConnection.signalingState !== 'closed') {\n this.peerConnection.close();\n }\n }\n\n private getSDPMetadata(): SDPStreamMetadata {\n const metadata = {};\n if (this.localMedia?.userMedia) {\n const streamId = this.localMedia.userMedia.id;\n metadata[streamId] = {\n purpose: SDPStreamMetadataPurpose.Usermedia,\n audio_muted: this.localMuteSettings?.microphone ?? false,\n video_muted: this.localMuteSettings?.camera ?? false,\n };\n }\n if (this.localMedia?.screenShare) {\n const streamId = this.localMedia.screenShare.id;\n metadata[streamId] = {\n purpose: SDPStreamMetadataPurpose.Screenshare\n };\n }\n return metadata;\n }\n\n private findReceiverForStream(kind: TrackKind, streamId: string): Receiver | undefined {\n return this.peerConnection.getReceivers().find(r => {\n return r.track.kind === kind && this._remoteTrackToStreamId.get(r.track.id) === streamId;\n });\n }\n\n private findTransceiverForTrack(track: Track): Transceiver | undefined {\n return this.peerConnection.getTransceivers().find(t => {\n return t.sender.track?.id === track.id;\n });\n }\n\n\n private onRemoteTrack(track: Track, streams: ReadonlyArray, log: ILogItem) {\n log.set(\"kind\", track.kind);\n log.set(\"id\", track.id);\n log.set(\"streams\", streams.map(s => s.id));\n if (streams.length === 0) {\n log.log({l: `ignoring ${track.kind} streamless track`, id: track.id});\n return;\n }\n const stream = streams[0];\n this._remoteTrackToStreamId.set(track.id, stream.id);\n if (!this._remoteStreams.has(stream.id)) {\n const listener = (event: StreamTrackEvent): void => {\n this.logItem.wrap({l: \"removetrack\", id: event.track.id}, log => {\n const streamId = this._remoteTrackToStreamId.get(event.track.id);\n if (streamId) {\n this._remoteTrackToStreamId.delete(event.track.id);\n const streamDetails = this._remoteStreams.get(streamId);\n if (streamDetails && streamDetails.stream.getTracks().length === 0) {\n this.disposables.disposeTracked(disposeListener);\n this._remoteStreams.delete(stream.id);\n this.updateRemoteMedia(log);\n }\n }\n });\n };\n stream.addEventListener(\"removetrack\", listener);\n const disposeListener = () => {\n stream.removeEventListener(\"removetrack\", listener);\n };\n this.disposables.track(disposeListener);\n this._remoteStreams.set(stream.id, {\n disposeListener,\n stream\n });\n }\n this.updateRemoteMedia(log);\n }\n\n private updateRemoteMedia(log: ILogItem): void {\n log.wrap(\"reevaluating remote media\", log => {\n this._remoteMedia.userMedia = undefined;\n this._remoteMedia.screenShare = undefined;\n if (this.remoteSDPStreamMetadata) {\n for (const streamDetails of this._remoteStreams.values()) {\n const {stream} = streamDetails;\n const metaData = this.remoteSDPStreamMetadata[stream.id];\n if (metaData) {\n if (metaData.purpose === SDPStreamMetadataPurpose.Usermedia) {\n this._remoteMedia.userMedia = stream;\n const audioReceiver = this.findReceiverForStream(TrackKind.Audio, stream.id);\n if (audioReceiver) {\n audioReceiver.track.enabled = !metaData.audio_muted;\n }\n const videoReceiver = this.findReceiverForStream(TrackKind.Video, stream.id);\n if (videoReceiver) {\n videoReceiver.track.enabled = !metaData.video_muted;\n }\n this._remoteMuteSettings = new MuteSettings(\n metaData.audio_muted ?? false,\n metaData.video_muted ?? false,\n !!audioReceiver?.track ?? false,\n !!videoReceiver?.track ?? false\n );\n log.log({\n l: \"setting userMedia\",\n micMuted: this._remoteMuteSettings.microphone,\n cameraMuted: this._remoteMuteSettings.camera\n });\n } else if (metaData.purpose === SDPStreamMetadataPurpose.Screenshare) {\n this._remoteMedia.screenShare = stream;\n log.log(\"setting screenShare\");\n }\n } else {\n log.log({l: \"no metadata yet for stream, ignoring for now\", id: stream.id});\n }\n }\n }\n this.options.emitUpdate(this, undefined, log);\n });\n }\n\n private updateLocalMedia(localMedia: LocalMedia, logItem: ILogItem): Promise {\n return logItem.wrap(\"updateLocalMedia\", async log => {\n const senders = this.peerConnection.getSenders();\n const applyStream = async (oldStream: Stream | undefined, stream: Stream | undefined, streamPurpose: SDPStreamMetadataPurpose) => {\n const applyTrack = async (oldTrack: Track | undefined, newTrack: Track | undefined) => {\n const oldSender = senders.find(s => s.track === oldTrack);\n const streamToKeep = (oldStream ?? stream)!;\n if (streamToKeep !== stream) {\n if (oldTrack) {\n streamToKeep.removeTrack(oldTrack);\n oldTrack.stop();\n }\n if (newTrack) {\n streamToKeep.addTrack(newTrack);\n }\n }\n if (newTrack && oldSender) {\n try {\n await log.wrap(`attempting to replace ${streamPurpose} ${newTrack.kind} track`, log => {\n return oldSender.replaceTrack(newTrack);\n });\n // replaceTrack succeeded, nothing left to do\n return;\n } catch (err) {}\n }\n if(oldSender) {\n log.wrap(`removing ${streamPurpose} ${oldSender.track!.kind} track`, log => {\n this.peerConnection.removeTrack(oldSender);\n });\n }\n if (newTrack) {\n log.wrap(`adding ${streamPurpose} ${newTrack.kind} track`, log => {\n const newSender = this.peerConnection.addTrack(newTrack, streamToKeep);\n this.options.webRTC.prepareSenderForPurpose(this.peerConnection, newSender, streamPurpose);\n });\n }\n }\n if (!oldStream && !stream) {\n return;\n }\n await applyTrack(getStreamAudioTrack(oldStream), getStreamAudioTrack(stream));\n await applyTrack(getStreamVideoTrack(oldStream), getStreamVideoTrack(stream));\n };\n\n await applyStream(this.localMedia?.userMedia, localMedia?.userMedia, SDPStreamMetadataPurpose.Usermedia);\n await applyStream(this.localMedia?.screenShare, localMedia?.screenShare, SDPStreamMetadataPurpose.Screenshare);\n // we explicitly don't replace this.localMedia if already set\n // as we need to keep the old stream so the stream id doesn't change\n // instead we add and remove tracks in the stream in applyTrack\n if (!this.localMedia) {\n this.localMedia = localMedia;\n }\n // TODO: datachannel, but don't do it here as we don't want to do it from answer, rather in different method\n });\n }\n\n private async delay(timeoutMs: number): Promise {\n // Allow a short time for initial candidates to be gathered\n const timeout = this.disposables.track(this.options.createTimeout(timeoutMs));\n try {\n await timeout.elapsed();\n } finally {\n this.disposables.untrack(timeout);\n }\n }\n\n private sendSignallingMessage(message: SignallingMessage, log: ILogItem) {\n return log.wrap({l: \"send\", id: message.type}, async log => {\n return this.options.sendSignallingMessage(message, log);\n });\n }\n\n public dispose(): void {\n this.disposables.dispose();\n this.iceDisconnectedTimeout?.abort();\n this.peerConnection.close();\n // replace emitUpdate in case any eventhandler in here is still attached\n // we really don't want to trigger any code in Member after this\n this.options.emitUpdate = (_, __, log) => {\n log.log(\"emitting update from PeerCall after disposal\", this.logItem.level.Error);\n console.trace(\"emitting update from PeerCall after disposal\");\n };\n }\n\n public close(reason: CallErrorCode | undefined, log: ILogItem): void {\n if (reason === undefined) {\n reason = CallErrorCode.UserHangup;\n }\n this.terminate(CallParty.Local, reason, log);\n }\n}\n\n\n\n//import { randomString } from '../randomstring';\n\n// null is used as a special value meaning that the we're in a legacy 1:1 call\n// without MSC2746 that doesn't provide an id which device sent the message.\ntype PartyId = string | null;\n\nexport enum CallParty {\n Local = 'local',\n Remote = 'remote',\n}\n\nexport enum CallState {\n Fledgling = 'fledgling',\n CreateOffer = 'create_offer',\n InviteSent = 'invite_sent',\n CreateAnswer = 'create_answer',\n Connecting = 'connecting',\n Connected = 'connected',\n Ringing = 'ringing',\n Ending = 'ending',\n Ended = 'ended',\n}\n\nexport enum CallDirection {\n Inbound = 'inbound',\n Outbound = 'outbound',\n}\n\n/**\n * The version field that we set in m.call.* events\n */\nconst VOIP_PROTO_VERSION = 1;\n\n/** The length of time a call can be ringing for. */\nconst CALL_TIMEOUT_MS = 60000;\n\n//const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\nexport class CallError extends Error {\n code: string;\n\n constructor(code: CallErrorCode, msg: string, err: Error) {\n // Still don't think there's any way to have proper nested errors\n super(msg + \": \" + err);\n\n this.code = code;\n }\n}\n\nexport function handlesEventType(eventType: string): boolean {\n return eventType === EventType.Invite ||\n eventType === EventType.Candidates ||\n eventType === EventType.Answer ||\n eventType === EventType.Hangup ||\n eventType === EventType.SDPStreamMetadataChanged ||\n eventType === EventType.SDPStreamMetadataChangedPrefix ||\n eventType === EventType.Negotiate;\n}\n\nfunction enableSenderOnTransceiver(transceiver: Transceiver, enabled: boolean) {\n return enableTransceiver(transceiver, enabled, \"sendonly\", \"recvonly\");\n}\n\nfunction enableTransceiver(transceiver: Transceiver, enabled: boolean, exclusiveValue: TransceiverDirection, excludedValue: TransceiverDirection) {\n if (enabled) {\n if (transceiver.direction === \"inactive\") {\n transceiver.direction = exclusiveValue;\n } else {\n transceiver.direction = \"sendrecv\";\n }\n } else {\n if (transceiver.direction === \"sendrecv\") {\n transceiver.direction = excludedValue;\n } else {\n transceiver.direction = \"inactive\";\n }\n }\n}\n\n/**\n * tests to write:\n * \n * upgradeCall: adding a track with setMedia calls the correct methods on the peerConnection\n * upgradeCall: removing a track with setMedia calls the correct methods on the peerConnection\n * upgradeCall: replacing compatible track with setMedia calls the correct methods on the peerConnection\n * upgradeCall: replacing incompatible track (sender.replaceTrack throws) with setMedia calls the correct methods on the peerConnection\n * \n * */\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class ErrorBoundary {\n private _error?: Error;\n\n constructor(private readonly errorCallback: (err: Error) => void) {}\n\n /**\n * Executes callback() and then runs errorCallback() on error.\n * This will never throw but instead return `errorValue` if an error occurred.\n */\n try(callback: () => T, errorValue?: E): T | typeof errorValue;\n try(callback: () => Promise, errorValue?: E): Promise | typeof errorValue {\n try {\n let result: T | Promise = callback();\n if (result instanceof Promise) {\n result = result.catch(err => {\n this._error = err;\n this.reportError(err);\n return errorValue;\n });\n }\n return result;\n } catch (err) {\n this._error = err;\n this.reportError(err);\n return errorValue;\n }\n }\n\n reportError(err: Error) {\n try {\n this.errorCallback(err);\n } catch (err) {\n console.error(\"error in ErrorBoundary callback\", err);\n }\n }\n\n get error(): Error | undefined {\n return this._error;\n }\n}\n\nexport function tests() {\n return {\n \"catches sync error\": assert => {\n let emitted = false;\n const boundary = new ErrorBoundary(() => emitted = true);\n const result = boundary.try(() => {\n throw new Error(\"fail!\");\n }, 0);\n assert(emitted);\n assert.strictEqual(result, 0);\n },\n \"return value of callback is forwarded\": assert => {\n let emitted = false;\n const boundary = new ErrorBoundary(() => emitted = true);\n const result = boundary.try(() => {\n return \"hello\";\n });\n assert(!emitted);\n assert.strictEqual(result, \"hello\");\n },\n \"catches async error\": async assert => {\n let emitted = false;\n const boundary = new ErrorBoundary(() => emitted = true);\n const result = await boundary.try(async () => {\n throw new Error(\"fail!\");\n }, 0);\n assert(emitted);\n assert.strictEqual(result, 0);\n },\n \"exception in error callback is swallowed\": async assert => {\n let emitted = false;\n const boundary = new ErrorBoundary(() => { throw new Error(\"bug in errorCallback\"); });\n assert.doesNotThrow(() => {\n boundary.try(() => {\n throw new Error(\"fail!\");\n });\n });\n }\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {PeerCall, CallState, IncomingMessageAction} from \"../PeerCall\";\nimport {makeTxnId, makeId} from \"../../common\";\nimport {EventType, CallErrorCode} from \"../callEventTypes\";\nimport {formatToDeviceMessagesPayload} from \"../../common\";\nimport {sortedIndex} from \"../../../utils/sortedIndex\";\nimport { ErrorBoundary } from \"../../../utils/ErrorBoundary\";\n\nimport {MuteSettings} from \"../common\";\nimport type {Options as PeerCallOptions, RemoteMedia} from \"../PeerCall\";\nimport type {LocalMedia} from \"../LocalMedia\";\nimport type {HomeServerApi} from \"../../net/HomeServerApi\";\nimport type {MCallBase, MGroupCallBase, SignallingMessage, CallDeviceMembership} from \"../callEventTypes\";\nimport type {GroupCall} from \"./GroupCall\";\nimport {RoomMember} from \"../../room/members/RoomMember\";\nimport type {EncryptedMessage} from \"../../e2ee/olm/Encryption\";\nimport type {ILogItem} from \"../../../logging/types\";\nimport type {BaseObservableValue} from \"../../../observable/value\";\nimport type {Clock, Timeout} from \"../../../platform/web/dom/Clock\";\n\nexport type Options = Omit & {\n confId: string,\n ownUserId: string,\n ownDeviceId: string,\n // local session id of our client\n sessionId: string,\n hsApi: HomeServerApi,\n encryptDeviceMessage: (userId: string, deviceId: string, message: SignallingMessage, log: ILogItem) => Promise,\n emitUpdate: (participant: Member, params?: any) => void,\n clock: Clock\n}\n\nconst errorCodesWithoutRetry = [\n CallErrorCode.UserHangup,\n CallErrorCode.AnsweredElsewhere,\n CallErrorCode.Replaced,\n CallErrorCode.UserBusy,\n CallErrorCode.Transfered,\n CallErrorCode.NewSession\n];\n\n/** @internal */\nclass MemberConnection {\n public retryCount: number = 0;\n public peerCall?: PeerCall;\n public lastProcessedSeqNr: number | undefined;\n // XXX: Not needed anymore when seq is scoped to call_id\n // see https://github.com/matrix-org/matrix-spec-proposals/pull/3401#discussion_r1097482166\n public lastIgnoredSeqNr: number | undefined;\n public queuedSignallingMessages: SignallingMessage[] = [];\n public outboundSeqCounter: number = 0;\n\n constructor(\n public localMedia: LocalMedia,\n public localMuteSettings: MuteSettings,\n public turnServer: BaseObservableValue,\n public readonly logItem: ILogItem\n ) {}\n\n get canDequeueNextSignallingMessage() {\n if (this.queuedSignallingMessages.length === 0) {\n return false;\n }\n const first = this.queuedSignallingMessages[0];\n const firstSeq = first.content.seq;\n // prevent not being able to jump over seq values of ignored messages for other call ids\n // as they don't increase lastProcessedSeqNr.\n if (this.lastIgnoredSeqNr !== undefined && firstSeq === this.lastIgnoredSeqNr + 1) {\n return true;\n }\n if (this.lastProcessedSeqNr === undefined) {\n return firstSeq === 0;\n }\n // allow messages with both a seq we've just seen and\n // the next one to be dequeued as it can happen\n // that messages for other callIds (which could repeat seq)\n // are present in the queue\n // XXX: Not needed anymore when seq is scoped to call_id\n // see https://github.com/matrix-org/matrix-spec-proposals/pull/3401#discussion_r1097482166\n return firstSeq <= (this.lastProcessedSeqNr + 1);\n }\n\n dispose() {\n this.peerCall?.dispose();\n this.localMedia.dispose();\n this.logItem.finish();\n }\n}\n\nexport class Member {\n private connection?: MemberConnection;\n private expireTimeout?: Timeout;\n private errorBoundary = new ErrorBoundary(err => {\n this.options.emitUpdate(this, \"error\");\n if (this.connection) {\n // in case the error happens in code that does not log,\n // log it here to make sure it isn't swallowed\n this.connection.logItem.log(\"error at boundary\").catch(err);\n }\n });\n\n constructor(\n public member: RoomMember,\n private callDeviceMembership: CallDeviceMembership,\n private options: Options,\n updateMemberLog: ILogItem\n ) {\n this._renewExpireTimeout(updateMemberLog);\n }\n\n get error(): Error | undefined {\n return this.errorBoundary.error;\n }\n\n get usesFoci(): boolean {\n const activeFoci = this.callDeviceMembership[\"m.foci.active\"];\n return Array.isArray(activeFoci) && activeFoci.length > 0;\n }\n\n private _renewExpireTimeout(log: ILogItem) {\n this.expireTimeout?.dispose();\n this.expireTimeout = undefined;\n const expiresAt = memberExpiresAt(this.callDeviceMembership);\n if (typeof expiresAt !== \"number\") {\n return;\n }\n const expiresFromNow = Math.max(0, expiresAt - this.options.clock.now());\n log?.set(\"expiresIn\", expiresFromNow);\n // add 10ms to make sure isExpired returns true\n this.expireTimeout = this.options.clock.createTimeout(expiresFromNow + 10);\n this.expireTimeout.elapsed().then(\n () => { this.options.emitUpdate(this, \"isExpired\"); },\n (err) => { /* ignore abort error */ },\n );\n }\n\n /**\n * Gives access the log item for this item once joined to the group call.\n * The signalling for this member will be log in this item.\n * Can be used for call diagnostics while in the call.\n **/\n get logItem(): ILogItem | undefined {\n return this.connection?.logItem;\n }\n\n get remoteMedia(): RemoteMedia | undefined {\n return this.connection?.peerCall?.remoteMedia;\n }\n\n get isExpired(): boolean {\n // never consider a peer we're connected to, to be expired\n return !this.isConnected && isMemberExpired(this.callDeviceMembership, this.options.clock.now());\n }\n\n get remoteMuteSettings(): MuteSettings | undefined {\n return this.connection?.peerCall?.remoteMuteSettings;\n }\n\n get isConnected(): boolean {\n return this.connection?.peerCall?.state === CallState.Connected;\n }\n\n get userId(): string {\n return this.member.userId;\n }\n\n get deviceId(): string {\n return this.callDeviceMembership.device_id;\n }\n\n /** @internal, to emulate deviceKey properties when calling formatToDeviceMessagesPayload */ \n get user_id(): string {\n return this.userId;\n }\n \n /** @internal, to emulate deviceKey properties when calling formatToDeviceMessagesPayload */\n get device_id(): string {\n return this.deviceId;\n }\n\n /** session id of the member */\n get sessionId(): string {\n return this.callDeviceMembership.session_id;\n }\n\n get dataChannel(): any | undefined {\n return this.connection?.peerCall?.dataChannel;\n }\n\n /** @internal */\n connect(localMedia: LocalMedia, localMuteSettings: MuteSettings, turnServer: BaseObservableValue, memberLogItem: ILogItem): Promise | undefined {\n return this.errorBoundary.try(async () => {\n if (this.connection) {\n return;\n }\n // Safari can't send a MediaStream to multiple sources, so clone it\n const connection = new MemberConnection(\n localMedia.clone(),\n localMuteSettings,\n turnServer,\n memberLogItem\n );\n this.connection = connection;\n let connectLogItem: ILogItem | undefined;\n await connection.logItem.wrap(\"connect\", async log => {\n connectLogItem = log;\n await this.callIfNeeded(log);\n });\n return connectLogItem;\n });\n }\n\n private callIfNeeded(log: ILogItem): Promise {\n return log.wrap(\"callIfNeeded\", async log => {\n // otherwise wait for it to connect\n let shouldInitiateCall;\n // the lexicographically lower side initiates the call\n if (this.member.userId === this.options.ownUserId) {\n shouldInitiateCall = this.deviceId > this.options.ownDeviceId;\n } else {\n shouldInitiateCall = this.member.userId > this.options.ownUserId;\n }\n if (shouldInitiateCall) {\n const connection = this.connection!;\n connection.peerCall = this._createPeerCall(makeId(\"c\"));\n await connection.peerCall.call(\n connection.localMedia,\n connection.localMuteSettings,\n log\n );\n } else {\n log.set(\"wait_for_invite\", true);\n }\n });\n }\n\n /** @internal */\n disconnect(hangup: boolean): Promise | undefined {\n return this.errorBoundary.try(async () => {\n const {connection} = this;\n if (!connection) {\n return;\n }\n let disconnectLogItem: ILogItem | undefined;\n // if if not sending the hangup, still log disconnect\n await connection.logItem.wrap(\"disconnect\", async log => {\n disconnectLogItem = log;\n if (hangup && connection.peerCall) {\n await connection.peerCall.hangup(CallErrorCode.UserHangup, log);\n }\n });\n connection.dispose();\n this.connection = undefined;\n return disconnectLogItem;\n });\n }\n\n /** @internal */\n updateCallInfo(callDeviceMembership: CallDeviceMembership, causeItem: ILogItem) {\n this.errorBoundary.try(() => {\n this.callDeviceMembership = callDeviceMembership;\n this._renewExpireTimeout(causeItem);\n if (this.connection) {\n this.connection.logItem.refDetached(causeItem);\n }\n });\n }\n \n /** @internal */\n updateRoomMember(roomMember: RoomMember) {\n this.member = roomMember;\n // TODO: this emits an update during the writeSync phase, which we usually try to avoid\n this.options.emitUpdate(this);\n }\n\n /** @internal */\n emitUpdateFromPeerCall = async (peerCall: PeerCall, params: any, log: ILogItem): Promise => {\n const connection = this.connection!;\n if (peerCall.state === CallState.Ringing) {\n connection.logItem.wrap(\"ringing, answer peercall\", answerLog => {\n log.refDetached(answerLog);\n return peerCall.answer(connection.localMedia, connection.localMuteSettings, answerLog);\n });\n }\n else if (peerCall.state === CallState.Ended) {\n const hangupReason = peerCall.hangupReason;\n peerCall.dispose();\n connection.peerCall = undefined;\n if (hangupReason && !errorCodesWithoutRetry.includes(hangupReason)) {\n connection.retryCount += 1;\n const {retryCount} = connection;\n await connection.logItem.wrap({l: \"retry connection\", retryCount}, async retryLog => {\n log.refDetached(retryLog);\n if (retryCount <= 3) {\n await this.callIfNeeded(retryLog);\n } else {\n const disconnectLogItem = await this.disconnect(false);\n if (disconnectLogItem) {\n retryLog.refDetached(disconnectLogItem);\n }\n }\n });\n }\n }\n this.options.emitUpdate(this, params);\n }\n\n /** @internal */\n sendSignallingMessage = async (message: SignallingMessage, log: ILogItem): Promise => {\n const groupMessage = message as SignallingMessage;\n groupMessage.content.seq = this.connection!.outboundSeqCounter++;\n groupMessage.content.conf_id = this.options.confId;\n groupMessage.content.device_id = this.options.ownDeviceId;\n groupMessage.content.party_id = this.options.ownDeviceId;\n groupMessage.content.sender_session_id = this.options.sessionId;\n groupMessage.content.dest_session_id = this.sessionId;\n let payload;\n let type: string = message.type;\n const encryptedMessages = await this.options.encryptDeviceMessage(this.member.userId, this.deviceId, groupMessage, log);\n if (encryptedMessages) {\n payload = formatToDeviceMessagesPayload(encryptedMessages);\n type = \"m.room.encrypted\";\n } else {\n // device needs deviceId and userId\n payload = formatToDeviceMessagesPayload([{content: groupMessage.content, device: this}]);\n }\n // TODO: remove this for release\n log.set(\"payload\", groupMessage.content);\n const request = this.options.hsApi.sendToDevice(\n type,\n payload,\n makeTxnId(),\n {log}\n );\n await request.response();\n }\n\n /** @internal */\n handleDeviceMessage(message: SignallingMessage, syncLog: ILogItem): void {\n this.errorBoundary.try(() => {\n syncLog.wrap({l: \"Member.handleDeviceMessage\", type: message.type, seq: message.content?.seq}, log => {\n const {connection} = this;\n if (connection) {\n const destSessionId = message.content.dest_session_id;\n if (destSessionId !== this.options.sessionId) {\n const logItem = connection.logItem.log({l: \"ignoring to_device event with wrong session_id\", destSessionId, type: message.type});\n log.refDetached(logItem);\n return;\n }\n // if there is no peerCall, we either create it with an invite and Handle is implied or we'll ignore it \n if (connection.peerCall) {\n const action = connection.peerCall.getMessageAction(message);\n // deal with glare and replacing the call before creating new calls\n if (action === IncomingMessageAction.InviteGlare) {\n const {shouldReplace, log} = connection.peerCall.handleInviteGlare(message, this.deviceId, connection.logItem);\n if (log) {\n log.refDetached(log);\n }\n if (shouldReplace) {\n connection.peerCall.dispose();\n connection.peerCall = undefined;\n }\n }\n }\n // create call on invite\n if (message.type === EventType.Invite && !connection.peerCall) {\n connection.peerCall = this._createPeerCall(message.content.call_id);\n }\n // enqueue\n const idx = sortedIndex(connection.queuedSignallingMessages, message, (a, b) => a.content.seq - b.content.seq);\n connection.queuedSignallingMessages.splice(idx, 0, message);\n // dequeue as much as we can\n let hasNewMessageBeenDequeued = false;\n if (connection.peerCall) {\n hasNewMessageBeenDequeued = this.dequeueSignallingMessages(connection, connection.peerCall, message, log);\n }\n if (!hasNewMessageBeenDequeued) {\n log.refDetached(connection.logItem.log({l: \"queued message\", type: message.type, seq: message.content.seq, idx}));\n }\n } else {\n // TODO: the right thing to do here would be to at least enqueue the message rather than drop it,\n // and if it's up to the other end to send the invite and the type is an invite to actually\n // call connect and assume the m.call.member state update is on its way?\n syncLog.log({l: \"member not connected\", userId: this.userId, deviceId: this.deviceId});\n }\n });\n });\n }\n\n private dequeueSignallingMessages(connection: MemberConnection, peerCall: PeerCall, newMessage: SignallingMessage, syncLog: ILogItem): boolean {\n let hasNewMessageBeenDequeued = false;\n while (connection.canDequeueNextSignallingMessage) {\n const message = connection.queuedSignallingMessages.shift()!;\n const isNewMsg = message === newMessage;\n hasNewMessageBeenDequeued = hasNewMessageBeenDequeued || isNewMsg;\n syncLog.wrap(isNewMsg ? \"process message\" : \"dequeue message\", log => {\n const seq = message.content?.seq;\n log.set(\"seq\", seq);\n log.set(\"type\", message.type);\n // ignore items in the queue that should not be handled and prevent\n // the lastProcessedSeqNr being corrupted with the `seq` for other call ids\n // XXX: Not needed anymore when seq is scoped to call_id\n // see https://github.com/matrix-org/matrix-spec-proposals/pull/3401#discussion_r1097482166\n const action = peerCall.getMessageAction(message);\n if (action === IncomingMessageAction.Handle) {\n const item = peerCall.handleIncomingSignallingMessage(message, this.deviceId, connection.logItem);\n log.refDetached(item);\n connection.lastProcessedSeqNr = seq;\n } else {\n log.set(\"ignored\", true);\n connection.lastIgnoredSeqNr = seq;\n }\n });\n }\n return hasNewMessageBeenDequeued;\n }\n\n /** @internal */\n async setMedia(localMedia: LocalMedia, previousMedia: LocalMedia): Promise {\n return this.errorBoundary.try(async () => {\n const {connection} = this;\n if (connection) {\n connection.localMedia = localMedia.replaceClone(connection.localMedia, previousMedia);\n await connection.peerCall?.setMedia(connection.localMedia, connection.logItem);\n }\n });\n }\n\n async setMuted(muteSettings: MuteSettings): Promise {\n return this.errorBoundary.try(async () => {\n const {connection} = this;\n if (connection) {\n connection.localMuteSettings = muteSettings;\n await connection.peerCall?.setMuted(muteSettings, connection.logItem);\n }\n });\n }\n\n private _createPeerCall(callId: string): PeerCall {\n const connection = this.connection!;\n return new PeerCall(callId, Object.assign({}, this.options, {\n errorBoundary: this.errorBoundary,\n emitUpdate: this.emitUpdateFromPeerCall,\n sendSignallingMessage: this.sendSignallingMessage,\n turnServer: connection.turnServer\n }), connection.logItem);\n }\n\n dispose() {\n this.connection?.dispose();\n this.connection = undefined;\n this.expireTimeout?.dispose();\n this.expireTimeout = undefined;\n // ensure the emitUpdate callback can't be called anymore\n this.options.emitUpdate = () => {};\n }\n}\n\nexport function memberExpiresAt(callDeviceMembership: CallDeviceMembership): number | undefined {\n const expiresAt = callDeviceMembership[\"expires_ts\"];\n if (Number.isSafeInteger(expiresAt)) {\n return expiresAt;\n }\n}\n\nexport function isMemberExpired(callDeviceMembership: CallDeviceMembership, now: number, margin: number = 0) {\n const expiresAt = memberExpiresAt(callDeviceMembership);\n return typeof expiresAt === \"number\" ? ((expiresAt + margin) <= now) : true;\n}\n\nimport {ObservableValue} from \"../../../observable/value\";\nimport {Clock as MockClock} from \"../../../mocks/Clock\";\nimport {Instance as NullLoggerInstance} from \"../../../logging/NullLogger\";\n\nexport function tests() {\n \n class MockMedia {\n clone(): MockMedia { return this; }\n }\n\n class MockPeerConn {\n addEventListener() {}\n removeEventListener() {}\n setConfiguration() {}\n setRemoteDescription() {}\n getReceivers() { return [{}]; } // non-empty array\n getSenders() { return []; }\n addTrack() { return {}; }\n removeTrack() {}\n close() {}\n }\n return {\n \"test queue doesn't get blocked by enqueued, then ignored device message\": assert => {\n // XXX we might want to refactor the queue code a bit so it's easier to test\n // without having to provide so many mocks\n const clock = new MockClock();\n // setup logging\n const logger = NullLoggerInstance;\n // const logger = new Logger({platform: {clock, random: Math.random}});\n // logger.addReporter(new ConsoleReporter());\n \n // create member\n const callDeviceMembership = {\n [\"device_id\"]: \"BVPIHSKXFC\",\n [\"session_id\"]: \"s1d5863f41ec5a5\",\n [\"expires_ts\"]: 123,\n feeds: [{purpose: \"m.usermedia\"}]\n };\n const roomMember = RoomMember.fromUserId(\"!abc\", \"@bruno4:matrix.org\", \"join\");\n const turnServer = new ObservableValue({}) as ObservableValue;\n // @ts-ignore\n const options = {\n confId: \"conf\",\n ownUserId: \"@foobaraccount2:matrix.org\",\n ownDeviceId: \"CMLEZSARRT\",\n sessionId: \"s1cece7088b9d35\",\n clock,\n emitUpdate: () => {},\n webRTC: {\n prepareSenderForPurpose: () => {},\n createPeerConnection() {\n return new MockPeerConn();\n }\n }\n } as Options;\n const member = new Member(roomMember, callDeviceMembership, options, logger.child(\"member\"));\n member.connect(new MockMedia() as LocalMedia, new MuteSettings(), turnServer, logger.child(\"connect\"));\n // pretend we've already received 3 messages\n // @ts-ignore\n member.connection!.lastProcessedSeqNr = 2;\n // send hangup with seq=3, this will enqueue the message because there is no peerCall\n // as it's up to @bruno4:matrix.org to send the invite\n const hangup = {\n type: EventType.Hangup,\n content: {\n \"call_id\": \"c0ac1b0e37afe73\",\n \"version\": 1,\n \"reason\": \"invite_timeout\",\n \"seq\": 3,\n \"conf_id\": \"conf-16a120796440a6\",\n \"device_id\": \"BVPIHSKXFC\",\n \"party_id\": \"BVPIHSKXFC\",\n \"sender_session_id\": \"s1d5863f41ec5a5\",\n \"dest_session_id\": \"s1cece7088b9d35\"\n }\n } as SignallingMessage;\n member.handleDeviceMessage(hangup, logger.child(\"handle hangup\"));\n // Send an invite with seq=4, this will create a new peer call with a the call id\n // when dequeueing the hangup from before, it'll get ignored because it is\n // for the previous call id.\n const invite = {\n type: EventType.Invite,\n content: {\n \"call_id\": \"c1175b12d559fb1\",\n \"offer\": {\n \"type\": \"offer\",\n \"sdp\": \"...\"\n },\n \"org.matrix.msc3077.sdp_stream_metadata\": {\n \"60087b60-487e-4fa0-8229-b232c18e1332\": {\n \"purpose\": \"m.usermedia\",\n \"audio_muted\": false,\n \"video_muted\": false\n }\n },\n \"version\": 1,\n \"lifetime\": 60000,\n \"seq\": 4,\n \"conf_id\": \"conf-16a120796440a6\",\n \"device_id\": \"BVPIHSKXFC\",\n \"party_id\": \"BVPIHSKXFC\",\n \"sender_session_id\": \"s1d5863f41ec5a5\",\n \"dest_session_id\": \"s1cece7088b9d35\"\n }\n } as SignallingMessage;\n member.handleDeviceMessage(invite, logger.child(\"handle invite\"));\n // @ts-ignore\n assert.equal(member.connection!.queuedSignallingMessages.length, 0);\n // logger.reporters[0].printOpenItems();\n }\n };\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableMap} from \"../../../observable/map\";\nimport {Member, isMemberExpired, memberExpiresAt} from \"./Member\";\nimport {LocalMedia} from \"../LocalMedia\";\nimport {MuteSettings, CALL_LOG_TYPE, CALL_MEMBER_VALIDITY_PERIOD_MS, mute} from \"../common\";\nimport {MemberChange, RoomMember} from \"../../room/members/RoomMember\";\nimport {EventEmitter} from \"../../../utils/EventEmitter\";\nimport {EventType, CallIntent, CallType} from \"../callEventTypes\";\nimport { ErrorBoundary } from \"../../../utils/ErrorBoundary\";\n\nimport type {Options as MemberOptions} from \"./Member\";\nimport type {TurnServerSource} from \"../TurnServerSource\";\nimport type {BaseObservableMap} from \"../../../observable/map\";\nimport type {Track} from \"../../../platform/types/MediaDevices\";\nimport type {SignallingMessage, MGroupCallBase, CallMembership, CallMemberContent, CallDeviceMembership} from \"../callEventTypes\";\nimport type {Room} from \"../../room/Room\";\nimport type {StateEvent} from \"../../storage/types\";\nimport type {Platform} from \"../../../platform/web/Platform\";\nimport type {EncryptedMessage} from \"../../e2ee/olm/Encryption\";\nimport type {ILogItem, ILogger} from \"../../../logging/types\";\nimport type {Storage} from \"../../storage/idb/Storage\";\nimport type {BaseObservableValue} from \"../../../observable/value\";\nimport type {Clock, Timeout} from \"../../../platform/web/dom/Clock\";\n\nexport enum GroupCallState {\n Fledgling = \"fledgling\",\n Creating = \"creating\",\n Created = \"created\",\n Joining = \"joining\",\n Joined = \"joined\",\n}\n\nfunction getMemberKey(userId: string, deviceId: string) {\n return JSON.stringify(userId)+`,`+JSON.stringify(deviceId);\n}\n\nfunction memberKeyIsForUser(key: string, userId: string) {\n return key.startsWith(JSON.stringify(userId)+`,`);\n}\n\nfunction getDeviceFromMemberKey(key: string): string {\n return JSON.parse(`[${key}]`)[1];\n}\n\nexport type Options = Omit & {\n emitUpdate: (call: GroupCall, params?: any) => void;\n encryptDeviceMessage: (roomId: string, userId: string, deviceId: string, message: SignallingMessage, log: ILogItem) => Promise,\n storage: Storage,\n random: () => number,\n logger: ILogger,\n turnServerSource: TurnServerSource\n};\n\nclass JoinedData {\n public renewMembershipTimeout?: Timeout;\n\n constructor(\n public readonly logItem: ILogItem,\n public readonly membersLogItem: ILogItem,\n public localMedia: LocalMedia,\n public localPreviewMedia: LocalMedia,\n public localMuteSettings: MuteSettings,\n public readonly turnServer: BaseObservableValue\n ) {}\n\n dispose() {\n this.localMedia.dispose();\n this.localPreviewMedia.dispose();\n this.logItem.finish();\n this.renewMembershipTimeout?.dispose();\n }\n}\n\nexport class GroupCall extends EventEmitter<{change: never}> {\n private readonly _members: ObservableMap = new ObservableMap();\n private _memberOptions: MemberOptions;\n private _state: GroupCallState;\n private bufferedDeviceMessages = new Map>>();\n /** Set between calling join and leave. */\n private joinedData?: JoinedData;\n private errorBoundary = new ErrorBoundary(err => {\n this.emitChange();\n if (this.joinedData) {\n // in case the error happens in code that does not log,\n // log it here to make sure it isn't swallowed\n this.joinedData.logItem.log(\"error at boundary\").catch(err);\n console.error(err);\n }\n });\n\n constructor(\n public readonly id: string,\n public readonly isLoadedFromStorage: boolean,\n newCall: boolean,\n private startTime: number | undefined,\n private callContent: Record,\n public readonly roomId: string,\n private readonly options: Options,\n ) {\n super();\n this._state = newCall ? GroupCallState.Fledgling : GroupCallState.Created;\n this._memberOptions = Object.assign({}, options, {\n confId: this.id,\n emitUpdate: member => {\n const memberKey = getMemberKey(member.userId, member.deviceId);\n // only remove expired members to whom we're not already connected\n if (member.isExpired && !member.isConnected) {\n const logItem = this.options.logger.log({\n l: \"removing expired member from call\",\n memberKey,\n callId: this.id\n })\n member.logItem?.refDetached(logItem);\n member.dispose();\n this._members.remove(memberKey);\n } else {\n this._members.update(memberKey);\n }\n },\n encryptDeviceMessage: (userId: string, deviceId: string, message: SignallingMessage, log) => {\n return this.options.encryptDeviceMessage(this.roomId, userId, deviceId, message, log);\n }\n });\n }\n\n get localMedia(): LocalMedia | undefined { return this.joinedData?.localMedia; }\n get localPreviewMedia(): LocalMedia | undefined { return this.joinedData?.localPreviewMedia; }\n get members(): BaseObservableMap { return this._members; }\n\n get isTerminated(): boolean {\n return !!this.callContent?.[\"m.terminated\"];\n }\n\n get usesFoci(): boolean {\n for (const member of this._members.values()) {\n if (member.usesFoci) {\n return true;\n }\n }\n return false;\n }\n\n get duration(): number | undefined {\n if (typeof this.startTime === \"number\") {\n return (this.options.clock.now() - this.startTime);\n }\n }\n\n get isRinging(): boolean {\n return this._state === GroupCallState.Created && this.intent === \"m.ring\" && !this.isMember(this.options.ownUserId);\n }\n\n get name(): string {\n return this.callContent?.[\"m.name\"];\n }\n\n get intent(): CallIntent {\n return this.callContent?.[\"m.intent\"];\n }\n\n get type(): CallType {\n return this.callContent?.[\"m.type\"];\n }\n\n /**\n * Gives access the log item for this call while joined.\n * Can be used for call diagnostics while in the call.\n **/\n get logItem(): ILogItem | undefined {\n return this.joinedData?.logItem;\n }\n\n get error(): Error | undefined {\n return this.errorBoundary.error;\n }\n\n join(localMedia: LocalMedia, log?: ILogItem): Promise {\n return this.options.logger.wrapOrRun(log, \"Call.join\", async joinLog => {\n if (this._state !== GroupCallState.Created || this.joinedData || this.usesFoci) {\n localMedia.dispose();\n return;\n }\n const logItem = this.options.logger.child({\n l: \"Call.connection\",\n t: CALL_LOG_TYPE,\n id: this.id,\n ownSessionId: this.options.sessionId\n });\n const turnServer = await this.options.turnServerSource.getSettings(logItem);\n const membersLogItem = logItem.child(\"member connections\");\n const localMuteSettings = new MuteSettings();\n localMuteSettings.updateTrackInfo(localMedia.userMedia);\n const localPreviewMedia = localMedia.asPreview();\n const joinedData = new JoinedData(\n logItem,\n membersLogItem,\n localMedia,\n localPreviewMedia,\n localMuteSettings,\n turnServer\n );\n this.joinedData = joinedData;\n await joinedData.logItem.wrap(\"join\", async log => {\n joinLog.refDetached(log);\n this._state = GroupCallState.Joining;\n this.emitChange();\n await log.wrap(\"update member state\", async log => {\n const memberContent = await this._createMemberPayload(true);\n log.set(\"payload\", memberContent);\n // send m.call.member state event\n const request = this.options.hsApi.sendState(this.roomId, EventType.GroupCallMember, this.options.ownUserId, memberContent, {log});\n await request.response();\n this.emitChange();\n });\n // send invite to all members that are < my userId\n for (const member of this._members.values()) {\n this.connectToMember(member, joinedData, log);\n }\n });\n });\n }\n\n async setMedia(localMedia: LocalMedia): Promise {\n if ((this._state === GroupCallState.Joining || this._state === GroupCallState.Joined) && this.joinedData) {\n const oldMedia = this.joinedData.localMedia;\n this.joinedData.localMedia = localMedia;\n this.joinedData.localPreviewMedia?.dispose();\n this.joinedData.localPreviewMedia = localMedia.asPreview();\n // reflect the fact we gained or lost local tracks in the local mute settings\n // and update the track info so PeerCall can use it to send up to date metadata,\n this.joinedData.localMuteSettings.updateTrackInfo(localMedia.userMedia);\n this.emitChange(); //allow listeners to see new media/mute settings\n // TODO: if setMedia fails on one of the members, we should revert to the old media\n // on the members processed so far, and show an error that we could not set the new media\n // for this, we will need to remove the usage of the errorBoundary in member.setMedia.\n await Promise.all(Array.from(this._members.values()).map(m => {\n return m.setMedia(localMedia, oldMedia);\n }));\n oldMedia?.dispose();\n }\n }\n\n async setMuted(muteSettings: MuteSettings): Promise {\n const {joinedData} = this;\n if (!joinedData) {\n return;\n }\n const prevMuteSettings = joinedData.localMuteSettings;\n // we still update the mute settings if nothing changed because\n // you might be muted because you don't have a track or because\n // you actively chosen to mute\n // (which we want to respect in the future when you add a track)\n muteSettings.updateTrackInfo(joinedData.localMedia.userMedia);\n joinedData.localMuteSettings = muteSettings;\n if (!prevMuteSettings.equals(muteSettings)) {\n // Mute our copies of LocalMedias;\n // otherwise the camera lights will still be on.\n if (this.localPreviewMedia) {\n mute(this.localPreviewMedia, muteSettings, this.joinedData!.logItem);\n }\n if (this.localMedia) {\n mute(this.localMedia, muteSettings, this.joinedData!.logItem);\n }\n // TODO: if setMuted fails on one of the members, we should revert to the old media\n // on the members processed so far, and show an error that we could not set the new media\n // for this, we will need to remove the usage of the errorBoundary in member.setMuted.\n await Promise.all(Array.from(this._members.values()).map(m => {\n return m.setMuted(joinedData.localMuteSettings);\n }));\n this.emitChange();\n }\n }\n\n get muteSettings(): MuteSettings | undefined {\n return this.joinedData?.localMuteSettings;\n }\n\n get hasJoined() {\n return this._state === GroupCallState.Joining || this._state === GroupCallState.Joined;\n }\n\n async leave(log?: ILogItem): Promise {\n await this.options.logger.wrapOrRun(log, \"Call.leave\", async log => {\n const {joinedData} = this;\n if (!joinedData) {\n return;\n }\n try {\n joinedData.renewMembershipTimeout?.dispose();\n joinedData.renewMembershipTimeout = undefined;\n const memberContent = await this._createMemberPayload(false);\n // send m.call.member state event\n if (memberContent) {\n const request = this.options.hsApi.sendState(this.roomId, EventType.GroupCallMember, this.options.ownUserId, memberContent, {log});\n await request.response();\n // our own user isn't included in members, so not in the count\n if ((this.intent === CallIntent.Ring || this.intent === CallIntent.Prompt) && this._members.size === 0) {\n await this.terminate(log);\n }\n } else {\n log.set(\"already_left\", true);\n }\n } finally {\n // disconnect is called both from the sync loop and from methods like this one that\n // are called from the view model. We want errors during the sync loop being caught\n // by the errorboundary, but since leave is called from the view model, we want\n // the error to be thrown. So here we check if disconnect succeeded, and if not\n // we rethrow the error put into the errorBoundary.\n if(!this.disconnect(log)) {\n throw this.errorBoundary.error;\n }\n }\n });\n }\n\n private terminate(log?: ILogItem): Promise {\n return this.options.logger.wrapOrRun(log, {l: \"terminate call\", t: CALL_LOG_TYPE}, async log => {\n if (this._state === GroupCallState.Fledgling) {\n return;\n }\n const request = this.options.hsApi.sendState(this.roomId, EventType.GroupCall, this.id, Object.assign({}, this.callContent, {\n \"m.terminated\": true\n }), {log});\n await request.response();\n });\n }\n\n /** @internal */\n create(type: CallType, log: ILogItem): Promise {\n return log.wrap({l: \"create call\", t: CALL_LOG_TYPE}, async log => {\n if (this._state !== GroupCallState.Fledgling) {\n return;\n }\n this._state = GroupCallState.Creating;\n this.emitChange();\n this.callContent = Object.assign({\n \"m.type\": type,\n }, this.callContent);\n const request = this.options.hsApi.sendState(this.roomId, EventType.GroupCall, this.id, this.callContent!, {log});\n await request.response();\n this._state = GroupCallState.Created;\n this.emitChange();\n });\n }\n\n /** @internal */\n updateCallEvent(event: StateEvent, syncLog: ILogItem) {\n this.errorBoundary.try(() => {\n syncLog.wrap({l: \"update call\", t: CALL_LOG_TYPE, id: this.id}, log => {\n\n if (typeof this.startTime !== \"number\") {\n this.startTime = event.origin_server_ts;\n }\n this.callContent = event.content;\n if (this._state === GroupCallState.Creating) {\n this._state = GroupCallState.Created;\n }\n log.set(\"status\", this._state);\n this.emitChange();\n });\n });\n }\n\n /** @internal */\n updateRoomMembers(memberChanges: Map) {\n this.errorBoundary.try(() => {\n for (const change of memberChanges.values()) {\n const {member} = change;\n for (const callMember of this._members.values()) {\n // find all call members for a room member (can be multiple, for every device)\n if (callMember.userId === member.userId) {\n callMember.updateRoomMember(member);\n }\n }\n }\n });\n }\n\n /** @internal */\n updateMembership(userId: string, roomMember: RoomMember, callMembership: CallMembership, syncLog: ILogItem) {\n this.errorBoundary.try(async () => {\n await syncLog.wrap({l: \"update call membership\", t: CALL_LOG_TYPE, id: this.id, userId}, async log => {\n const now = this.options.clock.now();\n const devices = callMembership[\"m.devices\"];\n const previousDeviceIds = this.getDeviceIdsForUserId(userId);\n for (const device of devices) {\n const deviceId = device.device_id;\n const memberKey = getMemberKey(userId, deviceId);\n if (userId === this.options.ownUserId && deviceId === this.options.ownDeviceId) {\n log.wrap(\"update own membership\", log => {\n if (this.hasJoined) {\n if (this.joinedData) {\n this.joinedData.logItem.refDetached(log);\n }\n this._setupRenewMembershipTimeout(device, log);\n }\n if (this._state === GroupCallState.Joining) {\n log.set(\"joined\", true);\n this._state = GroupCallState.Joined;\n this.emitChange();\n }\n });\n } else {\n await log.wrap({l: \"update device membership\", id: memberKey, sessionId: device.session_id}, async log => {\n if (isMemberExpired(device, now)) {\n log.set(\"expired\", true);\n const member = this._members.get(memberKey);\n if (member) {\n member.dispose();\n this._members.remove(memberKey);\n log.set(\"removed\", true);\n } else {\n // We don't want to pollute the logs with all the expired members.\n // This can be an issue for long lived calls that have had a large number\n // of users join and leave at some point in time.\n log.discard();\n }\n return;\n }\n let member = this._members.get(memberKey);\n const sessionIdChanged = member && member.sessionId !== device.session_id;\n if (member && !sessionIdChanged) {\n log.set(\"update\", true);\n member.updateCallInfo(device, log);\n } else {\n if (member && sessionIdChanged) {\n log.set(\"removedSessionId\", member.sessionId);\n const disconnectLogItem = await member.disconnect(false);\n if (disconnectLogItem) {\n log.refDetached(disconnectLogItem);\n }\n member.dispose();\n this._members.remove(memberKey);\n member = undefined;\n }\n log.set(\"add\", true);\n member = new Member(\n roomMember,\n device, this._memberOptions,\n log\n );\n this._members.add(memberKey, member);\n if (this.joinedData) {\n this.connectToMember(member, this.joinedData, log);\n }\n }\n // flush pending messages, either after having created the member,\n // or updated the session id with updateCallInfo\n this.flushPendingIncomingDeviceMessages(member, log);\n });\n }\n }\n\n const newDeviceIds = new Set(devices.map(call => call.device_id));\n // remove user as member of any calls not present anymore\n for (const previousDeviceId of previousDeviceIds) {\n if (!newDeviceIds.has(previousDeviceId)) {\n this.removeMemberDevice(userId, previousDeviceId, log);\n }\n }\n if (userId === this.options.ownUserId && !newDeviceIds.has(this.options.ownDeviceId)) {\n this.removeOwnDevice(log);\n }\n });\n });\n }\n\n /** @internal */\n removeMembership(userId: string, syncLog: ILogItem) {\n this.errorBoundary.try(() => {\n const deviceIds = this.getDeviceIdsForUserId(userId);\n syncLog.wrap({\n l: \"remove call member\",\n t: CALL_LOG_TYPE,\n id: this.id,\n userId\n }, log => {\n for (const deviceId of deviceIds) {\n this.removeMemberDevice(userId, deviceId, log);\n }\n if (userId === this.options.ownUserId) {\n this.removeOwnDevice(log);\n }\n });\n });\n }\n\n private flushPendingIncomingDeviceMessages(member: Member, log: ILogItem) {\n const memberKey = getMemberKey(member.userId, member.deviceId);\n const bufferedMessages = this.bufferedDeviceMessages.get(memberKey);\n // check if we have any pending message for the member with (userid, deviceid, sessionid)\n if (bufferedMessages) {\n for (const message of bufferedMessages) {\n if (message.content.sender_session_id === member.sessionId) {\n member.handleDeviceMessage(message, log);\n bufferedMessages.delete(message);\n }\n }\n if (bufferedMessages.size === 0) {\n this.bufferedDeviceMessages.delete(memberKey);\n }\n }\n }\n\n private getDeviceIdsForUserId(userId: string): string[] {\n return Array.from(this._members.keys())\n .filter(key => memberKeyIsForUser(key, userId))\n .map(key => getDeviceFromMemberKey(key));\n }\n\n private isMember(userId: string): boolean {\n return Array.from(this._members.keys()).some(key => memberKeyIsForUser(key, userId));\n }\n\n private removeOwnDevice(log: ILogItem) {\n log.wrap(\"remove own membership\", log => {\n this.disconnect(log);\n });\n }\n\n /** @internal */\n disconnect(log: ILogItem): Promise | true {\n return this.errorBoundary.try(async () => {\n if (this.hasJoined) {\n for (const member of this._members.values()) {\n const disconnectLogItem = await member.disconnect(true);\n if (disconnectLogItem) {\n log.refDetached(disconnectLogItem);\n }\n }\n this._state = GroupCallState.Created;\n }\n this.joinedData?.dispose();\n this.joinedData = undefined;\n this.emitChange();\n }, false) || true;\n }\n\n /** @internal */\n private async removeMemberDevice(userId: string, deviceId: string, log: ILogItem) {\n const memberKey = getMemberKey(userId, deviceId);\n await log.wrap({l: \"remove device member\", id: memberKey}, async log => {\n const member = this._members.get(memberKey);\n if (member) {\n log.set(\"leave\", true);\n const disconnectLogItem = await member.disconnect(false);\n if (disconnectLogItem) {\n log.refDetached(disconnectLogItem);\n }\n member.dispose();\n this._members.remove(memberKey);\n }\n });\n }\n\n /** @internal */\n handleDeviceMessage(message: SignallingMessage, userId: string, deviceId: string, syncLog: ILogItem) {\n this.errorBoundary.try(() => {\n // TODO: return if we are not membering to the call\n const key = getMemberKey(userId, deviceId);\n let member = this._members.get(key);\n if (member && message.content.sender_session_id === member.sessionId) {\n member.handleDeviceMessage(message, syncLog);\n } else {\n const item = syncLog.log({\n l: \"call: buffering to_device message, member not found\",\n t: CALL_LOG_TYPE,\n id: this.id,\n userId,\n deviceId,\n sessionId: message.content.sender_session_id,\n type: message.type\n });\n // we haven't received the m.call.member yet for this caller (or with this session id).\n // buffer the device messages or create the member/call as it should arrive in a moment\n let messages = this.bufferedDeviceMessages.get(key);\n if (!messages) {\n messages = new Set();\n this.bufferedDeviceMessages.set(key, messages);\n }\n messages.add(message);\n }\n });\n }\n\n private async _createMemberPayload(includeOwn: boolean): Promise {\n const {storage} = this.options;\n const txn = await storage.readTxn([storage.storeNames.roomState]);\n const stateEvent = await txn.roomState.get(this.roomId, EventType.GroupCallMember, this.options.ownUserId);\n const stateContent: CallMemberContent = stateEvent?.event?.content as CallMemberContent ?? {\n [\"m.calls\"]: []\n };\n let callsInfo = stateContent[\"m.calls\"];\n let callInfo = callsInfo.find(c => c[\"m.call_id\"] === this.id);\n if (!callInfo) {\n callInfo = {\n [\"m.call_id\"]: this.id,\n [\"m.devices\"]: []\n };\n callsInfo.push(callInfo);\n }\n const now = this.options.clock.now();\n callInfo[\"m.devices\"] = callInfo[\"m.devices\"].filter(d => {\n // remove our own device (to add it again below)\n if (d[\"device_id\"] === this.options.ownDeviceId) {\n return false;\n }\n // also remove any expired devices (+ the validity period added again)\n if (memberExpiresAt(d) === undefined || isMemberExpired(d, now, CALL_MEMBER_VALIDITY_PERIOD_MS)) {\n return false;\n }\n return true;\n });\n if (includeOwn) {\n callInfo[\"m.devices\"].push({\n [\"device_id\"]: this.options.ownDeviceId,\n [\"session_id\"]: this.options.sessionId,\n [\"expires_ts\"]: now + CALL_MEMBER_VALIDITY_PERIOD_MS,\n feeds: [{purpose: \"m.usermedia\"}]\n });\n }\n // filter out empty call membership\n stateContent[\"m.calls\"] = callsInfo.filter(c => c[\"m.devices\"].length !== 0);\n return stateContent;\n }\n\n private async connectToMember(member: Member, joinedData: JoinedData, log: ILogItem) {\n const memberKey = getMemberKey(member.userId, member.deviceId);\n const logItem = joinedData.membersLogItem.child({\n l: \"member\",\n id: memberKey,\n sessionId: member.sessionId\n });\n await log.wrap({l: \"connect\", id: memberKey}, async log => {\n const connectItem = await member.connect(\n joinedData.localMedia,\n joinedData.localMuteSettings,\n joinedData.turnServer,\n logItem\n );\n if (connectItem) {\n log.refDetached(connectItem);\n }\n });\n }\n\n protected emitChange() {\n this.emit(\"change\");\n this.options.emitUpdate(this);\n }\n\n private _setupRenewMembershipTimeout(callDeviceMembership: CallDeviceMembership, log: ILogItem) {\n const {joinedData} = this;\n if (!joinedData) {\n return;\n }\n joinedData.renewMembershipTimeout?.dispose();\n joinedData.renewMembershipTimeout = undefined;\n const expiresAt = memberExpiresAt(callDeviceMembership);\n if (typeof expiresAt !== \"number\") {\n return;\n }\n const expiresFromNow = expiresAt - this.options.clock.now();\n // renew 1 to 5 minutes (8.3% of 1h, but min 10s) before expiring\n // do it a bit beforehand and somewhat random to not collide with\n // other clients trying to renew as well\n const timeToRenewBeforeExpiration = Math.max(10000, Math.ceil((0.2 +(this.options.random() * 0.8)) * (0.08333 * CALL_MEMBER_VALIDITY_PERIOD_MS)));\n const renewFromNow = Math.max(0, expiresFromNow - timeToRenewBeforeExpiration);\n log.set(\"expiresIn\", expiresFromNow);\n log.set(\"renewIn\", renewFromNow);\n joinedData.renewMembershipTimeout = this.options.clock.createTimeout(renewFromNow);\n joinedData.renewMembershipTimeout.elapsed().then(\n () => {\n joinedData.logItem.wrap(\"renew membership\", async log => {\n const memberContent = await this._createMemberPayload(true);\n log.set(\"payload\", memberContent);\n // send m.call.member state event\n const request = this.options.hsApi.sendState(this.roomId, EventType.GroupCallMember, this.options.ownUserId, memberContent, {log});\n await request.response();\n });\n },\n () => { /* assume we're swallowing AbortError from dispose above */ }\n );\n }\n\n dispose() {\n this.joinedData?.dispose();\n for (const member of this._members.values()) {\n member.dispose();\n }\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {RetainedObservableValue} from \"../../observable/value\";\n\nimport type {HomeServerApi} from \"../net/HomeServerApi\";\nimport type {IHomeServerRequest} from \"../net/HomeServerRequest\";\nimport type {BaseObservableValue, ObservableValue} from \"../../observable/value\";\nimport type {Clock, Timeout} from \"../../platform/web/dom/Clock\";\nimport type {ILogItem} from \"../../logging/types\";\n\ntype TurnServerSettings = {\n uris: string[],\n username: string,\n password: string,\n ttl: number\n};\n\nconst DEFAULT_TTL = 5 * 60; // 5min\nconst DEFAULT_SETTINGS: RTCIceServer = {\n urls: [\"stun:turn.matrix.org\"],\n username: \"\",\n credential: \"\",\n};\n\nexport class TurnServerSource {\n private currentObservable?: ObservableValue;\n private pollTimeout?: Timeout;\n private pollRequest?: IHomeServerRequest;\n private isPolling = false;\n\n constructor(\n private hsApi: HomeServerApi,\n private clock: Clock,\n private defaultSettings: RTCIceServer = DEFAULT_SETTINGS\n ) {}\n\n getSettings(log: ILogItem): Promise> {\n return log.wrap(\"get turn server\", async log => {\n if (!this.isPolling) {\n const settings = await this.doRequest(log);\n const iceServer = settings ? toIceServer(settings) : this.defaultSettings;\n log.set(\"iceServer\", iceServer);\n if (this.currentObservable) {\n this.currentObservable.set(iceServer);\n } else {\n this.currentObservable = new RetainedObservableValue(iceServer, \n () => {\n this.stopPollLoop();\n },\n () => {\n // start loop on first subscribe\n this.runLoop(settings?.ttl ?? DEFAULT_TTL);\n });\n }\n }\n return this.currentObservable!;\n });\n }\n\n private async runLoop(initialTtl: number): Promise {\n let ttl = initialTtl;\n this.isPolling = true;\n while(this.isPolling) {\n try {\n this.pollTimeout = this.clock.createTimeout(ttl * 1000);\n await this.pollTimeout.elapsed();\n this.pollTimeout = undefined;\n const settings = await this.doRequest(undefined);\n if (settings) {\n const iceServer = toIceServer(settings);\n if (shouldUpdate(this.currentObservable!, iceServer)) {\n this.currentObservable!.set(iceServer);\n }\n if (settings.ttl > 0) {\n ttl = settings.ttl;\n } else {\n // stop polling is settings are good indefinitely\n this.stopPollLoop();\n }\n } else {\n ttl = DEFAULT_TTL;\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n /* ignore, the loop will exit because isPolling is false */\n } else {\n // TODO: log error\n }\n }\n }\n }\n\n private async doRequest(log: ILogItem | undefined): Promise {\n try {\n this.pollRequest = this.hsApi.getTurnServer({log});\n const settings = await this.pollRequest.response();\n return settings;\n } catch (err) {\n if (err.name === \"HomeServerError\") {\n return undefined;\n }\n throw err;\n } finally {\n this.pollRequest = undefined;\n }\n }\n\n private stopPollLoop() {\n this.isPolling = false;\n this.currentObservable = undefined;\n this.pollTimeout?.dispose();\n this.pollTimeout = undefined;\n this.pollRequest?.abort();\n this.pollRequest = undefined;\n }\n\n dispose() {\n this.stopPollLoop();\n }\n}\n\nfunction shouldUpdate(observable: BaseObservableValue, settings: RTCIceServer): boolean {\n const currentSettings = observable.get();\n if (!currentSettings) {\n return true;\n }\n // same length and new settings doesn't contain any uri the old settings don't contain\n const currentUrls = Array.isArray(currentSettings.urls) ? currentSettings.urls : [currentSettings.urls];\n const newUrls = Array.isArray(settings.urls) ? settings.urls : [settings.urls];\n const arraysEqual = currentUrls.length === newUrls.length &&\n !newUrls.some(uri => !currentUrls.includes(uri));\n return !arraysEqual || settings.username !== currentSettings.username ||\n settings.credential !== currentSettings.credential;\n}\n\nfunction toIceServer(settings: TurnServerSettings): RTCIceServer {\n return {\n urls: settings.uris,\n username: settings.username,\n credential: settings.password,\n // @ts-ignore\n // this field is deprecated but providing it nonetheless\n credentialType: \"password\"\n }\n}\n\nexport function tests() {\n return {\n \"shouldUpdate returns false for same object\": assert => {\n const observable = {get() {\n return {\n urls: [\"a\", \"b\"],\n username: \"alice\",\n credential: \"f00\",\n };\n }};\n const same = {\n urls: [\"a\", \"b\"],\n username: \"alice\",\n credential: \"f00\",\n };\n assert.equal(false, shouldUpdate(observable as any as BaseObservableValue, same));\n },\n \"shouldUpdate returns true for 1 different uri\": assert => {\n const observable = {get() {\n return {\n urls: [\"a\", \"c\"],\n username: \"alice\",\n credential: \"f00\",\n };\n }};\n const same = {\n urls: [\"a\", \"b\"],\n username: \"alice\",\n credential: \"f00\",\n };\n assert.equal(true, shouldUpdate(observable as any as BaseObservableValue, same));\n },\n \"shouldUpdate returns true for different user\": assert => {\n const observable = {get() {\n return {\n urls: [\"a\", \"b\"],\n username: \"alice\",\n credential: \"f00\",\n };\n }};\n const same = {\n urls: [\"a\", \"b\"],\n username: \"bob\",\n credential: \"f00\",\n };\n assert.equal(true, shouldUpdate(observable as any as BaseObservableValue, same));\n },\n \"shouldUpdate returns true for different password\": assert => {\n const observable = {get() {\n return {\n urls: [\"a\", \"b\"],\n username: \"alice\",\n credential: \"f00\",\n };\n }};\n const same = {\n urls: [\"a\", \"b\"],\n username: \"alice\",\n credential: \"b4r\",\n };\n assert.equal(true, shouldUpdate(observable as any as BaseObservableValue, same));\n }\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableMap} from \"../../observable/map\";\nimport {WebRTC, PeerConnection} from \"../../platform/types/WebRTC\";\nimport {MediaDevices, Track} from \"../../platform/types/MediaDevices\";\nimport {handlesEventType} from \"./PeerCall\";\nimport {EventType, CallIntent, CallType} from \"./callEventTypes\";\nimport {GroupCall} from \"./group/GroupCall\";\nimport {makeId} from \"../common\";\nimport {CALL_LOG_TYPE} from \"./common\";\nimport {EVENT_TYPE as MEMBER_EVENT_TYPE, RoomMember} from \"../room/members/RoomMember\";\nimport {TurnServerSource} from \"./TurnServerSource\";\n\nimport type {LocalMedia} from \"./LocalMedia\";\nimport type {Room} from \"../room/Room\";\nimport type {MemberChange} from \"../room/members/RoomMember\";\nimport type {StateEvent} from \"../storage/types\";\nimport type {ILogItem, ILogger} from \"../../logging/types\";\nimport type {Platform} from \"../../platform/web/Platform\";\nimport type {BaseObservableMap} from \"../../observable/map\";\nimport type {SignallingMessage, MGroupCallBase} from \"./callEventTypes\";\nimport type {Options as GroupCallOptions} from \"./group/GroupCall\";\nimport type {Transaction} from \"../storage/idb/Transaction\";\nimport type {CallEntry} from \"../storage/idb/stores/CallStore\";\nimport type {Clock} from \"../../platform/web/dom/Clock\";\nimport type {RoomStateHandler} from \"../room/state/types\";\nimport type {MemberSync} from \"../room/timeline/persistence/MemberWriter\";\n\nexport type Options = Omit & {\n clock: Clock\n};\n\nfunction getRoomMemberKey(roomId: string, userId: string): string {\n return JSON.stringify(roomId)+`,`+JSON.stringify(userId);\n}\n\nexport class CallHandler implements RoomStateHandler {\n // group calls by call id\n private readonly _calls: ObservableMap = new ObservableMap();\n // map of `\"roomId\",\"userId\"` to set of conf_id's they are in\n private roomMemberToCallIds: Map> = new Map();\n private groupCallOptions: GroupCallOptions;\n private sessionId = makeId(\"s\");\n\n constructor(private readonly options: Options) {\n this.groupCallOptions = Object.assign({}, this.options, {\n turnServerSource: new TurnServerSource(this.options.hsApi, this.options.clock),\n emitUpdate: (groupCall, params) => this._calls.update(groupCall.id, params),\n createTimeout: this.options.clock.createTimeout,\n sessionId: this.sessionId\n });\n }\n\n loadCalls(intent?: CallIntent, log?: ILogItem) {\n return this.options.logger.wrapOrRun(log, \"CallHandler.loadCalls\", async log => {\n if (!intent) {\n intent = CallIntent.Ring;\n }\n log.set(\"intent\", intent);\n const txn = await this._getLoadTxn();\n const callEntries = await txn.calls.getByIntent(intent);\n await this._loadCallEntries(callEntries, txn, log);\n });\n }\n\n loadCallsForRoom(intent: CallIntent, roomId: string, log?: ILogItem) {\n return this.options.logger.wrapOrRun(log, \"CallHandler.loadCallsForRoom\", async log => {\n log.set(\"intent\", intent);\n log.set(\"roomId\", roomId);\n const txn = await this._getLoadTxn();\n const callEntries = await txn.calls.getByIntentAndRoom(intent, roomId);\n await this._loadCallEntries(callEntries, txn, log);\n });\n }\n\n private async _getLoadTxn(): Promise {\n const names = this.options.storage.storeNames;\n const txn = await this.options.storage.readTxn([\n names.calls,\n names.roomState,\n ]);\n return txn;\n }\n\n private async _loadCallEntries(callEntries: CallEntry[], txn: Transaction, log: ILogItem): Promise {\n log.set(\"entries\", callEntries.length);\n await Promise.all(callEntries.map(async callEntry => {\n if (this._calls.get(callEntry.callId)) {\n return;\n }\n const event = await txn.roomState.get(callEntry.roomId, EventType.GroupCall, callEntry.callId);\n if (event) {\n const call = new GroupCall(\n event.event.state_key, // id\n true, // isLoadedFromStorage\n false, // newCall\n callEntry.timestamp, // startTime\n event.event.content, // callContent\n event.roomId, // roomId\n this.groupCallOptions // options\n );\n this._calls.set(call.id, call);\n }\n }));\n const roomIds = Array.from(new Set(callEntries.map(e => e.roomId)));\n await Promise.all(roomIds.map(async roomId => {\n // TODO: don't load all members until we need them\n const callsMemberEvents = await txn.roomState.getAllForType(roomId, EventType.GroupCallMember);\n await Promise.all(callsMemberEvents.map(async entry => {\n const userId = entry.event.sender;\n const roomMemberState = await txn.roomState.get(roomId, MEMBER_EVENT_TYPE, userId);\n let roomMember;\n if (roomMemberState) {\n roomMember = RoomMember.fromMemberEvent(roomMemberState.event);\n }\n if (!roomMember) {\n // we'll be missing the member here if we received a call and it's members\n // as pre-gap state and the members weren't active in the timeline we got.\n roomMember = RoomMember.fromUserId(roomId, userId, \"join\");\n }\n this.handleCallMemberEvent(entry.event, roomMember, roomId, log);\n }));\n }));\n log.set(\"newSize\", this._calls.size);\n }\n\n createCall(roomId: string, type: CallType, name: string, intent?: CallIntent, log?: ILogItem): Promise {\n return this.options.logger.wrapOrRun(log, \"CallHandler.createCall\", async log => {\n if (!intent) {\n intent = CallIntent.Ring;\n }\n const call = new GroupCall(\n makeId(\"conf-\"), // id\n false, // isLoadedFromStorage\n true, // newCall\n undefined, // startTime\n {\"m.name\": name, \"m.intent\": intent}, // callContent\n roomId, // roomId\n this.groupCallOptions // options\n );\n this._calls.set(call.id, call);\n\n try {\n await call.create(type, log);\n // store call info so it will ring again when reopening the app\n const txn = await this.options.storage.readWriteTxn([this.options.storage.storeNames.calls]);\n txn.calls.add({\n intent: call.intent,\n callId: call.id,\n timestamp: this.options.clock.now(),\n roomId: roomId\n });\n await txn.complete();\n } catch (err) {\n //if (err.name === \"ConnectionError\") {\n // if we're offline, give up and remove the call again\n this._calls.remove(call.id);\n //}\n throw err;\n }\n return call;\n });\n }\n\n get calls(): BaseObservableMap { return this._calls; }\n\n // TODO: check and poll turn server credentials here\n\n /** @internal */\n async handleRoomState(room: Room, event: StateEvent, memberSync: MemberSync, txn: Transaction, log: ILogItem) {\n if (event.type === EventType.GroupCall) {\n this.handleCallEvent(event, room.id, txn, log);\n }\n if (event.type === EventType.GroupCallMember) {\n let member = await memberSync.lookupMemberAtEvent(event.sender, event, txn);\n if (!member) {\n // we'll be missing the member here if we received a call and it's members\n // as pre-gap state and the members weren't active in the timeline we got.\n member = RoomMember.fromUserId(room.id, event.sender, \"join\");\n }\n this.handleCallMemberEvent(event, member, room.id, log);\n }\n }\n\n /** @internal */\n updateRoomMembers(room: Room, memberChanges: Map) {\n // TODO: also have map for roomId to calls, so we can easily update members\n // we will also need this to get the call for a room\n for (const call of this._calls.values()) {\n if (call.roomId === room.id) {\n call.updateRoomMembers(memberChanges);\n }\n }\n }\n\n /** @internal */\n handlesDeviceMessageEventType(eventType: string): boolean {\n return handlesEventType(eventType);\n }\n\n /** @internal */\n handleDeviceMessage(message: SignallingMessage, userId: string, deviceId: string, log: ILogItem) {\n // TODO: buffer messages for calls we haven't received the state event for yet?\n const call = this._calls.get(message.content.conf_id);\n call?.handleDeviceMessage(message, userId, deviceId, log);\n }\n\n private handleCallEvent(event: StateEvent, roomId: string, txn: Transaction, log: ILogItem) {\n const callId = event.state_key;\n let call = this._calls.get(callId);\n if (call) {\n call.updateCallEvent(event, log);\n if (call.isTerminated) {\n call.disconnect(log);\n this._calls.remove(call.id);\n txn.calls.remove(call.intent, roomId, call.id);\n }\n } else if(!event.content[\"m.terminated\"]) {\n // We don't have this call already and it isn't terminated, so create the call:\n call = new GroupCall(\n event.state_key, // id\n false, // isLoadedFromStorage\n false, // newCall\n event.origin_server_ts, // startTime\n event.content, // callContent\n roomId, // roomId\n this.groupCallOptions // options\n );\n this._calls.set(call.id, call);\n txn.calls.add({\n intent: call.intent,\n callId: call.id,\n timestamp: event.origin_server_ts,\n roomId: roomId\n });\n }\n }\n\n private handleCallMemberEvent(event: StateEvent, member: RoomMember, roomId: string, log: ILogItem) {\n const userId = event.state_key;\n const roomMemberKey = getRoomMemberKey(roomId, userId)\n const calls = event.content[\"m.calls\"] ?? [];\n for (const call of calls) {\n const callId = call[\"m.call_id\"];\n const groupCall = this._calls.get(callId);\n // TODO: also check the member when receiving the m.call event\n groupCall?.updateMembership(userId, member, call, log);\n };\n const newCallIdsMemberOf = new Set(calls.map(call => call[\"m.call_id\"]));\n let previousCallIdsMemberOf = this.roomMemberToCallIds.get(roomMemberKey);\n\n // remove user as member of any calls not present anymore\n if (previousCallIdsMemberOf) {\n for (const previousCallId of previousCallIdsMemberOf) {\n if (!newCallIdsMemberOf.has(previousCallId)) {\n const groupCall = this._calls.get(previousCallId);\n groupCall?.removeMembership(userId, log);\n }\n }\n }\n if (newCallIdsMemberOf.size === 0) {\n this.roomMemberToCallIds.delete(roomMemberKey);\n } else {\n this.roomMemberToCallIds.set(roomMemberKey, newCallIdsMemberOf);\n }\n }\n\n dispose() {\n this.groupCallOptions.turnServerSource.dispose();\n for(const call of this._calls.values()) {\n call.dispose();\n }\n }\n}\n\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {ILogItem} from \"../../../logging/types\";\nimport type {StateEvent} from \"../../storage/types\";\nimport type {Transaction} from \"../../storage/idb/Transaction\";\nimport type {Room} from \"../Room\";\nimport type {MemberChange} from \"../members/RoomMember\";\nimport type {RoomStateHandler} from \"./types\";\nimport type {MemberSync} from \"../timeline/persistence/MemberWriter.js\";\nimport {BaseObservable} from \"../../../observable/BaseObservable\";\n\n/** keeps track of all handlers registered with Session.observeRoomState */\nexport class RoomStateHandlerSet extends BaseObservable implements RoomStateHandler {\n async handleRoomState(room: Room, stateEvent: StateEvent, memberSync: MemberSync, txn: Transaction, log: ILogItem): Promise {\n const promises: Promise[] = [];\n for(let h of this._handlers) {\n promises.push(h.handleRoomState(room, stateEvent, memberSync, txn, log));\n }\n await Promise.all(promises);\n }\n updateRoomMembers(room: Room, memberChanges: Map) {\n for(let h of this._handlers) {\n h.updateRoomMembers(room, memberChanges);\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {SettingsStorage} from \"./platform/web/dom/SettingsStorage\";\n\nexport enum FeatureFlag {\n Calls = 1 << 0,\n CrossSigning = 1 << 1\n}\n\nexport class FeatureSet {\n constructor(public readonly flags: number = 0) {}\n\n withFeature(flag: FeatureFlag): FeatureSet {\n return new FeatureSet(this.flags | flag);\n }\n\n withoutFeature(flag: FeatureFlag): FeatureSet {\n return new FeatureSet(this.flags ^ flag);\n }\n \n isFeatureEnabled(flag: FeatureFlag): boolean {\n return (this.flags & flag) !== 0;\n }\n\n get calls(): boolean {\n return this.isFeatureEnabled(FeatureFlag.Calls);\n }\n\n get crossSigning(): boolean {\n return this.isFeatureEnabled(FeatureFlag.CrossSigning);\n }\n\n static async load(settingsStorage: SettingsStorage): Promise {\n const flags = await settingsStorage.getInt(\"enabled_features\") || 0;\n return new FeatureSet(flags);\n }\n\n async store(settingsStorage: SettingsStorage): Promise {\n await settingsStorage.setInt(\"enabled_features\", this.flags);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Room} from \"./room/Room.js\";\nimport {ArchivedRoom} from \"./room/ArchivedRoom.js\";\nimport {RoomStatus} from \"./room/common\";\nimport {RoomBeingCreated} from \"./room/RoomBeingCreated\";\nimport {Invite} from \"./room/Invite.js\";\nimport {Pusher} from \"./push/Pusher\";\nimport {ObservableMap} from \"../observable\";\nimport {User} from \"./User.js\";\nimport {DeviceMessageHandler} from \"./DeviceMessageHandler.js\";\nimport {Account as E2EEAccount} from \"./e2ee/Account.js\";\nimport {uploadAccountAsDehydratedDevice} from \"./e2ee/Dehydration.js\";\nimport {Decryption as OlmDecryption} from \"./e2ee/olm/Decryption\";\nimport {Encryption as OlmEncryption} from \"./e2ee/olm/Encryption\";\nimport {Decryption as MegOlmDecryption} from \"./e2ee/megolm/Decryption\";\nimport {KeyLoader as MegOlmKeyLoader} from \"./e2ee/megolm/decryption/KeyLoader\";\nimport {KeyBackup} from \"./e2ee/megolm/keybackup/KeyBackup\";\nimport {CrossSigning} from \"./verification/CrossSigning\";\nimport {Encryption as MegOlmEncryption} from \"./e2ee/megolm/Encryption.js\";\nimport {MEGOLM_ALGORITHM} from \"./e2ee/common\";\nimport {RoomEncryption} from \"./e2ee/RoomEncryption.js\";\nimport {DeviceTracker} from \"./e2ee/DeviceTracker\";\nimport {LockMap} from \"../utils/LockMap\";\nimport {groupBy} from \"../utils/groupBy\";\nimport {\n keyFromCredential as ssssKeyFromCredential,\n readKey as ssssReadKey,\n writeKey as ssssWriteKey,\n removeKey as ssssRemoveKey,\n keyFromDehydratedDeviceKey as createSSSSKeyFromDehydratedDeviceKey,\n SecretStorage,\n SecretSharing,\n SecretFetcher\n} from \"./ssss/index\";\nimport {ObservableValue, RetainedObservableValue} from \"../observable/value\";\nimport {CallHandler} from \"./calls/CallHandler\";\nimport {RoomStateHandlerSet} from \"./room/state/RoomStateHandlerSet\";\n\nconst PICKLE_KEY = \"DEFAULT_KEY\";\nconst PUSHER_KEY = \"pusher\";\n\nexport class Session {\n // sessionInfo contains deviceId, userId and homeserver\n constructor({storage, hsApi, sessionInfo, olm, olmWorker, platform, mediaRepository, features}) {\n this._platform = platform;\n this._storage = storage;\n this._hsApi = hsApi;\n this._mediaRepository = mediaRepository;\n this._features = features;\n this._syncInfo = null;\n this._sessionInfo = sessionInfo;\n this._rooms = new ObservableMap();\n this._roomUpdateCallback = (room, params) => this._rooms.update(room.id, params);\n this._activeArchivedRooms = new Map();\n this._invites = new ObservableMap();\n this._inviteUpdateCallback = (invite, params) => this._invites.update(invite.id, params);\n this._roomsBeingCreatedUpdateCallback = (rbc, params) => {\n if (rbc.isCancelled) {\n this._roomsBeingCreated.remove(rbc.id);\n } else {\n this._roomsBeingCreated.update(rbc.id, params)\n }\n };\n this._roomsBeingCreated = new ObservableMap();\n this._user = new User(sessionInfo.userId);\n this._roomStateHandler = new RoomStateHandlerSet();\n if (features.calls) {\n this._setupCallHandler();\n }\n this._deviceMessageHandler = new DeviceMessageHandler({storage, callHandler: this._callHandler});\n this._olm = olm;\n this._olmUtil = null;\n this._e2eeAccount = null;\n this._deviceTracker = null;\n this._olmEncryption = null;\n this._keyLoader = null;\n this._megolmEncryption = null;\n this._megolmDecryption = null;\n this._getSyncToken = () => this.syncToken;\n this._olmWorker = olmWorker;\n this._keyBackup = new ObservableValue(undefined);\n this._crossSigning = new ObservableValue(undefined);\n this._observedRoomStatus = new Map();\n\n if (olm) {\n this._olmUtil = new olm.Utility();\n this._deviceTracker = new DeviceTracker({\n storage,\n getSyncToken: this._getSyncToken,\n olmUtil: this._olmUtil,\n ownUserId: sessionInfo.userId,\n ownDeviceId: sessionInfo.deviceId,\n });\n }\n this._createRoomEncryption = this._createRoomEncryption.bind(this);\n this._forgetArchivedRoom = this._forgetArchivedRoom.bind(this);\n this.needsKeyBackup = new ObservableValue(false);\n this._secretFetcher = new SecretFetcher();\n this._secretSharing = null;\n this._secretStorage = null;\n }\n\n get fingerprintKey() {\n return this._e2eeAccount?.identityKeys.ed25519;\n }\n\n get hasSecretStorageKey() {\n return this._hasSecretStorageKey;\n }\n\n get deviceId() {\n return this._sessionInfo.deviceId;\n }\n\n get userId() {\n return this._sessionInfo.userId;\n }\n\n get callHandler() {\n return this._callHandler;\n }\n\n get features() {\n return this._features;\n }\n\n _setupCallHandler() {\n this._callHandler = new CallHandler({\n clock: this._platform.clock,\n random: this._platform.random,\n hsApi: this._hsApi,\n encryptDeviceMessage: async (roomId, userId, deviceId, message, log) => {\n if (!this._deviceTracker || !this._olmEncryption) {\n log.set(\"encryption_disabled\", true);\n return;\n }\n const device = await log.wrap(\"get device key\", async log => {\n const device = this._deviceTracker.deviceForId(userId, deviceId, this._hsApi, log);\n if (!device) {\n log.set(\"not_found\", true);\n }\n return device;\n });\n if (device) {\n const encryptedMessages = await this._olmEncryption.encrypt(message.type, message.content, [device], this._hsApi, log);\n return encryptedMessages;\n }\n },\n storage: this._storage,\n webRTC: this._platform.webRTC,\n ownDeviceId: this._sessionInfo.deviceId,\n ownUserId: this._sessionInfo.userId,\n logger: this._platform.logger,\n forceTURN: false,\n });\n this.observeRoomState(this._callHandler);\n }\n\n // called once this._e2eeAccount is assigned\n async _setupEncryption() {\n // TODO: this should all go in a wrapper in e2ee/ that is bootstrapped by passing in the account\n // and can create RoomEncryption objects and handle encrypted to_device messages and device list changes.\n const senderKeyLock = new LockMap();\n const olmDecryption = new OlmDecryption(\n this._e2eeAccount,\n PICKLE_KEY,\n this._platform.clock.now,\n this._user.id,\n this._olm,\n senderKeyLock\n );\n this._olmEncryption = new OlmEncryption(\n this._e2eeAccount,\n PICKLE_KEY,\n this._olm,\n this._storage,\n this._platform.clock.now,\n this._user.id,\n this._olmUtil,\n senderKeyLock\n );\n this._keyLoader = new MegOlmKeyLoader(this._olm, PICKLE_KEY, 20);\n this._megolmEncryption = new MegOlmEncryption({\n account: this._e2eeAccount,\n pickleKey: PICKLE_KEY,\n olm: this._olm,\n storage: this._storage,\n keyLoader: this._keyLoader,\n now: this._platform.clock.now,\n ownDeviceId: this._sessionInfo.deviceId,\n });\n this._megolmDecryption = new MegOlmDecryption(this._keyLoader, this._olmWorker);\n this._deviceMessageHandler.enableEncryption({olmDecryption, megolmDecryption: this._megolmDecryption});\n this._secretSharing = new SecretSharing({\n hsApi: this._hsApi,\n storage: this._storage,\n deviceMessageHandler: this._deviceMessageHandler,\n deviceTracker: this._deviceTracker,\n ourUserId: this.userId,\n olmEncryption: this._olmEncryption,\n crypto: this._platform.crypto,\n encoding: this._platform.encoding,\n crossSigning: this._crossSigning,\n logger: this._platform.logger,\n });\n await this._secretSharing.load();\n this._secretFetcher.setSecretSharing(this._secretSharing);\n }\n\n _createRoomEncryption(room, encryptionParams) {\n // TODO: this will actually happen when users start using the e2ee version for the first time\n\n // this should never happen because either a session was already synced once\n // and thus an e2ee account was created as well and _setupEncryption is called from load\n // OR\n // this is a new session and loading it will load zero rooms, thus not calling this method.\n // in this case _setupEncryption is called from beforeFirstSync, right after load,\n // so any incoming synced rooms won't be there yet\n if (!this._olmEncryption) {\n throw new Error(\"creating room encryption before encryption got globally enabled\");\n }\n // only support megolm\n if (encryptionParams.algorithm !== MEGOLM_ALGORITHM) {\n return null;\n }\n return new RoomEncryption({\n room,\n deviceTracker: this._deviceTracker,\n olmEncryption: this._olmEncryption,\n megolmEncryption: this._megolmEncryption,\n megolmDecryption: this._megolmDecryption,\n storage: this._storage,\n keyBackup: this._keyBackup?.get(),\n encryptionParams,\n notifyMissingMegolmSession: () => {\n if (!this._keyBackup.get()) {\n this.needsKeyBackup.set(true)\n }\n },\n clock: this._platform.clock\n });\n }\n\n /**\n * Enable secret storage by providing the secret storage credential.\n * This will also see if there is a megolm key backup and try to enable that if so.\n *\n * @param {KeyType} type either KeyType.RecoveryKey (0) or KeyType.Passphrase (1)\n * @param {string} credential either the passphrase or the recovery key, depending on the type\n * @return {Promise} resolves or rejects after having tried to enable secret storage\n */\n enableSecretStorage(type, credential, log = undefined) {\n return this._platform.logger.wrapOrRun(log, \"enable secret storage\", async log => {\n if (!this._olm) {\n throw new Error(\"olm required\");\n }\n if (this._keyBackup.get()) {\n this._keyBackup.get().dispose();\n this._keyBackup.set(undefined);\n }\n const key = await ssssKeyFromCredential(type, credential, this._storage, this._platform, this._olm);\n if (await this._tryLoadSecretStorage(key, log)) {\n // only after having read a secret, write the key\n // as we only find out if it was good if the MAC verification succeeds\n await this._writeSSSSKey(key, log);\n await this._keyBackup.get()?.start(log);\n await this._crossSigning.get()?.start(log);\n return key;\n } else {\n throw new Error(\"Could not read key backup with the given key\");\n }\n });\n }\n\n async _writeSSSSKey(key, log) {\n // we're going to write the 4S key, and also the backup version.\n // this way, we can detect when we enter a key for a new backup version\n // and mark all inbound sessions to be backed up again\n const keyBackup = this._keyBackup.get();\n if (!keyBackup) {\n return;\n }\n const backupVersion = keyBackup.version;\n const writeTxn = await this._storage.readWriteTxn([\n this._storage.storeNames.session,\n this._storage.storeNames.inboundGroupSessions,\n ]);\n try {\n const previousBackupVersion = await ssssWriteKey(key, backupVersion, writeTxn);\n log.set(\"previousBackupVersion\", previousBackupVersion);\n log.set(\"backupVersion\", backupVersion);\n if (!!previousBackupVersion && previousBackupVersion !== backupVersion) {\n const amountMarked = await keyBackup.markAllForBackup(writeTxn);\n log.set(\"amountMarkedForBackup\", amountMarked);\n }\n } catch (err) {\n writeTxn.abort();\n throw err;\n }\n await writeTxn.complete();\n }\n\n async disableSecretStorage() {\n const writeTxn = await this._storage.readWriteTxn([\n this._storage.storeNames.session,\n ]);\n try {\n ssssRemoveKey(writeTxn);\n } catch (err) {\n writeTxn.abort();\n throw err;\n }\n await writeTxn.complete();\n if (this._keyBackup.get()) {\n for (const room of this._rooms.values()) {\n if (room.isEncrypted) {\n room.enableKeyBackup(undefined);\n }\n }\n this._keyBackup.get().dispose();\n this._keyBackup.set(undefined);\n }\n const crossSigning = this._crossSigning.get();\n if (crossSigning) {\n crossSigning.dispose();\n this._crossSigning.set(undefined);\n }\n }\n\n _tryLoadSecretStorage(ssssKey, log) {\n return log.wrap(\"enable secret storage\", async log => {\n const secretStorage = new SecretStorage({key: ssssKey, platform: this._platform, storage: this._storage});\n const isValid = await secretStorage.hasValidKeyForAnyAccountData();\n log.set(\"isValid\", isValid);\n if (isValid) {\n this._secretStorage = secretStorage;\n await this._loadSecretStorageServices(secretStorage, log);\n this._secretFetcher.setSecretStorage(secretStorage);\n }\n return isValid;\n });\n }\n\n async _loadSecretStorageServices(secretStorage, log) {\n try {\n await log.wrap(\"enable key backup\", async log => {\n const keyBackup = new KeyBackup(\n this._hsApi,\n this._olm,\n this._keyLoader,\n this._storage,\n this._platform,\n );\n if (await keyBackup.load(secretStorage, log)) {\n for (const room of this._rooms.values()) {\n if (room.isEncrypted) {\n room.enableKeyBackup(keyBackup);\n }\n }\n this._keyBackup.set(keyBackup);\n return true;\n } else {\n log.set(\"no_backup\", true);\n }\n });\n } catch (err) {\n log.catch(err);\n }\n }\n\n /**\n * @type {ObservableValue this._e2eeAccount.uploadKeys(this._storage, false, log));\n }\n await this._createCrossSigning();\n }\n }\n\n /** @internal */\n async dehydrateIdentity(dehydratedDevice, log) {\n log.set(\"deviceId\", dehydratedDevice.deviceId);\n if (!this._olm) {\n log.set(\"no_olm\", true);\n return false;\n }\n if (dehydratedDevice.deviceId !== this.deviceId) {\n log.set(\"wrong_device\", true);\n return false;\n }\n if (this._e2eeAccount) {\n log.set(\"account_already_setup\", true);\n return false;\n }\n if (!await dehydratedDevice.claim(this._hsApi, log)) {\n log.set(\"already_claimed\", true);\n return false;\n }\n this._e2eeAccount = await E2EEAccount.adoptDehydratedDevice({\n dehydratedDevice,\n hsApi: this._hsApi,\n olm: this._olm,\n pickleKey: PICKLE_KEY,\n userId: this._sessionInfo.userId,\n olmWorker: this._olmWorker,\n deviceId: this.deviceId,\n storage: this._storage,\n });\n log.set(\"keys\", this._e2eeAccount.identityKeys);\n this._setupEncryption();\n return true;\n }\n\n _createNewAccount(deviceId, storage = undefined) {\n // storage is optional and if omitted the account won't be persisted (useful for dehydrating devices)\n return E2EEAccount.create({\n hsApi: this._hsApi,\n olm: this._olm,\n pickleKey: PICKLE_KEY,\n userId: this._sessionInfo.userId,\n olmWorker: this._olmWorker,\n deviceId,\n storage,\n });\n }\n\n setupDehydratedDevice(key, log = null) {\n return this._platform.logger.wrapOrRun(log, \"setupDehydratedDevice\", async log => {\n const dehydrationAccount = await this._createNewAccount(\"temp-device-id\");\n try {\n const deviceId = await uploadAccountAsDehydratedDevice(\n dehydrationAccount, this._hsApi, key, \"Dehydrated device\", log);\n log.set(\"deviceId\", deviceId);\n return deviceId;\n } finally {\n dehydrationAccount.dispose();\n }\n });\n }\n\n /** @internal */\n async load(log) {\n const txn = await this._storage.readTxn([\n this._storage.storeNames.session,\n this._storage.storeNames.roomSummary,\n this._storage.storeNames.invites,\n this._storage.storeNames.roomMembers,\n this._storage.storeNames.timelineEvents,\n this._storage.storeNames.timelineFragments,\n this._storage.storeNames.pendingEvents,\n this._storage.storeNames.accountData,\n this._storage.storeNames.crossSigningKeys,\n ]);\n // restore session object\n this._syncInfo = await txn.session.get(\"sync\");\n // restore e2ee account, if any\n if (this._olm) {\n this._e2eeAccount = await E2EEAccount.load({\n hsApi: this._hsApi,\n olm: this._olm,\n pickleKey: PICKLE_KEY,\n userId: this._sessionInfo.userId,\n deviceId: this._sessionInfo.deviceId,\n olmWorker: this._olmWorker,\n txn\n });\n if (this._e2eeAccount) {\n log.set(\"keys\", this._e2eeAccount.identityKeys);\n }\n this._setupEncryption();\n }\n const pendingEventsByRoomId = await this._getPendingEventsByRoom(txn);\n // load invites\n const invites = await txn.invites.getAll();\n const inviteLoadPromise = Promise.all(invites.map(async inviteData => {\n const invite = this.createInvite(inviteData.roomId);\n log.wrap(\"invite\", log => invite.load(inviteData, log));\n this._invites.add(invite.id, invite);\n }));\n // load rooms\n const rooms = await txn.roomSummary.getAll();\n const roomLoadPromise = Promise.all(rooms.map(async summary => {\n const room = this.createJoinedRoom(summary.roomId, pendingEventsByRoomId.get(summary.roomId));\n await log.wrap(\"room\", log => room.load(summary, txn, log));\n this._rooms.add(room.id, room);\n }));\n // load invites and rooms in parallel\n await Promise.all([inviteLoadPromise, roomLoadPromise]);\n for (const [roomId, invite] of this.invites) {\n const room = this.rooms.get(roomId);\n if (room) {\n room.setInvite(invite);\n }\n }\n if (this._olm && this._e2eeAccount) {\n // try set up session backup and cross-signing if we stored the ssss key\n const ssssKey = await ssssReadKey(txn);\n if (ssssKey) {\n // this will close the txn above, so we do it last\n await this._tryLoadSecretStorage(ssssKey, log);\n }\n }\n if (this._e2eeAccount) {\n await this._createCrossSigning();\n }\n }\n\n async _createCrossSigning() {\n if (this._features.crossSigning) {\n this._platform.logger.run(\"enable cross-signing\", async log => {\n const crossSigning = new CrossSigning({\n storage: this._storage,\n secretFetcher: this._secretFetcher,\n platform: this._platform,\n olm: this._olm,\n olmUtil: this._olmUtil,\n deviceTracker: this._deviceTracker,\n deviceMessageHandler: this._deviceMessageHandler,\n hsApi: this._hsApi,\n ownUserId: this.userId,\n e2eeAccount: this._e2eeAccount,\n deviceId: this.deviceId,\n });\n await crossSigning.load(log);\n this._crossSigning.set(crossSigning);\n });\n }\n }\n\n dispose() {\n this._olmWorker?.dispose();\n this._olmWorker = undefined;\n this._keyBackup.get()?.dispose();\n this._keyBackup.set(undefined);\n this._megolmDecryption?.dispose();\n this._megolmDecryption = undefined;\n this._e2eeAccount?.dispose();\n this._e2eeAccount = undefined;\n this._callHandler?.dispose();\n this._callHandler = undefined;\n this._crossSigning.get()?.dispose();\n for (const room of this._rooms.values()) {\n room.dispose();\n }\n this._rooms = undefined;\n }\n\n /**\n * @internal called from session container when coming back online and catchup syncs have finished.\n * @param {Object} lastVersionResponse a response from /versions, which is polled while offline,\n * and useful to store so we can later tell what capabilities\n * our homeserver has.\n */\n async start(lastVersionResponse, dehydratedDevice, log) {\n if (lastVersionResponse) {\n // store /versions response\n const txn = await this._storage.readWriteTxn([\n this._storage.storeNames.session\n ]);\n txn.session.set(\"serverVersions\", lastVersionResponse);\n // TODO: what can we do if this throws?\n await txn.complete();\n }\n // try if the key used to decrypt the dehydrated device also fits for secret storage\n if (dehydratedDevice) {\n await log.wrap(\"SSSSKeyFromDehydratedDeviceKey\", async log => {\n const ssssKey = await createSSSSKeyFromDehydratedDeviceKey(dehydratedDevice.key, this._storage, this._platform);\n if (ssssKey) {\n if (await this._tryLoadSecretStorage(ssssKey, log)) {\n log.set(\"success\", true);\n await this._writeSSSSKey(ssssKey);\n }\n }\n });\n }\n await this._keyBackup.get()?.start(log);\n await this._crossSigning.get()?.start(log);\n \n // restore unfinished operations, like sending out room keys\n const opsTxn = await this._storage.readWriteTxn([\n this._storage.storeNames.operations\n ]);\n const operations = await opsTxn.operations.getAll();\n const operationsByScope = groupBy(operations, o => o.scope);\n\n for (const room of this._rooms.values()) {\n let roomOperationsByType;\n const roomOperations = operationsByScope.get(room.id);\n if (roomOperations) {\n roomOperationsByType = groupBy(roomOperations, r => r.type);\n }\n room.start(roomOperationsByType, log);\n }\n }\n\n async _getPendingEventsByRoom(txn) {\n const pendingEvents = await txn.pendingEvents.getAll();\n return pendingEvents.reduce((groups, pe) => {\n const group = groups.get(pe.roomId);\n if (group) {\n group.push(pe);\n } else {\n groups.set(pe.roomId, [pe]);\n }\n return groups;\n }, new Map());\n }\n\n get rooms() {\n return this._rooms;\n }\n\n findDirectMessageForUserId(userId) {\n for (const [,room] of this._rooms) {\n if (room.isDirectMessageForUserId(userId)) {\n return room;\n }\n }\n for (const [,invite] of this._invites) {\n if (invite.isDirectMessageForUserId(userId)) {\n return invite;\n }\n }\n }\n\n /** @internal */\n createJoinedRoom(roomId, pendingEvents) {\n return new Room({\n roomId,\n getSyncToken: this._getSyncToken,\n storage: this._storage,\n emitCollectionChange: this._roomUpdateCallback,\n hsApi: this._hsApi,\n mediaRepository: this._mediaRepository,\n pendingEvents,\n user: this._user,\n createRoomEncryption: this._createRoomEncryption,\n platform: this._platform,\n roomStateHandler: this._roomStateHandler\n });\n }\n\n /** @internal */\n _createArchivedRoom(roomId) {\n const room = new ArchivedRoom({\n roomId,\n getSyncToken: this._getSyncToken,\n storage: this._storage,\n emitCollectionChange: () => {},\n releaseCallback: () => this._activeArchivedRooms.delete(roomId),\n forgetCallback: this._forgetArchivedRoom,\n hsApi: this._hsApi,\n mediaRepository: this._mediaRepository,\n user: this._user,\n createRoomEncryption: this._createRoomEncryption,\n platform: this._platform\n });\n this._activeArchivedRooms.set(roomId, room);\n return room;\n }\n\n get invites() {\n return this._invites;\n }\n\n /** @internal */\n createInvite(roomId) {\n return new Invite({\n roomId,\n hsApi: this._hsApi,\n emitCollectionUpdate: this._inviteUpdateCallback,\n mediaRepository: this._mediaRepository,\n user: this._user,\n platform: this._platform,\n });\n }\n\n get roomsBeingCreated() {\n return this._roomsBeingCreated;\n }\n\n async createRoom(options) {\n let roomBeingCreated;\n await this._platform.logger.run(\"create room\", async log => {\n const id = `local-${Math.floor(this._platform.random() * Number.MAX_SAFE_INTEGER)}`;\n roomBeingCreated = new RoomBeingCreated(\n id, options, this._roomsBeingCreatedUpdateCallback,\n this._mediaRepository, this._platform, log);\n this._roomsBeingCreated.set(id, roomBeingCreated);\n const promises = [roomBeingCreated.create(this._hsApi, log)];\n const loadProfiles = options.loadProfiles !== false; // default to true\n if (loadProfiles) {\n promises.push(roomBeingCreated.loadProfiles(this._hsApi, log));\n }\n await Promise.all(promises);\n // we should now know the roomId, check if the room was synced before we received\n // the room id. Replace the room being created with the synced room.\n if (roomBeingCreated.roomId) {\n if (this.rooms.get(roomBeingCreated.roomId)) {\n this._tryReplaceRoomBeingCreated(roomBeingCreated.roomId, log);\n }\n await roomBeingCreated.adjustDirectMessageMapIfNeeded(this._user, this._storage, this._hsApi, log);\n }\n });\n return roomBeingCreated;\n }\n\n async obtainSyncLock(syncResponse) {\n const toDeviceEvents = syncResponse.to_device?.events;\n if (Array.isArray(toDeviceEvents) && toDeviceEvents.length) {\n return await this._deviceMessageHandler.obtainSyncLock(toDeviceEvents);\n }\n }\n\n async prepareSync(syncResponse, lock, txn, log) {\n const toDeviceEvents = syncResponse.to_device?.events;\n if (Array.isArray(toDeviceEvents) && toDeviceEvents.length) {\n return await log.wrap(\"deviceMsgs\", log => this._deviceMessageHandler.prepareSync(toDeviceEvents, lock, txn, log));\n }\n }\n\n /** @internal */\n async writeSync(syncResponse, syncFilterId, preparation, txn, log) {\n const changes = {\n syncInfo: null,\n e2eeAccountChanges: null,\n hasNewRoomKeys: false,\n deviceMessageDecryptionResults: null,\n changedDevices: null,\n };\n const syncToken = syncResponse.next_batch;\n if (syncToken !== this.syncToken) {\n const syncInfo = {token: syncToken, filterId: syncFilterId};\n // don't modify `this` because transaction might still fail\n txn.session.set(\"sync\", syncInfo);\n changes.syncInfo = syncInfo;\n }\n\n const deviceOneTimeKeysCount = syncResponse.device_one_time_keys_count;\n if (this._e2eeAccount && deviceOneTimeKeysCount) {\n changes.e2eeAccountChanges = this._e2eeAccount.writeSync(deviceOneTimeKeysCount, txn, log);\n }\n\n const deviceLists = syncResponse.device_lists;\n if (this._deviceTracker && Array.isArray(deviceLists?.changed) && deviceLists.changed.length) {\n await log.wrap(\"deviceLists\", log => this._deviceTracker.writeDeviceChanges(deviceLists.changed, txn, log));\n changes.changedDevices = deviceLists.changed;\n }\n\n if (preparation) {\n const {hasNewRoomKeys, decryptionResults} = await log.wrap(\"deviceMsgs\", log => this._deviceMessageHandler.writeSync(preparation, txn, log));\n changes.hasNewRoomKeys = hasNewRoomKeys;\n changes.deviceMessageDecryptionResults = decryptionResults;\n }\n\n // store account data\n const accountData = syncResponse[\"account_data\"];\n if (Array.isArray(accountData?.events)) {\n for (const event of accountData.events) {\n if (typeof event.type === \"string\") {\n txn.accountData.set(event);\n }\n }\n }\n return changes;\n }\n\n /** @internal */\n afterSync({syncInfo, e2eeAccountChanges}) {\n if (syncInfo) {\n // sync transaction succeeded, modify object state now\n this._syncInfo = syncInfo;\n }\n if (this._e2eeAccount) {\n this._e2eeAccount.afterSync(e2eeAccountChanges);\n }\n }\n\n /** @internal */\n async afterSyncCompleted(changes, isCatchupSync, log) {\n // we don't start uploading one-time keys until we've caught up with\n // to-device messages, to help us avoid throwing away one-time-keys that we\n // are about to receive messages for\n // (https://github.com/vector-im/riot-web/issues/2782).\n if (this._e2eeAccount && !isCatchupSync && !this._sessionInfo.isReadOnly) {\n const needsToUploadOTKs = await this._e2eeAccount.generateOTKsIfNeeded(this._storage, log);\n if (needsToUploadOTKs) {\n await log.wrap(\"uploadKeys\", log => this._e2eeAccount.uploadKeys(this._storage, false, log));\n }\n }\n if (changes.hasNewRoomKeys) {\n this._keyBackup.get()?.flush(log);\n }\n if (changes.deviceMessageDecryptionResults) {\n await this._deviceMessageHandler.afterSyncCompleted(changes.deviceMessageDecryptionResults, this._deviceTracker, this._hsApi, log);\n }\n if (changes.changedDevices?.includes(this.userId)) {\n this._secretSharing?.checkSecretValidity();\n }\n }\n\n _tryReplaceRoomBeingCreated(roomId, log) {\n for (const [,roomBeingCreated] of this._roomsBeingCreated) {\n if (roomBeingCreated.roomId === roomId) {\n const observableStatus = this._observedRoomStatus.get(roomBeingCreated.id);\n if (observableStatus) {\n log.log(`replacing room being created`)\n .set(\"localId\", roomBeingCreated.id)\n .set(\"roomId\", roomBeingCreated.roomId);\n observableStatus.set(observableStatus.get() | RoomStatus.Replaced);\n }\n roomBeingCreated.dispose();\n this._roomsBeingCreated.remove(roomBeingCreated.id);\n return;\n }\n }\n }\n\n async applyRoomCollectionChangesAfterSync(inviteStates, roomStates, archivedRoomStates, log) {\n // update the collections after sync\n for (const rs of roomStates) {\n if (rs.shouldAdd) {\n this._rooms.add(rs.id, rs.room);\n this._tryReplaceRoomBeingCreated(rs.id, log);\n } else if (rs.shouldRemove) {\n this._rooms.remove(rs.id);\n }\n }\n for (const is of inviteStates) {\n if (is.shouldAdd) {\n this._invites.add(is.id, is.invite);\n } else if (is.shouldRemove) {\n this._invites.remove(is.id);\n }\n }\n // now all the collections are updated, update the room status\n // so any listeners to the status will find the collections\n // completely up to date\n if (this._observedRoomStatus.size !== 0) {\n for (const ars of archivedRoomStates) {\n if (ars.shouldAdd) {\n this._observedRoomStatus.get(ars.id)?.set(RoomStatus.Archived);\n }\n }\n for (const rs of roomStates) {\n if (rs.shouldAdd) {\n this._observedRoomStatus.get(rs.id)?.set(RoomStatus.Joined);\n }\n }\n for (const is of inviteStates) {\n const statusObservable = this._observedRoomStatus.get(is.id);\n if (statusObservable) {\n const withInvited = statusObservable.get() | RoomStatus.Invited;\n if (is.shouldAdd) {\n statusObservable.set(withInvited);\n } else if (is.shouldRemove) {\n const withoutInvited = withInvited ^ RoomStatus.Invited;\n statusObservable.set(withoutInvited);\n }\n }\n }\n }\n }\n\n _forgetArchivedRoom(roomId) {\n const statusObservable = this._observedRoomStatus.get(roomId);\n if (statusObservable) {\n statusObservable.set((statusObservable.get() | RoomStatus.Archived) ^ RoomStatus.Archived);\n }\n }\n\n /** @internal */\n get syncToken() {\n return this._syncInfo?.token;\n }\n\n /** @internal */\n get syncFilterId() {\n return this._syncInfo?.filterId;\n }\n\n get user() {\n return this._user;\n }\n\n get mediaRepository() {\n return this._mediaRepository;\n }\n\n enablePushNotifications(enable) {\n if (enable) {\n return this._enablePush();\n } else {\n return this._disablePush();\n }\n }\n\n async _enablePush() {\n return this._platform.logger.run(\"enablePush\", async log => {\n const defaultPayload = Pusher.createDefaultPayload(this._sessionInfo.id);\n const pusher = await this._platform.notificationService.enablePush(Pusher, defaultPayload);\n if (!pusher) {\n log.set(\"no_pusher\", true);\n return false;\n }\n await pusher.enable(this._hsApi, log);\n // store pusher data, so we know we enabled it across reloads,\n // and we can disable it without too much hassle\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.session]);\n txn.session.set(PUSHER_KEY, pusher.serialize());\n await txn.complete();\n return true;\n });\n }\n\n\n async _disablePush() {\n return this._platform.logger.run(\"disablePush\", async log => {\n await this._platform.notificationService.disablePush();\n const readTxn = await this._storage.readTxn([this._storage.storeNames.session]);\n const pusherData = await readTxn.session.get(PUSHER_KEY);\n if (!pusherData) {\n // we've disabled push in the notif service at least\n return true;\n }\n const pusher = new Pusher(pusherData);\n await pusher.disable(this._hsApi, log);\n const txn = await this._storage.readWriteTxn([this._storage.storeNames.session]);\n txn.session.remove(PUSHER_KEY);\n await txn.complete();\n return true;\n });\n }\n\n async arePushNotificationsEnabled() {\n if (!await this._platform.notificationService.isPushEnabled()) {\n return false;\n }\n const readTxn = await this._storage.readTxn([this._storage.storeNames.session]);\n const pusherData = await readTxn.session.get(PUSHER_KEY);\n return !!pusherData;\n }\n\n async checkPusherEnabledOnHomeserver() {\n const readTxn = await this._storage.readTxn([this._storage.storeNames.session]);\n const pusherData = await readTxn.session.get(PUSHER_KEY);\n if (!pusherData) {\n return false;\n }\n const myPusher = new Pusher(pusherData);\n const serverPushersData = await this._hsApi.getPushers().response();\n const serverPushers = (serverPushersData?.pushers || []).map(data => new Pusher(data));\n return serverPushers.some(p => p.equals(myPusher));\n }\n\n async getRoomStatus(roomId) {\n const isBeingCreated = !!this._roomsBeingCreated.get(roomId);\n if (isBeingCreated) {\n return RoomStatus.BeingCreated;\n }\n const isJoined = !!this._rooms.get(roomId);\n if (isJoined) {\n return RoomStatus.Joined;\n } else {\n const isInvited = !!this._invites.get(roomId);\n const txn = await this._storage.readTxn([this._storage.storeNames.archivedRoomSummary]);\n const isArchived = await txn.archivedRoomSummary.has(roomId);\n if (isInvited && isArchived) {\n return RoomStatus.Invited | RoomStatus.Archived;\n } else if (isInvited) {\n return RoomStatus.Invited;\n } else if (isArchived) {\n return RoomStatus.Archived;\n } else {\n return RoomStatus.None;\n }\n }\n }\n\n async observeRoomStatus(roomId) {\n let observable = this._observedRoomStatus.get(roomId);\n if (!observable) {\n let status = undefined;\n // Create and set the observable with value = undefined, so that\n // we don't loose any sync changes that come in while we are busy\n // calculating the current room status.\n observable = new RetainedObservableValue(status, () => {\n this._observedRoomStatus.delete(roomId);\n });\n this._observedRoomStatus.set(roomId, observable);\n status = await this.getRoomStatus(roomId);\n // If observable.value is not undefined anymore, then some\n // change has come through the sync.\n if (observable.get() === undefined) {\n observable.set(status);\n }\n }\n return observable;\n }\n\n observeRoomState(roomStateHandler) {\n return this._roomStateHandler.subscribe(roomStateHandler);\n }\n\n /**\n Creates an empty (summary isn't loaded) the archived room if it isn't\n loaded already, assuming sync will either remove it (when rejoining) or\n write a full summary adopting it from the joined room when leaving\n\n @internal\n */\n createOrGetArchivedRoomForSync(roomId) {\n let archivedRoom = this._activeArchivedRooms.get(roomId);\n if (archivedRoom) {\n archivedRoom.retain();\n } else {\n archivedRoom = this._createArchivedRoom(roomId);\n }\n return archivedRoom;\n }\n\n loadArchivedRoom(roomId, log = null) {\n return this._platform.logger.wrapOrRun(log, \"loadArchivedRoom\", async log => {\n log.set(\"id\", roomId);\n const activeArchivedRoom = this._activeArchivedRooms.get(roomId);\n if (activeArchivedRoom) {\n activeArchivedRoom.retain();\n return activeArchivedRoom;\n }\n const txn = await this._storage.readTxn([\n this._storage.storeNames.archivedRoomSummary,\n this._storage.storeNames.roomMembers,\n ]);\n const summary = await txn.archivedRoomSummary.get(roomId);\n if (summary) {\n const room = this._createArchivedRoom(roomId);\n await room.load(summary, txn, log);\n return room;\n }\n });\n }\n\n joinRoom(roomIdOrAlias, log = null) {\n return this._platform.logger.wrapOrRun(log, \"joinRoom\", async log => {\n const body = await this._hsApi.joinIdOrAlias(roomIdOrAlias, {log}).response();\n return body.room_id;\n });\n }\n\n /**\n * Updates the access token used by the API. Does NOT\n * change the token in storage.\n * @param {string} token \n */\n updateAccessToken(token) {\n this._hsApi.updateAccessToken(token);\n }\n}\n\nimport {FeatureSet} from \"../features\";\nexport function tests() {\n function createStorageMock(session, pendingEvents = []) {\n return {\n readTxn() {\n return {\n session: {\n get(key) {\n return Promise.resolve(session[key]);\n }\n },\n pendingEvents: {\n getAll() {\n return Promise.resolve(pendingEvents);\n }\n },\n roomSummary: {\n getAll() {\n return Promise.resolve([]);\n }\n },\n invites: {\n getAll() {\n return Promise.resolve([]);\n }\n }\n };\n },\n storeNames: {}\n };\n }\n\n return {\n \"session data is not modified until after sync\": async (assert) => {\n const storage = createStorageMock({\n sync: {token: \"a\", filterId: 5}\n });\n const session = new Session({\n storage,\n sessionInfo: {userId: \"\"},\n platform: {\n clock: {\n createTimeout: () => undefined\n }\n },\n features: new FeatureSet(0)\n });\n await session.load();\n let syncSet = false;\n const syncTxn = {\n session: {\n set(key, value) {\n if (key === \"sync\") {\n assert.equal(value.token, \"b\");\n assert.equal(value.filterId, 6);\n syncSet = true;\n }\n }\n }\n };\n const newSessionData = await session.writeSync({next_batch: \"b\"}, 6, null, syncTxn, {});\n assert(syncSet);\n assert.equal(session.syncToken, \"a\");\n assert.equal(session.syncFilterId, 5);\n session.afterSync(newSessionData);\n assert.equal(session.syncToken, \"b\");\n assert.equal(session.syncFilterId, 6);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ILogItem} from \"../../logging/types\";\nimport {ILoginMethod} from \"./LoginMethod\";\nimport {HomeServerApi} from \"../net/HomeServerApi.js\";\n\nexport class PasswordLoginMethod implements ILoginMethod {\n private readonly _username: string;\n private readonly _password: string;\n public readonly homeserver: string;\n\n constructor({username, password, homeserver}: {username: string, password: string, homeserver: string}) {\n this._username = username;\n this._password = password;\n this.homeserver = homeserver;\n }\n\n async login(hsApi: HomeServerApi, deviceName: string, log: ILogItem): Promise> {\n return await hsApi.passwordLogin(this._username, this._password, deviceName, {log}).response();\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {makeTxnId} from \"../common.js\";\nimport {ILogItem} from \"../../logging/types\";\nimport {ILoginMethod} from \"./LoginMethod\";\nimport {HomeServerApi} from \"../net/HomeServerApi.js\";\n\nexport class TokenLoginMethod implements ILoginMethod {\n private readonly _loginToken: string;\n public readonly homeserver: string;\n\n constructor({ homeserver, loginToken }: { homeserver: string, loginToken: string}) {\n this.homeserver = homeserver;\n this._loginToken = loginToken;\n }\n\n async login(hsApi: HomeServerApi, deviceName: string, log: ILogItem): Promise> {\n return await hsApi.tokenLogin(this._loginToken, makeTxnId(), deviceName, {log}).response();\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class SSOLoginHelper{\n private _homeserver: string;\n\n constructor(homeserver: string) {\n this._homeserver = homeserver;\n }\n\n get homeserver(): string { return this._homeserver; }\n\n createSSORedirectURL(returnURL: string): string {\n return `${this._homeserver}/_matrix/client/r0/login/sso/redirect?redirectUrl=${encodeURIComponent(returnURL)}`;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {AuthenticationData, RegistrationParams} from \"../types\";\n\nexport abstract class BaseRegistrationStage {\n protected _session: string;\n protected _nextStage: BaseRegistrationStage;\n protected readonly _params?: Record\n\n constructor(session: string, params?: RegistrationParams) {\n this._session = session;\n this._params = params;\n }\n\n /**\n * eg: m.login.recaptcha or m.login.dummy\n */\n abstract get type(): string;\n\n /**\n * This method should return auth part that must be provided to\n * /register endpoint to successfully complete this stage\n */\n /** @internal */\n abstract generateAuthenticationData(): AuthenticationData;\n\n setNextStage(stage: BaseRegistrationStage) {\n this._nextStage = stage;\n }\n\n get nextStage(): BaseRegistrationStage {\n return this._nextStage;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AuthenticationData} from \"../types\";\nimport {BaseRegistrationStage} from \"./BaseRegistrationStage\";\n\nexport class DummyAuth extends BaseRegistrationStage {\n generateAuthenticationData(): AuthenticationData {\n return {\n session: this._session,\n type: this.type,\n }; \n }\n\n get type(): string {\n return \"m.login.dummy\";\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AuthenticationData} from \"../types\";\nimport {BaseRegistrationStage} from \"./BaseRegistrationStage\";\n\nexport class TermsAuth extends BaseRegistrationStage {\n generateAuthenticationData(): AuthenticationData {\n return {\n session: this._session,\n type: this.type,\n // No other auth data needed for m.login.terms\n }; \n }\n\n get type(): string {\n return \"m.login.terms\";\n }\n\n get privacyPolicy() {\n return this._params?.policies[\"privacy_policy\"];\n }\n\n get termsOfService() {\n return this._params?.policies[\"terms_of_service\"];\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AuthenticationData, RegistrationParams} from \"../types\";\nimport {BaseRegistrationStage} from \"./BaseRegistrationStage\";\n\nexport class TokenAuth extends BaseRegistrationStage {\n private _token?: string;\n private readonly _type: string;\n\n constructor(session: string, params: RegistrationParams | undefined, type: string) {\n super(session, params);\n this._type = type;\n }\n\n\n generateAuthenticationData(): AuthenticationData {\n if (!this._token) {\n throw new Error(\"No token provided for TokenAuth\");\n }\n return {\n session: this._session,\n type: this._type,\n token: this._token,\n }; \n }\n\n setToken(token: string) {\n this._token = token;\n }\n\n get type(): string {\n return this._type;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {HomeServerApi} from \"../net/HomeServerApi\";\nimport type {BaseRegistrationStage} from \"./stages/BaseRegistrationStage\";\nimport {DummyAuth} from \"./stages/DummyAuth\";\nimport {TermsAuth} from \"./stages/TermsAuth\";\nimport {TokenAuth} from \"./stages/TokenAuth\";\nimport type {\n AccountDetails,\n RegistrationFlow,\n RegistrationResponseMoreDataNeeded,\n RegistrationResponse,\n RegistrationResponseSuccess,\n AuthData,\n RegistrationParams,\n} from \"./types\";\n\ntype FlowSelector = (flows: RegistrationFlow[]) => RegistrationFlow | void;\n\nexport class Registration {\n private readonly _hsApi: HomeServerApi;\n private readonly _accountDetails: AccountDetails;\n private readonly _flowSelector: FlowSelector;\n private _registerResponse?: RegistrationResponseSuccess;\n public readonly homeserver: string;\n\n constructor(homeserver: string, hsApi: HomeServerApi, accountDetails: AccountDetails, flowSelector?: FlowSelector) {\n this.homeserver = homeserver;\n this._hsApi = hsApi;\n this._accountDetails = accountDetails;\n this._flowSelector = flowSelector ?? (flows => flows[0]);\n }\n\n async start(): Promise {\n const response = await this._hsApi.register(\n this._accountDetails.username,\n this._accountDetails.password,\n this._accountDetails.initialDeviceDisplayName,\n undefined,\n this._accountDetails.inhibitLogin).response();\n return this.parseStagesFromResponse(response);\n }\n\n /**\n * Finish a registration stage, return value is:\n * - the next stage if this stage was completed successfully\n * - undefined if registration is completed\n */\n async submitStage(stage: BaseRegistrationStage): Promise {\n const auth = stage.generateAuthenticationData();\n const { username, password, initialDeviceDisplayName, inhibitLogin } = this._accountDetails;\n const request = this._hsApi.register(username, password, initialDeviceDisplayName, auth, inhibitLogin);\n const response = await request.response();\n const status = await request.responseCode();\n const registrationResponse: RegistrationResponse = { ...response, status };\n return this.parseRegistrationResponse(registrationResponse, stage);\n }\n\n private parseStagesFromResponse(response: RegistrationResponseMoreDataNeeded): BaseRegistrationStage {\n const { session, params } = response;\n const flow = this._flowSelector(response.flows);\n if (!flow) {\n throw new Error(\"flowSelector did not return any flow!\");\n }\n let firstStage: BaseRegistrationStage | undefined;\n let lastStage: BaseRegistrationStage | undefined;\n for (const stage of flow.stages) {\n const registrationStage = this._createRegistrationStage(stage, session, params);\n if (!firstStage) {\n firstStage = registrationStage;\n lastStage = registrationStage;\n } else {\n lastStage!.setNextStage(registrationStage);\n lastStage = registrationStage;\n }\n }\n return firstStage!;\n }\n\n private async parseRegistrationResponse(response: RegistrationResponse, currentStage: BaseRegistrationStage) {\n switch (response.status) {\n case 200:\n this._registerResponse = response;\n return undefined;\n case 401:\n if (response.completed?.includes(currentStage.type)) {\n return currentStage.nextStage;\n }\n else {\n throw new Error(\"This stage could not be completed!\");\n }\n }\n }\n\n private _createRegistrationStage(type: string, session: string, params?: RegistrationParams) {\n switch (type) {\n case \"m.login.dummy\":\n return new DummyAuth(session, params?.[type]);\n case \"m.login.terms\":\n return new TermsAuth(session, params?.[type]);\n case \"org.matrix.msc3231.login.registration_token\":\n case \"m.login.registration_token\":\n return new TokenAuth(session, params?.[type], type);\n default:\n throw new Error(`Unknown stage: ${type}`);\n }\n }\n\n get authData(): AuthData | undefined {\n if (this._registerResponse) {\n return {\n accessToken: this._registerResponse.access_token,\n homeserver: this.homeserver,\n userId: this._registerResponse.user_id,\n deviceId: this._registerResponse.device_id,\n };\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {createEnum} from \"../utils/enum\";\nimport {lookupHomeserver} from \"./well-known.js\";\nimport {AbortableOperation} from \"../utils/AbortableOperation\";\nimport {ObservableValue} from \"../observable/value\";\nimport {HomeServerApi} from \"./net/HomeServerApi\";\nimport {Reconnector, ConnectionStatus} from \"./net/Reconnector\";\nimport {ExponentialRetryDelay} from \"./net/ExponentialRetryDelay\";\nimport {MediaRepository} from \"./net/MediaRepository\";\nimport {RequestScheduler} from \"./net/RequestScheduler\";\nimport {Sync, SyncStatus} from \"./Sync.js\";\nimport {Session} from \"./Session.js\";\nimport {PasswordLoginMethod} from \"./login/PasswordLoginMethod\";\nimport {TokenLoginMethod} from \"./login/TokenLoginMethod\";\nimport {SSOLoginHelper} from \"./login/SSOLoginHelper\";\nimport {getDehydratedDevice} from \"./e2ee/Dehydration.js\";\nimport {Registration} from \"./registration/Registration\";\nimport {FeatureSet} from \"../features\";\n\nexport const LoadStatus = createEnum(\n \"NotLoading\",\n \"Login\",\n \"LoginFailed\",\n \"QueryAccount\", // check for dehydrated device after login\n \"AccountSetup\", // asked to restore from dehydrated device if present, call sc.accountSetup.finish() to progress to the next stage\n \"Loading\",\n \"SessionSetup\", // upload e2ee keys, ...\n \"Migrating\", // not used atm, but would fit here\n \"FirstSync\",\n \"Error\",\n \"Ready\",\n);\n\nexport const LoginFailure = createEnum(\n \"Connection\",\n \"Credentials\",\n \"Unknown\",\n);\n\nexport class Client {\n constructor(platform, features = new FeatureSet(0)) {\n this._platform = platform;\n this._sessionStartedByReconnector = false;\n this._status = new ObservableValue(LoadStatus.NotLoading);\n this._error = null;\n this._loginFailure = null;\n this._reconnector = null;\n this._session = null;\n this._sync = null;\n this._sessionId = null;\n this._storage = null;\n this._requestScheduler = null;\n this._olmPromise = platform.loadOlm();\n this._workerPromise = platform.loadOlmWorker();\n this._accountSetup = undefined;\n this._features = features;\n }\n\n createNewSessionId() {\n return (Math.floor(this._platform.random() * Number.MAX_SAFE_INTEGER)).toString();\n }\n\n get sessionId() {\n return this._sessionId;\n }\n\n async startWithExistingSession(sessionId) {\n if (this._status.get() !== LoadStatus.NotLoading) {\n return;\n }\n this._status.set(LoadStatus.Loading);\n await this._platform.logger.run(\"load session\", async log => {\n log.set(\"id\", sessionId);\n try {\n const sessionInfo = await this._platform.sessionInfoStorage.get(sessionId);\n if (!sessionInfo) {\n throw new Error(\"Invalid session id: \" + sessionId);\n }\n await this._loadSessionInfo(sessionInfo, null, log);\n log.set(\"status\", this._status.get());\n } catch (err) {\n log.catch(err);\n this._error = err;\n this._status.set(LoadStatus.Error);\n }\n });\n }\n\n // TODO: When converted to typescript this should return the same type\n // as this._loginOptions is in LoginViewModel.ts (LoginOptions).\n _parseLoginOptions(options, homeserver) {\n /*\n Take server response and return new object which has two props password and sso which\n implements LoginMethod\n */\n const flows = options.flows;\n const result = {homeserver};\n for (const flow of flows) {\n if (flow.type === \"m.login.password\") {\n result.password = (username, password) => new PasswordLoginMethod({homeserver, username, password});\n }\n else if (flow.type === \"m.login.sso\" && flows.find(flow => flow.type === \"m.login.token\")) {\n result.sso = new SSOLoginHelper(homeserver);\n }\n else if (flow.type === \"m.login.token\") {\n result.token = loginToken => new TokenLoginMethod({homeserver, loginToken});\n }\n }\n return result;\n }\n\n queryLogin(homeserver) {\n return new AbortableOperation(async setAbortable => {\n homeserver = await lookupHomeserver(homeserver, (url, options) => {\n return setAbortable(this._platform.request(url, options));\n });\n const hsApi = new HomeServerApi({homeserver, request: this._platform.request});\n const response = await setAbortable(hsApi.getLoginFlows()).response();\n return this._parseLoginOptions(response, homeserver);\n });\n }\n\n async startRegistration(homeserver, username, password, initialDeviceDisplayName, flowSelector) {\n const request = this._platform.request;\n const hsApi = new HomeServerApi({homeserver, request});\n const registration = new Registration(homeserver, hsApi, {\n username,\n password,\n initialDeviceDisplayName,\n },\n flowSelector);\n return registration;\n }\n\n /** Method to start client after registration or with given access token.\n * To start the client after registering, use `startWithAuthData(registration.authData)`.\n * `homeserver` won't be resolved or normalized using this method,\n * use `lookupHomeserver` first if needed (not needed after registration) \n * \n * Setting isReadOnly to false disables OTK uploads.\n * Only do this if you're sure that you will never send encrypted messages.\n * */\n async startWithAuthData({accessToken, deviceId, userId, homeserver, isReadOnly = false}) {\n await this._platform.logger.run(\"startWithAuthData\", async (log) => {\n if (isReadOnly) {\n log.set(\"isReadonly (Disabled OTK Upload)\", true);\n }\n await this._createSessionAfterAuth({accessToken, deviceId, userId, homeserver}, true, isReadOnly, log);\n });\n }\n\n async startWithLogin(loginMethod, {inspectAccountSetup} = {}) {\n const currentStatus = this._status.get();\n if (currentStatus !== LoadStatus.LoginFailed &&\n currentStatus !== LoadStatus.NotLoading &&\n currentStatus !== LoadStatus.Error) {\n return;\n }\n this._resetStatus();\n await this._platform.logger.run(\"login\", async log => {\n this._status.set(LoadStatus.Login);\n let sessionInfo;\n try {\n const request = this._platform.request;\n const hsApi = new HomeServerApi({homeserver: loginMethod.homeserver, request});\n const loginData = await loginMethod.login(hsApi, \"Hydrogen\", log);\n sessionInfo = {\n deviceId: loginData.device_id,\n userId: loginData.user_id,\n homeserver: loginMethod.homeserver,\n accessToken: loginData.access_token,\n };\n } catch (err) {\n this._error = err;\n if (err.name === \"HomeServerError\") {\n if (err.errcode === \"M_FORBIDDEN\") {\n this._loginFailure = LoginFailure.Credentials;\n } else {\n this._loginFailure = LoginFailure.Unknown;\n }\n log.set(\"loginFailure\", this._loginFailure);\n this._status.set(LoadStatus.LoginFailed);\n } else if (err.name === \"ConnectionError\") {\n this._loginFailure = LoginFailure.Connection;\n this._status.set(LoadStatus.LoginFailed);\n } else {\n this._status.set(LoadStatus.Error);\n }\n return;\n }\n await this._createSessionAfterAuth(sessionInfo, inspectAccountSetup, false, log);\n });\n }\n\n async _createSessionAfterAuth({deviceId, userId, accessToken, homeserver}, inspectAccountSetup, isReadOnly, log) {\n const id = this.createNewSessionId();\n const lastUsed = this._platform.clock.now();\n const sessionInfo = {\n id,\n deviceId,\n userId,\n homeServer: homeserver, // deprecate this over time\n homeserver,\n accessToken,\n lastUsed,\n isReadOnly,\n };\n let dehydratedDevice;\n if (inspectAccountSetup) {\n dehydratedDevice = await this._inspectAccountAfterLogin(sessionInfo, log);\n if (dehydratedDevice) {\n sessionInfo.deviceId = dehydratedDevice.deviceId;\n }\n }\n await this._platform.sessionInfoStorage.add(sessionInfo);\n // loading the session can only lead to\n // LoadStatus.Error in case of an error,\n // so separate try/catch\n try {\n await this._loadSessionInfo(sessionInfo, dehydratedDevice, log);\n log.set(\"status\", this._status.get());\n } catch (err) {\n log.catch(err);\n // free olm Account that might be contained\n dehydratedDevice?.dispose();\n this._error = err;\n this._status.set(LoadStatus.Error);\n }\n }\n\n async _loadSessionInfo(sessionInfo, dehydratedDevice, log) {\n log.set(\"appVersion\", this._platform.version);\n const clock = this._platform.clock;\n this._sessionStartedByReconnector = false;\n this._status.set(LoadStatus.Loading);\n this._reconnector = new Reconnector({\n onlineStatus: this._platform.onlineStatus,\n retryDelay: new ExponentialRetryDelay(clock.createTimeout),\n createMeasure: clock.createMeasure,\n });\n const hsApi = new HomeServerApi({\n homeserver: sessionInfo.homeServer,\n accessToken: sessionInfo.accessToken,\n request: this._platform.request,\n reconnector: this._reconnector,\n });\n this._sessionId = sessionInfo.id;\n this._storage = await this._platform.storageFactory.create(\n sessionInfo.id,\n log\n );\n // no need to pass access token to session\n const filteredSessionInfo = {\n id: sessionInfo.id,\n deviceId: sessionInfo.deviceId,\n userId: sessionInfo.userId,\n homeserver: sessionInfo.homeServer,\n isReadOnly: sessionInfo.isReadOnly,\n };\n const olm = await this._olmPromise;\n let olmWorker = null;\n if (this._workerPromise) {\n olmWorker = await this._workerPromise;\n }\n this._requestScheduler = new RequestScheduler({ hsApi, clock });\n this._requestScheduler.start();\n\n const lastVersionsResponse = await hsApi\n .versions({ timeout: 10000, log })\n .response();\n const mediaRepository = new MediaRepository({\n homeserver: sessionInfo.homeServer,\n platform: this._platform,\n serverVersions: lastVersionsResponse.versions,\n });\n\n // Let the serviceWorkerHandler know of this access-token and homeserver\n this._platform.updateService.updateAuthData({\n accessToken: sessionInfo.accessToken,\n homeserver: sessionInfo.homeServer,\n });\n\n this._session = new Session({\n storage: this._storage,\n sessionInfo: filteredSessionInfo,\n hsApi: this._requestScheduler.hsApi,\n olm,\n olmWorker,\n mediaRepository,\n platform: this._platform,\n features: this._features,\n });\n await this._session.load(log);\n if (dehydratedDevice) {\n await log.wrap(\"dehydrateIdentity\", (log) =>\n this._session.dehydrateIdentity(dehydratedDevice, log)\n );\n await this._session.setupDehydratedDevice(\n dehydratedDevice.key,\n log\n );\n } else if (!this._session.hasIdentity) {\n this._status.set(LoadStatus.SessionSetup);\n await log.wrap(\"createIdentity\", (log) =>\n this._session.createIdentity(log)\n );\n }\n\n this._sync = new Sync({\n hsApi: this._requestScheduler.hsApi,\n storage: this._storage,\n session: this._session,\n logger: this._platform.logger,\n });\n // notify sync and session when back online\n this._reconnectSubscription =\n this._reconnector.connectionStatus.subscribe((state) => {\n if (state === ConnectionStatus.Online) {\n this._platform.logger.runDetached(\n \"reconnect\",\n async (log) => {\n // needs to happen before sync and session or it would abort all requests\n this._requestScheduler.start();\n this._sync.start();\n this._sessionStartedByReconnector = true;\n const d = dehydratedDevice;\n dehydratedDevice = undefined;\n await log.wrap(\"session start\", (log) =>\n this._session.start(\n this._reconnector.lastVersionsResponse,\n d,\n log\n )\n );\n }\n );\n }\n });\n await log.wrap(\"wait first sync\", () => this._waitForFirstSync());\n if (this._isDisposed) {\n return;\n }\n this._status.set(LoadStatus.Ready);\n\n // if the sync failed, and then the reconnector\n // restored the connection, it would have already\n // started to session, so check first\n // to prevent an extra /versions request\n if (!this._sessionStartedByReconnector) {\n if (this._isDisposed) {\n return;\n }\n const d = dehydratedDevice;\n dehydratedDevice = undefined;\n // log as ref as we don't want to await it\n await log.wrap(\"session start\", (log) =>\n this._session.start(lastVersionsResponse, d, log)\n );\n }\n }\n\n /**\n * Update the access token in use by the client.\n * Will also update the token in session storage.\n * @param {string} token A Matrix Access Token \n */\n async updateAccessToken(token) {\n if (!this._session) {\n throw Error(\"No session loaded, cannot update access token\");\n }\n this._session.updateAccessToken(token);\n this._platform.updateService.updateAuthData({\n accessToken: token,\n });\n await this._platform.sessionInfoStorage.updateAccessToken(this._sessionId, token);\n }\n\n async _waitForFirstSync() {\n this._sync.start();\n this._status.set(LoadStatus.FirstSync);\n // only transition into Ready once the first sync has succeeded\n this._waitForFirstSyncHandle = this._sync.status.waitFor(s => {\n if (s === SyncStatus.Stopped) {\n // keep waiting if there is a ConnectionError\n // as the reconnector above will call\n // sync.start again to retry in this case\n return this._sync.error?.name !== \"ConnectionError\";\n }\n return s === SyncStatus.Syncing;\n });\n try {\n await this._waitForFirstSyncHandle.promise;\n if (this._sync.status.get() === SyncStatus.Stopped && this._sync.error) {\n throw this._sync.error;\n }\n } catch (err) {\n // if dispose is called from stop, bail out\n if (err.name === \"AbortError\") {\n return;\n }\n throw err;\n } finally {\n this._waitForFirstSyncHandle = null;\n }\n }\n\n _inspectAccountAfterLogin(sessionInfo, log) {\n return log.wrap(\"inspectAccount\", async log => {\n this._status.set(LoadStatus.QueryAccount);\n const hsApi = new HomeServerApi({\n homeserver: sessionInfo.homeServer,\n accessToken: sessionInfo.accessToken,\n request: this._platform.request,\n });\n const olm = await this._olmPromise;\n let encryptedDehydratedDevice;\n try {\n encryptedDehydratedDevice = await getDehydratedDevice(hsApi, olm, this._platform, log);\n } catch (err) {\n if (err.name === \"HomeServerError\") {\n log.set(\"not_supported\", true);\n } else {\n throw err;\n }\n }\n if (encryptedDehydratedDevice) {\n let resolveStageFinish;\n const promiseStageFinish = new Promise(r => resolveStageFinish = r);\n this._accountSetup = new AccountSetup(encryptedDehydratedDevice, resolveStageFinish);\n this._status.set(LoadStatus.AccountSetup);\n await promiseStageFinish;\n const dehydratedDevice = this._accountSetup?._dehydratedDevice;\n this._accountSetup = null;\n return dehydratedDevice;\n }\n });\n }\n\n get accountSetup() {\n return this._accountSetup;\n }\n\n get loadStatus() {\n return this._status;\n }\n\n get loadError() {\n return this._error;\n }\n\n get loginFailure() {\n return this._loginFailure;\n }\n\n /** only set at loadStatus InitialSync, CatchupSync or Ready */\n get sync() {\n return this._sync;\n }\n\n /** only set at loadStatus InitialSync, CatchupSync or Ready */\n get session() {\n return this._session;\n }\n\n get reconnector() {\n return this._reconnector;\n }\n\n get _isDisposed() {\n return !this._reconnector;\n }\n\n startLogout(sessionId) {\n return this._platform.logger.run(\"logout\", async log => {\n this._sessionId = sessionId;\n log.set(\"id\", this._sessionId);\n const sessionInfo = await this._platform.sessionInfoStorage.get(this._sessionId);\n if (!sessionInfo) {\n throw new Error(`Could not find session for id ${this._sessionId}`);\n }\n try {\n const hsApi = new HomeServerApi({\n homeserver: sessionInfo.homeServer,\n accessToken: sessionInfo.accessToken,\n request: this._platform.request\n });\n await hsApi.logout({log}).response();\n } catch (err) {}\n await this.deleteSession(log);\n });\n }\n\n startForcedLogout(sessionId) {\n return this._platform.logger.run(\"forced-logout\", async log => {\n this._sessionId = sessionId;\n log.set(\"id\", this._sessionId);\n await this.deleteSession(log);\n });\n }\n\n dispose() {\n if (this._reconnectSubscription) {\n this._reconnectSubscription();\n this._reconnectSubscription = null;\n }\n this._reconnector = null;\n if (this._requestScheduler) {\n this._requestScheduler.stop();\n this._requestScheduler = null;\n }\n if (this._sync) {\n this._sync.stop();\n this._sync = null;\n }\n if (this._session) {\n this._session.dispose();\n this._session = null;\n }\n if (this._waitForFirstSyncHandle) {\n this._waitForFirstSyncHandle.dispose();\n this._waitForFirstSyncHandle = null;\n }\n if (this._storage) {\n this._storage.close();\n this._storage = null;\n }\n }\n\n async deleteSession(log) {\n if (this._sessionId) {\n // need to dispose first, so the storage is closed,\n // and also first sync finishing won't call Session.start anymore,\n // which assumes that the storage works.\n this.dispose();\n // if one fails, don't block the other from trying\n // also, run in parallel\n await Promise.all([\n log.wrap(\"storageFactory\", () => this._platform.storageFactory.delete(this._sessionId)),\n log.wrap(\"sessionInfoStorage\", () => this._platform.sessionInfoStorage.delete(this._sessionId)),\n ]);\n this._sessionId = null;\n }\n }\n\n _resetStatus() {\n this._status.set(LoadStatus.NotLoading);\n this._error = null;\n this._loginFailure = null;\n }\n}\n\nclass AccountSetup {\n constructor(encryptedDehydratedDevice, finishStage) {\n this._encryptedDehydratedDevice = encryptedDehydratedDevice;\n this._dehydratedDevice = undefined;\n this._finishStage = finishStage;\n }\n\n get encryptedDehydratedDevice() {\n return this._encryptedDehydratedDevice;\n }\n\n finish(dehydratedDevice) {\n this._dehydratedDevice = dehydratedDevice;\n this._finishStage();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// ViewModel should just be an eventemitter, not an ObservableValue\n// as in some cases it would really be more convenient to have multiple events (like telling the timeline to scroll down)\n// we do need to return a disposable from EventEmitter.on, or at least have a method here to easily track a subscription to an EventEmitter\n\nimport {EventEmitter} from \"../utils/EventEmitter\";\nimport {Disposables} from \"../utils/Disposables\";\n\nimport type {Disposable} from \"../utils/Disposables\";\nimport type {Platform} from \"../platform/web/Platform\";\nimport type {Clock} from \"../platform/web/dom/Clock\";\nimport type {ILogger} from \"../logging/types\";\nimport type {Navigation} from \"./navigation/Navigation\";\nimport type {SegmentType} from \"./navigation/index\";\nimport type {IURLRouter} from \"./navigation/URLRouter\";\nimport type { ITimeFormatter } from \"../platform/types/types\";\nimport type { FeatureSet } from \"../features\";\n\nexport type Options = {\n platform: Platform;\n logger: ILogger;\n urlRouter: IURLRouter;\n navigation: Navigation;\n emitChange?: (params: any) => void;\n features: FeatureSet\n}\n\n\nexport class ViewModel = Options> extends EventEmitter<{change: never}> {\n private disposables?: Disposables;\n private _isDisposed = false;\n private _options: Readonly;\n\n constructor(options: Readonly) {\n super();\n this._options = options;\n }\n\n childOptions(explicitOptions: T): T & O {\n return Object.assign({}, this._options, explicitOptions);\n }\n\n get options(): Readonly { return this._options; }\n\n // makes it easier to pass through dependencies of a sub-view model\n getOption(name: N): O[N] {\n return this._options[name];\n }\n\n observeNavigation(type: T, onChange: (value: N[T], type: T) => void): void {\n const segmentObservable = this.navigation.observe(type);\n const unsubscribe = segmentObservable.subscribe((value: N[T]) => {\n onChange(value, type);\n });\n this.track(unsubscribe);\n }\n\n track(disposable: D): D {\n if (!this.disposables) {\n this.disposables = new Disposables();\n }\n return this.disposables.track(disposable);\n }\n\n untrack(disposable: Disposable): undefined {\n if (this.disposables) {\n return this.disposables.untrack(disposable);\n }\n return undefined;\n }\n\n dispose(): void {\n if (this.disposables) {\n this.disposables.dispose();\n }\n this._isDisposed = true;\n }\n\n get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n disposeTracked(disposable: Disposable | undefined): undefined {\n if (this.disposables) {\n return this.disposables.disposeTracked(disposable);\n }\n return undefined;\n }\n\n // TODO: this will need to support binding\n // if any of the expr is a function, assume the function is a binding, and return a binding function ourselves\n //\n // translated string should probably always be bindings, unless we're fine with a refresh when changing the language?\n // we probably are, if we're using routing with a url, we could just refresh.\n i18n(parts: TemplateStringsArray, ...expr: any[]): string {\n // just concat for now\n let result = \"\";\n for (let i = 0; i < parts.length; ++i) {\n result = result + parts[i];\n if (i < expr.length) {\n result = result + expr[i];\n }\n }\n return result;\n }\n\n emitChange(changedProps?: any): void {\n if (this._options.emitChange) {\n this._options.emitChange(changedProps);\n } else {\n this.emit(\"change\", changedProps);\n }\n }\n\n get platform(): Platform {\n return this._options.platform;\n }\n\n get clock(): Clock {\n return this._options.platform.clock;\n }\n\n get logger(): ILogger {\n return this.platform.logger;\n }\n\n get urlRouter(): IURLRouter {\n return this._options.urlRouter;\n }\n\n get features(): FeatureSet {\n return this._options.features;\n }\n\n get navigation(): Navigation {\n // typescript needs a little help here\n return this._options.navigation as unknown as Navigation;\n }\n\n get timeFormatter(): ITimeFormatter {\n return this._options.platform.timeFormatter;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { Platform } from \"../platform/web/Platform\";\nimport { MediaRepository } from \"../matrix/net/MediaRepository\";\n\nexport function avatarInitials(name: string): string {\n let firstChar = name.charAt(0);\n if (firstChar === \"!\" || firstChar === \"@\" || firstChar === \"#\") {\n firstChar = name.charAt(1);\n }\n return firstChar.toUpperCase();\n}\n\n/**\n * calculates a numeric hash for a given string\n *\n * @param {string} str string to hash\n *\n * @return {number}\n */\nfunction hashCode(str: string): number {\n let hash = 0;\n let i: number;\n let chr: number;\n if (str.length === 0) {\n return hash;\n }\n for (i = 0; i < str.length; i++) {\n chr = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0;\n }\n return Math.abs(hash);\n}\n\nexport function getIdentifierColorNumber(id: string): number {\n return (hashCode(id) % 8) + 1;\n}\n\nexport function getAvatarHttpUrl(avatarUrl: string | undefined, cssSize: number, platform: Platform, mediaRepository: MediaRepository): string | undefined {\n if (avatarUrl) {\n const imageSize = cssSize * platform.devicePixelRatio;\n return mediaRepository.mxcUrlThumbnail(avatarUrl, imageSize, imageSize, \"crop\");\n }\n return undefined;\n}\n\n// move to AvatarView.js when converting to typescript\nexport interface IAvatarContract {\n avatarLetter: string;\n avatarColorNumber: number;\n avatarUrl: (size: number) => string | undefined;\n avatarTitle: string;\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\nimport {ViewModel} from \"../../ViewModel\";\n\nconst KIND_ORDER = [\"roomBeingCreated\", \"invite\", \"room\"];\n\nexport class BaseTileViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._isOpen = false;\n this._hidden = false;\n }\n\n get hidden() {\n return this._hidden;\n }\n\n set hidden(value) {\n if (value !== this._hidden) {\n this._hidden = value;\n this.emitChange(\"hidden\");\n }\n }\n\n close() {\n if (this._isOpen) {\n this._isOpen = false;\n this.emitChange(\"isOpen\");\n }\n }\n\n open() {\n if (!this._isOpen) {\n this._isOpen = true;\n this.emitChange(\"isOpen\");\n }\n }\n\n get isOpen() {\n return this._isOpen;\n }\n\n compare(other) {\n if (other.kind !== this.kind) {\n return KIND_ORDER.indexOf(this.kind) - KIND_ORDER.indexOf(other.kind);\n }\n return 0;\n }\n\n // Avatar view model contract\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._avatarSource.avatarColorId);\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._avatarSource.avatarUrl, size, this.platform, this._avatarSource.mediaRepository);\n }\n\n get avatarTitle() {\n return this.name;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseTileViewModel} from \"./BaseTileViewModel.js\";\n\nexport class RoomTileViewModel extends BaseTileViewModel {\n constructor(options) {\n super(options);\n const {room} = options;\n this._room = room;\n this._url = this.urlRouter.openRoomActionUrl(this._room.id);\n }\n\n get kind() {\n return \"room\";\n }\n\n get url() {\n return this._url;\n }\n\n /** very important that sorting order is stable and that comparing\n * to itself always returns 0, otherwise SortedMapList will\n * remove the wrong children, etc ... */\n compare(other) {\n const parentComparison = super.compare(other);\n if (parentComparison !== 0) {\n return parentComparison;\n }\n /*\n put unread rooms first\n then put rooms with a timestamp first, and sort by name\n then sort by name for rooms without a timestamp\n */\n const myRoom = this._room;\n const theirRoom = other._room;\n\n if (myRoom.isLowPriority !== theirRoom.isLowPriority) {\n if (myRoom.isLowPriority) {\n return 1;\n }\n return -1;\n }\n const myTimestamp = myRoom.lastMessageTimestamp;\n const theirTimestamp = theirRoom.lastMessageTimestamp;\n const myTimestampValid = Number.isSafeInteger(myTimestamp);\n const theirTimestampValid = Number.isSafeInteger(theirTimestamp);\n // if either does not have a timestamp, put the one with a timestamp first\n if (myTimestampValid !== theirTimestampValid) {\n if (!theirTimestampValid) {\n return -1;\n }\n return 1;\n }\n const timeDiff = theirTimestamp - myTimestamp;\n if (timeDiff === 0 || !theirTimestampValid || !myTimestampValid) {\n // sort alphabetically\n const nameCmp = this.name.localeCompare(other.name);\n if (nameCmp === 0) {\n return this._room.id.localeCompare(other._room.id);\n }\n return nameCmp;\n }\n return timeDiff;\n }\n\n get isUnread() {\n return this._room.isUnread;\n }\n\n get name() {\n return this._room.name || this.i18n`Empty Room`;\n }\n\n get badgeCount() {\n return this._room.notificationCount;\n }\n\n get isHighlighted() {\n return this._room.highlightCount !== 0;\n }\n\n get _avatarSource() {\n return this._room;\n }\n}\n","/*\nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function comparePrimitive(a, b) {\n if (a === b) {\n return 0;\n } else {\n return a < b ? -1 : 1;\n }\n}\n","/*\nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseTileViewModel} from \"./BaseTileViewModel.js\";\nimport {comparePrimitive} from \"./common\";\n\nexport class InviteTileViewModel extends BaseTileViewModel {\n constructor(options) {\n super(options);\n const {invite} = options;\n this._invite = invite;\n this._url = this.urlRouter.openRoomActionUrl(this._invite.id);\n }\n\n get busy() { return this._invite.accepting || this._invite.rejecting; }\n get kind() { return \"invite\"; }\n get url() { return this._url; }\n get name() { return this._invite.name; }\n get isHighlighted() { return true; }\n get isUnread() { return true; }\n get badgeCount() { return this.i18n`!`; }\n get _avatarSource() { return this._invite; }\n\n /** very important that sorting order is stable and that comparing\n * to itself always returns 0, otherwise SortedMapList will\n * remove the wrong children, etc ... */\n compare(other) {\n const parentComparison = super.compare(other);\n if (parentComparison !== 0) {\n return parentComparison;\n }\n const timeDiff = other._invite.timestamp - this._invite.timestamp;\n if (timeDiff !== 0) {\n return timeDiff;\n }\n return comparePrimitive(this._invite.id, other._invite.id);\n }\n}\n\nexport function tests() {\n return {\n \"test compare with timestamp\": assert => {\n const urlRouter = {openRoomActionUrl() { return \"\";}}\n const vm1 = new InviteTileViewModel({invite: {timestamp: 500, id: \"1\"}, urlRouter});\n const vm2 = new InviteTileViewModel({invite: {timestamp: 250, id: \"2\"}, urlRouter});\n assert(vm1.compare(vm2) < 0);\n assert(vm2.compare(vm1) > 0);\n assert.equal(vm1.compare(vm1), 0);\n },\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseTileViewModel} from \"./BaseTileViewModel.js\";\nimport {comparePrimitive} from \"./common\";\n\nexport class RoomBeingCreatedTileViewModel extends BaseTileViewModel {\n constructor(options) {\n super(options);\n const {roomBeingCreated} = options;\n this._roomBeingCreated = roomBeingCreated;\n this._url = this.urlRouter.openRoomActionUrl(this._roomBeingCreated.id);\n }\n\n get busy() { return !this._roomBeingCreated.error; }\n get kind() { return \"roomBeingCreated\"; }\n get isHighlighted() { return !this.busy; }\n get badgeCount() { return !this.busy && this.i18n`Failed`; }\n get url() { return this._url; }\n get name() { return this._roomBeingCreated.name; }\n get _avatarSource() { return this._roomBeingCreated; }\n\n /** very important that sorting order is stable and that comparing\n * to itself always returns 0, otherwise SortedMapList will\n * remove the wrong children, etc ... */\n compare(other) {\n const parentCmp = super.compare(other);\n if (parentCmp !== 0) {\n return parentCmp;\n }\n const nameCmp = comparePrimitive(this.name, other.name);\n if (nameCmp === 0) {\n return comparePrimitive(this._roomBeingCreated.id, other._roomBeingCreated.id);\n } else {\n return nameCmp;\n }\n }\n\n avatarUrl(size) {\n // allow blob url which doesn't need mxc => http resolution\n return this._roomBeingCreated.avatarBlobUrl ?? super.avatarUrl(size);\n }\n}\n\nexport function tests() {\n return {\n \"test compare with names\": assert => {\n const urlRouter = {openRoomActionUrl() { return \"\";}}\n const vm1 = new RoomBeingCreatedTileViewModel({roomBeingCreated: {name: \"A\", id: \"1\"}, urlRouter});\n const vm2 = new RoomBeingCreatedTileViewModel({roomBeingCreated: {name: \"B\", id: \"2\"}, urlRouter});\n assert(vm1.compare(vm2) < 0);\n assert(vm2.compare(vm1) > 0);\n assert.equal(vm1.compare(vm1), 0);\n },\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class RoomFilter {\n constructor(query) {\n this._parts = query.split(\" \").map(s => s.toLowerCase().trim());\n }\n\n matches(roomTileVM) {\n const name = roomTileVM.name.toLowerCase();\n return this._parts.every(p => name.includes(p));\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue, ObservableValue} from \"../../observable/value\";\n\ntype AllowsChild = (parent: Segment | undefined, child: Segment) => boolean;\n\n/**\n * OptionalValue is basically stating that if SegmentType[type] = true:\n * - Allow this type to be optional\n * - Give it a default value of undefined\n * - Also allow it to be true\n * This lets us do:\n * const s: Segment = new Segment(\"create-room\");\n * instead of\n * const s: Segment = new Segment(\"create-room\", undefined);\n */\nexport type OptionalValue = T extends true? [(undefined | true)?]: [T];\n\nexport class Navigation {\n private readonly _allowsChild: AllowsChild;\n private _path: Path;\n private readonly _observables: Map> = new Map();\n private readonly _pathObservable: ObservableValue>;\n\n constructor(allowsChild: AllowsChild) {\n this._allowsChild = allowsChild;\n this._path = new Path([], allowsChild);\n this._pathObservable = new ObservableValue(this._path);\n }\n\n get pathObservable(): ObservableValue> {\n return this._pathObservable;\n }\n\n get path(): Path {\n return this._path;\n }\n\n push(type: K, ...value: OptionalValue): void {\n const newPath = this.path.with(new Segment(type, ...value));\n if (newPath) {\n this.applyPath(newPath);\n }\n }\n\n applyPath(path: Path): void {\n // Path is not exported, so you can only create a Path through Navigation,\n // so we assume it respects the allowsChild rules\n const oldPath = this._path;\n this._path = path;\n // clear values not in the new path in reverse order of path\n for (let i = oldPath.segments.length - 1; i >= 0; i -= 1) {\n const segment = oldPath.segments[i];\n if (!this._path.get(segment.type)) {\n const observable = this._observables.get(segment.type);\n observable?.emitIfChanged();\n }\n }\n // change values in order of path\n for (const segment of this._path.segments) {\n const observable = this._observables.get(segment.type);\n observable?.emitIfChanged();\n }\n // to observe the whole path having changed\n // Since paths are immutable,\n // we can just use set here which will compare the references\n this._pathObservable.set(this._path);\n }\n\n observe(type: keyof T): SegmentObservable {\n let observable = this._observables.get(type);\n if (!observable) {\n observable = new SegmentObservable(this, type);\n this._observables.set(type, observable);\n }\n return observable;\n }\n\n pathFrom(segments: Segment[]): Path {\n let parent: Segment | undefined;\n let i: number;\n for (i = 0; i < segments.length; i += 1) {\n if (!this._allowsChild(parent, segments[i])) {\n return new Path(segments.slice(0, i), this._allowsChild);\n }\n parent = segments[i];\n }\n return new Path(segments, this._allowsChild);\n }\n\n segment(type: K, ...value: OptionalValue): Segment {\n return new Segment(type, ...value);\n }\n}\n\nfunction segmentValueEqual(a?: T[keyof T], b?: T[keyof T]): boolean {\n if (a === b) {\n return true;\n }\n // allow (sparse) arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i += 1) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n }\n return false;\n}\n\n\nexport class Segment {\n public value: T[K];\n\n constructor(public type: K, ...value: OptionalValue) {\n this.value = (value[0] === undefined ? true : value[0]) as unknown as T[K];\n }\n}\n\nclass Path {\n private readonly _segments: Segment[];\n private readonly _allowsChild: AllowsChild;\n\n constructor(segments: Segment[] = [], allowsChild: AllowsChild) {\n this._segments = segments;\n this._allowsChild = allowsChild;\n }\n\n clone(): Path {\n return new Path(this._segments.slice(), this._allowsChild);\n }\n\n with(segment: Segment): Path | undefined {\n let index = this._segments.length - 1;\n do {\n if (this._allowsChild(this._segments[index], segment)) {\n // pop the elements that didn't allow the new segment as a child\n const newSegments = this._segments.slice(0, index + 1);\n newSegments.push(segment);\n return new Path(newSegments, this._allowsChild);\n }\n index -= 1;\n } while(index >= -1);\n // allow -1 as well so we check if the segment is allowed as root\n return undefined;\n }\n\n until(type: keyof T): Path {\n const index = this._segments.findIndex(s => s.type === type);\n if (index !== -1) {\n return new Path(this._segments.slice(0, index + 1), this._allowsChild)\n }\n return new Path([], this._allowsChild);\n }\n\n get(type: keyof T): Segment | undefined {\n return this._segments.find(s => s.type === type);\n }\n\n replace(segment: Segment): Path | undefined {\n const index = this._segments.findIndex(s => s.type === segment.type);\n if (index !== -1) {\n const parent = this._segments[index - 1];\n if (this._allowsChild(parent, segment)) {\n const child = this._segments[index + 1];\n if (!child || this._allowsChild(segment, child)) {\n const newSegments = this._segments.slice();\n newSegments[index] = segment;\n return new Path(newSegments, this._allowsChild);\n }\n }\n }\n return undefined;\n }\n\n get segments(): Segment[] {\n return this._segments;\n }\n}\n\n/**\n * custom observable so it always returns what is in navigation.path, even if we haven't emitted the change yet.\n * This ensures that observers of a segment can also read the most recent value of other segments.\n */\nclass SegmentObservable extends BaseObservableValue {\n private readonly _navigation: Navigation;\n private _type: keyof T;\n private _lastSetValue?: T[keyof T];\n \n constructor(navigation: Navigation, type: keyof T) {\n super();\n this._navigation = navigation;\n this._type = type;\n this._lastSetValue = navigation.path.get(type)?.value;\n }\n\n get(): T[keyof T] | undefined {\n const path = this._navigation.path;\n const segment = path.get(this._type);\n const value = segment?.value;\n return value;\n }\n\n emitIfChanged(): void {\n const newValue = this.get();\n if (!segmentValueEqual(newValue, this._lastSetValue)) {\n this._lastSetValue = newValue;\n this.emit(newValue);\n }\n }\n}\n\nexport type {Path};\n\nexport function tests() {\n\n function createMockNavigation() {\n return new Navigation((parent, {type}) => {\n switch (parent?.type) {\n case undefined:\n return type === \"1\" || type === \"2\";\n case \"1\":\n return type === \"1.1\";\n case \"1.1\":\n return type === \"1.1.1\";\n case \"2\":\n return type === \"2.1\" || type === \"2.2\";\n default:\n return false;\n }\n });\n }\n\n function observeTypes(nav, types) {\n const changes: {type:string, value:any}[] = [];\n for (const type of types) {\n nav.observe(type).subscribe(value => {\n changes.push({type, value});\n });\n }\n return changes;\n }\n\n type SegmentType = {\n \"foo\": number;\n \"bar\": number;\n \"baz\": number;\n }\n\n return {\n \"applying a path emits an event on the observable\": assert => {\n const nav = createMockNavigation();\n const path = nav.pathFrom([\n new Segment(\"2\", 7),\n new Segment(\"2.2\", 8),\n ]);\n assert.equal(path.segments.length, 2);\n let changes = observeTypes(nav, [\"2\", \"2.2\"]);\n nav.applyPath(path);\n assert.equal(changes.length, 2);\n assert.equal(changes[0].type, \"2\");\n assert.equal(changes[0].value, 7);\n assert.equal(changes[1].type, \"2.2\");\n assert.equal(changes[1].value, 8);\n },\n \"path.get\": assert => {\n const path = new Path([new Segment(\"foo\", 5), new Segment(\"bar\", 6)], () => true);\n assert.equal(path.get(\"foo\")!.value, 5);\n assert.equal(path.get(\"bar\")!.value, 6);\n },\n \"path.replace success\": assert => {\n const path = new Path([new Segment(\"foo\", 5), new Segment(\"bar\", 6)], () => true);\n const newPath = path.replace(new Segment(\"foo\", 1));\n assert.equal(newPath!.get(\"foo\")!.value, 1);\n assert.equal(newPath!.get(\"bar\")!.value, 6);\n },\n \"path.replace not found\": assert => {\n const path = new Path([new Segment(\"foo\", 5), new Segment(\"bar\", 6)], () => true);\n const newPath = path.replace(new Segment(\"baz\", 1));\n assert.equal(newPath, null);\n }\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {History} from \"../../platform/web/dom/History.js\";\nimport type {Navigation, Segment, Path, OptionalValue} from \"./Navigation\";\nimport type {SubscriptionHandle} from \"../../observable/BaseObservable\";\n\ntype ParseURLPath = (urlPath: string, currentNavPath: Path, defaultSessionId?: string) => Segment[];\ntype StringifyPath = (path: Path) => string;\n\nexport interface IURLRouter {\n attach(): void;\n dispose(): void;\n pushUrl(url: string): void;\n tryRestoreLastUrl(): boolean;\n urlForSegments(segments: Segment[]): string | undefined;\n urlForSegment(type: K, ...value: OptionalValue): string | undefined;\n urlUntilSegment(type: keyof T): string;\n urlForPath(path: Path): string;\n openRoomActionUrl(roomId: string): string;\n createSSOCallbackURL(): string;\n normalizeUrl(): void;\n}\n\nexport class URLRouter implements IURLRouter {\n private readonly _history: History;\n private readonly _navigation: Navigation;\n private readonly _parseUrlPath: ParseURLPath;\n private readonly _stringifyPath: StringifyPath;\n private _subscription?: SubscriptionHandle;\n private _pathSubscription?: SubscriptionHandle;\n private _isApplyingUrl: boolean = false;\n private _defaultSessionId?: string;\n\n constructor(history: History, navigation: Navigation, parseUrlPath: ParseURLPath, stringifyPath: StringifyPath) {\n this._history = history;\n this._navigation = navigation;\n this._parseUrlPath = parseUrlPath;\n this._stringifyPath = stringifyPath;\n this._defaultSessionId = this._getLastSessionId();\n }\n\n private _getLastSessionId(): string | undefined {\n const navPath = this._urlAsNavPath(this._history.getLastSessionUrl() || \"\");\n const sessionId = navPath.get(\"session\")?.value;\n if (typeof sessionId === \"string\") {\n return sessionId;\n }\n return undefined;\n }\n\n attach(): void {\n this._subscription = this._history.subscribe(url => this._applyUrl(url));\n // subscribe to path before applying initial url\n // so redirects in _applyNavPathToHistory are reflected in url bar\n this._pathSubscription = this._navigation.pathObservable.subscribe(path => this._applyNavPathToHistory(path));\n this._applyUrl(this._history.get());\n }\n\n dispose(): void {\n if (this._subscription) { this._subscription = this._subscription(); }\n if (this._pathSubscription) { this._pathSubscription = this._pathSubscription(); }\n }\n\n private _applyNavPathToHistory(path: Path): void {\n const url = this.urlForPath(path);\n if (url !== this._history.get()) {\n if (this._isApplyingUrl) {\n // redirect\n this._history.replaceUrlSilently(url);\n } else {\n this._history.pushUrlSilently(url);\n }\n }\n }\n\n private _applyNavPathToNavigation(navPath: Path): void {\n // this will cause _applyNavPathToHistory to be called,\n // so set a flag whether this request came from ourselves\n // (in which case it is a redirect if the url does not match the current one)\n this._isApplyingUrl = true;\n this._navigation.applyPath(navPath);\n this._isApplyingUrl = false;\n }\n\n private _urlAsNavPath(url: string): Path {\n const urlPath = this._history.urlAsPath(url);\n return this._navigation.pathFrom(this._parseUrlPath(urlPath, this._navigation.path, this._defaultSessionId));\n }\n\n private _applyUrl(url: string): void {\n const navPath = this._urlAsNavPath(url);\n this._applyNavPathToNavigation(navPath);\n }\n\n pushUrl(url: string): void {\n this._history.pushUrl(url);\n }\n\n tryRestoreLastUrl(): boolean {\n const lastNavPath = this._urlAsNavPath(this._history.getLastSessionUrl() || \"\");\n if (lastNavPath.segments.length !== 0) {\n this._applyNavPathToNavigation(lastNavPath);\n return true;\n }\n return false;\n }\n\n urlForSegments(segments: Segment[]): string | undefined {\n let path: Path | undefined = this._navigation.path;\n for (const segment of segments) {\n path = path.with(segment);\n if (!path) {\n return;\n }\n }\n return this.urlForPath(path);\n }\n\n urlForSegment(type: K, ...value: OptionalValue): string | undefined {\n return this.urlForSegments([this._navigation.segment(type, ...value)]);\n }\n\n urlUntilSegment(type: keyof T): string {\n return this.urlForPath(this._navigation.path.until(type));\n }\n\n urlForPath(path: Path): string {\n return this._history.pathAsUrl(this._stringifyPath(path));\n }\n\n openRoomActionUrl(roomId: string): string {\n // not a segment to navigation knowns about, so append it manually\n const urlPath = `${this._stringifyPath(this._navigation.path.until(\"session\"))}/open-room/${encodeURIComponent(roomId)}`;\n return this._history.pathAsUrl(urlPath);\n }\n\n createSSOCallbackURL(): string {\n return window.location.href;\n }\n\n normalizeUrl(): void {\n const url = new URL(window.location.href);\n\n // Remove the loginToken query parameter from the URL after SSO.\n url.searchParams.delete(\"loginToken\");\n\n this._history.replaceUrlSilently(url.toString());\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Navigation, Segment} from \"./Navigation\";\nimport {URLRouter} from \"./URLRouter\";\nimport type {Path, OptionalValue} from \"./Navigation\";\n\nexport type SegmentType = {\n \"login\": true;\n \"session\": string | boolean;\n \"sso\": string;\n \"logout\": true;\n \"forced\": true;\n \"room\": string;\n \"rooms\": string[];\n \"settings\": true;\n \"create-room\": true;\n \"empty-grid-tile\": number;\n \"lightbox\": string;\n \"right-panel\": true;\n \"details\": true;\n \"members\": true;\n \"member\": string;\n \"invite\": true;\n \"device-verification\": string | boolean;\n \"verification\": string | boolean;\n \"join-room\": true;\n};\n\nexport function createNavigation(): Navigation {\n return new Navigation(allowsChild);\n}\n\nexport function createRouter({history, navigation}: {history: History, navigation: Navigation}): URLRouter {\n return new URLRouter(history, navigation, parseUrlPath, stringifyPath);\n}\n\nfunction allowsChild(parent: Segment | undefined, child: Segment): boolean {\n const {type} = child;\n switch (parent?.type) {\n case undefined:\n // allowed root segments\n return type === \"login\" || type === \"session\" || type === \"sso\" || type === \"logout\";\n case \"session\":\n return type === \"room\" || type === \"rooms\" || type === \"settings\" || type === \"create-room\" || type === \"join-room\" || type === \"device-verification\";\n case \"rooms\":\n // downside of the approach: both of these will control which tile is selected\n return type === \"room\" || type === \"empty-grid-tile\";\n case \"room\":\n return type === \"lightbox\" || type === \"right-panel\";\n case \"right-panel\":\n return type === \"details\"|| type === \"members\" || type === \"member\" || type === \"verification\" || type === \"invite\";\n case \"logout\":\n return type === \"forced\";\n default:\n return false;\n }\n}\n\nexport function removeRoomFromPath(path: Path, roomId: string): Path | undefined {\n let newPath: Path | undefined = path;\n const rooms = newPath.get(\"rooms\");\n let roomIdGridIndex = -1;\n // first delete from rooms segment\n if (rooms) {\n roomIdGridIndex = rooms.value.indexOf(roomId);\n if (roomIdGridIndex !== -1) {\n const idsWithoutRoom = rooms.value.slice();\n idsWithoutRoom[roomIdGridIndex] = \"\";\n newPath = newPath.replace(new Segment(\"rooms\", idsWithoutRoom));\n }\n }\n const room = newPath!.get(\"room\");\n // then from room (which occurs with or without rooms)\n if (room && room.value === roomId) {\n if (roomIdGridIndex !== -1) {\n newPath = newPath!.with(new Segment(\"empty-grid-tile\", roomIdGridIndex));\n } else {\n newPath = newPath!.until(\"session\");\n }\n }\n return newPath;\n}\n\nfunction roomsSegmentWithRoom(rooms: Segment, roomId: string, path: Path): Segment {\n if(!rooms.value.includes(roomId)) {\n const emptyGridTile = path.get(\"empty-grid-tile\");\n const oldRoom = path.get(\"room\");\n let index = 0;\n if (emptyGridTile) {\n index = emptyGridTile.value;\n } else if (oldRoom) {\n index = rooms.value.indexOf(oldRoom.value);\n }\n const roomIds = rooms.value.slice();\n roomIds[index] = roomId;\n return new Segment(\"rooms\", roomIds);\n } else {\n return rooms;\n }\n}\n\nfunction pushRightPanelSegment(array: Segment[], segment: T, ...value: OptionalValue): void {\n array.push(new Segment(\"right-panel\"));\n array.push(new Segment(segment, ...value));\n}\n\nexport function addPanelIfNeeded(navigation: Navigation, path: Path): Path {\n const segments = navigation.path.segments;\n const i = segments.findIndex(segment => segment.type === \"right-panel\");\n let _path = path;\n if (i !== -1) {\n _path = path.until(\"room\");\n _path = _path.with(segments[i])!;\n _path = _path.with(segments[i + 1])!;\n }\n return _path;\n}\n\nexport function parseUrlPath(urlPath: string, currentNavPath: Path, defaultSessionId?: string): Segment[] {\n // substring(1) to take of initial /\n const parts = urlPath.substring(1).split(\"/\");\n const iterator = parts[Symbol.iterator]();\n const segments: Segment[] = [];\n let next; \n while (!(next = iterator.next()).done) {\n const type = next.value;\n if (type === \"rooms\") {\n const roomsValue = iterator.next().value;\n if (roomsValue === undefined) { break; }\n const roomIds = roomsValue.split(\",\").map(id => decodeURIComponent(id));\n segments.push(new Segment(type, roomIds));\n const selectedIndex = parseInt(iterator.next().value || \"0\", 10);\n const roomId = roomIds[selectedIndex];\n if (roomId) {\n segments.push(new Segment(\"room\", roomId));\n } else {\n segments.push(new Segment(\"empty-grid-tile\", selectedIndex));\n }\n } else if (type === \"open-room\") {\n let roomId = iterator.next().value;\n if (!roomId) { break; }\n roomId = decodeURIComponent(roomId);\n const rooms = currentNavPath.get(\"rooms\");\n if (rooms) {\n segments.push(roomsSegmentWithRoom(rooms, roomId, currentNavPath));\n }\n segments.push(new Segment(\"room\", roomId));\n const openRoomPartIndex = parts.findIndex(part => part === \"open-room\");\n const hasOnlyRoomIdAfterPart = openRoomPartIndex >= parts.length - 2;\n if (hasOnlyRoomIdAfterPart) {\n // Copy right-panel segments from previous path only if there are no other parts after open-room\n // fixes memberlist -> member details closing/opening grid view\n const previousSegments = currentNavPath.segments;\n const i = previousSegments.findIndex(s => s.type === \"right-panel\");\n if (i !== -1) {\n segments.push(...previousSegments.slice(i));\n }\n }\n } else if (type === \"last-session\") {\n let sessionSegment = currentNavPath.get(\"session\");\n if (typeof sessionSegment?.value !== \"string\" && defaultSessionId) {\n sessionSegment = new Segment(\"session\", defaultSessionId);\n }\n if (sessionSegment) {\n segments.push(sessionSegment);\n }\n } else if (type === \"details\" || type === \"members\" || type === \"verification\" || type === \"invite\") {\n pushRightPanelSegment(segments, type);\n } else if (type === \"member\") {\n let userId = iterator.next().value;\n if (!userId) { break; }\n userId = decodeURIComponent(userId);\n pushRightPanelSegment(segments, type, userId);\n } else if (type.includes(\"loginToken\")) {\n // Special case for SSO-login with query parameter loginToken=\n const loginToken = type.split(\"=\").pop();\n segments.push(new Segment(\"sso\", loginToken));\n } else {\n // might be undefined, which will be turned into true by Segment \n let value = iterator.next().value;\n if (value) {\n // decode only if value isn't undefined!\n value = decodeURIComponent(value)\n }\n segments.push(new Segment(type, value));\n }\n }\n return segments;\n}\n\nexport function stringifyPath(path: Path): string {\n let urlPath = \"\";\n let prevSegment: Segment | undefined;\n for (const segment of path.segments) {\n const encodedSegmentValue = encodeSegmentValue(segment.value);\n switch (segment.type) {\n case \"rooms\":\n urlPath += `/rooms/${encodedSegmentValue}`;\n break;\n case \"empty-grid-tile\":\n urlPath += `/${encodedSegmentValue}`;\n break;\n case \"room\":\n if (prevSegment?.type === \"rooms\") {\n const index = prevSegment.value.indexOf(segment.value);\n urlPath += `/${index}`;\n } else {\n urlPath += `/${segment.type}/${encodedSegmentValue}`;\n }\n break;\n case \"right-panel\":\n case \"sso\":\n // Do not put these segments in URL\n continue;\n default:\n urlPath += `/${segment.type}`;\n if (encodedSegmentValue) {\n urlPath += `/${encodedSegmentValue}`;\n }\n }\n prevSegment = segment;\n }\n return urlPath;\n}\n\nfunction encodeSegmentValue(value: SegmentType[keyof SegmentType]): string {\n if (value === true) {\n // Nothing to encode for boolean\n return \"\";\n }\n else if (Array.isArray(value)) {\n return value.map(v => encodeURIComponent(v)).join(\",\");\n }\n else {\n return encodeURIComponent(value);\n }\n}\n\nexport function tests() {\n function createEmptyPath() {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([]);\n return path;\n }\n\n return {\n \"stringify grid url with focused empty tile\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"empty-grid-tile\", 3)\n ]);\n const urlPath = stringifyPath(path);\n assert.equal(urlPath, \"/session/1/rooms/a,b,c/3\");\n },\n \"stringify grid url with focused room\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\")\n ]);\n const urlPath = stringifyPath(path);\n assert.equal(urlPath, \"/session/1/rooms/a,b,c/1\");\n },\n \"stringify url with right-panel and details segment\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\"),\n new Segment(\"right-panel\"),\n new Segment(\"details\")\n ]);\n const urlPath = stringifyPath(path);\n assert.equal(urlPath, \"/session/1/rooms/a,b,c/1/details\");\n },\n \"Parse loginToken query parameter into SSO segment\": assert => {\n const path = createEmptyPath();\n const segments = parseUrlPath(\"?loginToken=a1232aSD123\", path);\n assert.equal(segments.length, 1);\n assert.equal(segments[0].type, \"sso\");\n assert.equal(segments[0].value, \"a1232aSD123\");\n },\n \"parse grid url path with focused empty tile\": assert => {\n const path = createEmptyPath();\n const segments = parseUrlPath(\"/session/1/rooms/a,b,c/3\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"b\", \"c\"]);\n assert.equal(segments[2].type, \"empty-grid-tile\");\n assert.equal(segments[2].value, 3);\n },\n \"parse grid url path with focused room\": assert => {\n const path = createEmptyPath();\n const segments = parseUrlPath(\"/session/1/rooms/a,b,c/1\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"b\", \"c\"]);\n assert.equal(segments[2].type, \"room\");\n assert.equal(segments[2].value, \"b\");\n },\n \"parse empty grid url\": assert => {\n const path = createEmptyPath();\n const segments = parseUrlPath(\"/session/1/rooms/\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"\"]);\n assert.equal(segments[2].type, \"empty-grid-tile\");\n assert.equal(segments[2].value, 0);\n },\n \"parse empty grid url with focus\": assert => {\n const path = createEmptyPath();\n const segments = parseUrlPath(\"/session/1/rooms//1\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"\"]);\n assert.equal(segments[2].type, \"empty-grid-tile\");\n assert.equal(segments[2].value, 1);\n },\n \"parse open-room action replacing the current focused room\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\")\n ]);\n const segments = parseUrlPath(\"/session/1/open-room/d\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"d\", \"c\"]);\n assert.equal(segments[2].type, \"room\");\n assert.equal(segments[2].value, \"d\");\n },\n \"parse open-room action changing focus to an existing room\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\")\n ]);\n const segments = parseUrlPath(\"/session/1/open-room/a\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"b\", \"c\"]);\n assert.equal(segments[2].type, \"room\");\n assert.equal(segments[2].value, \"a\");\n },\n \"parse open-room action changing focus to an existing room with details open\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\"),\n new Segment(\"right-panel\", true),\n new Segment(\"details\", true)\n ]);\n const segments = parseUrlPath(\"/session/1/open-room/a\", path);\n assert.equal(segments.length, 5);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"b\", \"c\"]);\n assert.equal(segments[2].type, \"room\");\n assert.equal(segments[2].value, \"a\");\n assert.equal(segments[3].type, \"right-panel\");\n assert.equal(segments[3].value, true);\n assert.equal(segments[4].type, \"details\");\n assert.equal(segments[4].value, true);\n },\n \"open-room action should only copy over previous segments if there are no parts after open-room\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\"),\n new Segment(\"right-panel\", true),\n new Segment(\"members\", true)\n ]);\n const segments = parseUrlPath(\"/session/1/open-room/a/member/foo\", path);\n assert.equal(segments.length, 5);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"b\", \"c\"]);\n assert.equal(segments[2].type, \"room\");\n assert.equal(segments[2].value, \"a\");\n assert.equal(segments[3].type, \"right-panel\");\n assert.equal(segments[3].value, true);\n assert.equal(segments[4].type, \"member\");\n assert.equal(segments[4].value, \"foo\");\n },\n \"parse open-room action setting a room in an empty tile\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"empty-grid-tile\", 4)\n ]);\n const segments = parseUrlPath(\"/session/1/open-room/d\", path);\n assert.equal(segments.length, 3);\n assert.equal(segments[0].type, \"session\");\n assert.equal(segments[0].value, \"1\");\n assert.equal(segments[1].type, \"rooms\");\n assert.deepEqual(segments[1].value, [\"a\", \"b\", \"c\", , \"d\"]); //eslint-disable-line no-sparse-arrays\n assert.equal(segments[2].type, \"room\");\n assert.equal(segments[2].value, \"d\");\n },\n \"parse session url path without id\": assert => {\n const path = createEmptyPath();\n const segments = parseUrlPath(\"/session\", path);\n assert.equal(segments.length, 1);\n assert.equal(segments[0].type, \"session\");\n assert.strictEqual(segments[0].value, true);\n },\n \"remove active room from grid path turns it into empty tile\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\")\n ]);\n const newPath = removeRoomFromPath(path, \"b\");\n assert.equal(newPath?.segments.length, 3);\n assert.equal(newPath?.segments[0].type, \"session\");\n assert.equal(newPath?.segments[0].value, 1);\n assert.equal(newPath?.segments[1].type, \"rooms\");\n assert.deepEqual(newPath?.segments[1].value, [\"a\", \"\", \"c\"]);\n assert.equal(newPath?.segments[2].type, \"empty-grid-tile\");\n assert.equal(newPath?.segments[2].value, 1);\n },\n \"remove inactive room from grid path\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"c\"]),\n new Segment(\"room\", \"b\")\n ]);\n const newPath = removeRoomFromPath(path, \"a\");\n assert.equal(newPath?.segments.length, 3);\n assert.equal(newPath?.segments[0].type, \"session\");\n assert.equal(newPath?.segments[0].value, 1);\n assert.equal(newPath?.segments[1].type, \"rooms\");\n assert.deepEqual(newPath?.segments[1].value, [\"\", \"b\", \"c\"]);\n assert.equal(newPath?.segments[2].type, \"room\");\n assert.equal(newPath?.segments[2].value, \"b\");\n },\n \"remove inactive room from grid path with empty tile\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"rooms\", [\"a\", \"b\", \"\"]),\n new Segment(\"empty-grid-tile\", 3)\n ]);\n const newPath = removeRoomFromPath(path, \"b\");\n assert.equal(newPath?.segments.length, 3);\n assert.equal(newPath?.segments[0].type, \"session\");\n assert.equal(newPath?.segments[0].value, 1);\n assert.equal(newPath?.segments[1].type, \"rooms\");\n assert.deepEqual(newPath?.segments[1].value, [\"a\", \"\", \"\"]);\n assert.equal(newPath?.segments[2].type, \"empty-grid-tile\");\n assert.equal(newPath?.segments[2].value, 3);\n },\n \"remove active room\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"room\", \"b\")\n ]);\n const newPath = removeRoomFromPath(path, \"b\");\n assert.equal(newPath?.segments.length, 1);\n assert.equal(newPath?.segments[0].type, \"session\");\n assert.equal(newPath?.segments[0].value, 1);\n },\n \"remove inactive room doesn't do anything\": assert => {\n const nav: Navigation = new Navigation(allowsChild);\n const path = nav.pathFrom([\n new Segment(\"session\", 1),\n new Segment(\"room\", \"b\")\n ]);\n const newPath = removeRoomFromPath(path, \"a\");\n assert.equal(newPath?.segments.length, 2);\n assert.equal(newPath?.segments[0].type, \"session\");\n assert.equal(newPath?.segments[0].value, 1);\n assert.equal(newPath?.segments[1].type, \"room\");\n assert.equal(newPath?.segments[1].value, \"b\");\n },\n \n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {RoomTileViewModel} from \"./RoomTileViewModel.js\";\nimport {InviteTileViewModel} from \"./InviteTileViewModel.js\";\nimport {RoomBeingCreatedTileViewModel} from \"./RoomBeingCreatedTileViewModel.js\";\nimport {RoomFilter} from \"./RoomFilter.js\";\nimport {ApplyMap} from \"../../../observable\";\nimport {addPanelIfNeeded} from \"../../navigation\";\n\nexport class LeftPanelViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {session} = options;\n this._tileViewModelsMap = this._mapTileViewModels(session.roomsBeingCreated, session.invites, session.rooms);\n this._tileViewModelsFilterMap = new ApplyMap(this._tileViewModelsMap);\n this._tileViewModels = this._tileViewModelsFilterMap.sortValues((a, b) => a.compare(b));\n this._currentTileVM = null;\n this._setupNavigation();\n this._closeUrl = this.urlRouter.urlForSegment(\"session\");\n this._settingsUrl = this.urlRouter.urlForSegment(\"settings\");\n }\n\n _mapTileViewModels(roomsBeingCreated, invites, rooms) {\n // join is not commutative, invites will take precedence over rooms\n const allTiles = invites.join(roomsBeingCreated, rooms).mapValues((item, emitChange) => {\n let vm;\n if (item.isBeingCreated) {\n vm = new RoomBeingCreatedTileViewModel(this.childOptions({roomBeingCreated: item, emitChange}));\n } else if (item.isInvite) {\n vm = new InviteTileViewModel(this.childOptions({invite: item, emitChange}));\n } else {\n vm = new RoomTileViewModel(this.childOptions({room: item, emitChange}));\n }\n const isOpen = this.navigation.path.get(\"room\")?.value === item.id;\n if (isOpen) {\n vm.open();\n this._updateCurrentVM(vm);\n }\n return vm;\n });\n return allTiles;\n }\n\n _updateCurrentVM(vm) {\n // need to also update the current vm here as\n // we can't call `_open` from the ctor as the map\n // is only populated when the view subscribes.\n this._currentTileVM?.close();\n this._currentTileVM = vm;\n }\n\n get closeUrl() {\n return this._closeUrl;\n }\n\n get settingsUrl() {\n return this._settingsUrl;\n }\n\n showCreateRoomView() {\n this.navigation.push(\"create-room\");\n }\n\n showJoinRoomView() {\n this.navigation.push(\"join-room\");\n }\n \n _setupNavigation() {\n const roomObservable = this.navigation.observe(\"room\");\n this.track(roomObservable.subscribe(roomId => this._open(roomId)));\n\n const gridObservable = this.navigation.observe(\"rooms\");\n this.gridEnabled = !!gridObservable.get();\n this.track(gridObservable.subscribe(roomIds => {\n const changed = this.gridEnabled ^ !!roomIds;\n this.gridEnabled = !!roomIds;\n if (changed) {\n this.emitChange(\"gridEnabled\");\n }\n }));\n }\n\n _open(roomId) {\n this._currentTileVM?.close();\n this._currentTileVM = null;\n if (roomId) {\n this._currentTileVM = this._tileViewModelsMap.get(roomId);\n this._currentTileVM?.open();\n }\n }\n\n toggleGrid() {\n const room = this.navigation.path.get(\"room\");\n let path = this.navigation.path.until(\"session\");\n if (this.gridEnabled) {\n if (room) {\n path = path.with(room);\n path = addPanelIfNeeded(this.navigation, path);\n }\n } else {\n if (room) {\n path = path.with(this.navigation.segment(\"rooms\", [room.value]));\n path = path.with(room);\n path = addPanelIfNeeded(this.navigation, path);\n } else {\n path = path.with(this.navigation.segment(\"rooms\", []));\n path = path.with(this.navigation.segment(\"empty-grid-tile\", 0));\n }\n }\n this.navigation.applyPath(path);\n }\n\n get tileViewModels() {\n return this._tileViewModels;\n }\n\n clearFilter() {\n this._tileViewModelsFilterMap.setApply(null);\n this._tileViewModelsFilterMap.applyOnce((roomId, vm) => vm.hidden = false);\n }\n\n setFilter(query) {\n query = query.trim();\n if (query.length === 0) {\n this.clearFilter();\n return false;\n } else {\n const startFiltering = !this._tileViewModelsFilterMap.hasApply();\n const filter = new RoomFilter(query);\n this._tileViewModelsFilterMap.setApply((roomId, vm) => {\n vm.hidden = !filter.matches(vm);\n });\n return startFiltering;\n }\n }\n}\n","import {UpdateAction} from \"../UpdateAction.js\";\nimport {BaseEntry} from \"../../../../../matrix/room/timeline/entries/BaseEntry\";\nimport {IDisposable} from \"../../../../../utils/Disposables\";\n\nexport type EmitUpdateFn = (tile: ITile, props: any) => void\n\nexport enum TileShape {\n Message = \"message\",\n MessageStatus = \"message-status\",\n Announcement = \"announcement\",\n File = \"file\",\n Gap = \"gap\",\n Image = \"image\",\n Location = \"location\",\n MissingAttachment = \"missing-attachment\",\n Redacted = \"redacted\",\n Video = \"video\",\n DateHeader = \"date-header\",\n Call = \"call\",\n Verification = \"verification\",\n}\n\n// TODO: should we imply inheriting from view model here?\nexport interface ITile extends IDisposable {\n setUpdateEmit(emitUpdate: EmitUpdateFn): void;\n get upperEntry(): E;\n get lowerEntry(): E;\n /** compare two tiles, returning:\n * - 0 if both tiles are considered equal\n * - a negative value if this tiles is sorted before the given tile\n * - a positive value if this tiles is sorted after the given tile\n **/\n compare(tile: ITile): number;\n /** Some tiles might need comparison mechanisms that are not commutative,\n * (e.g. `tileA.compare(tileB)` not being the same as `tileB.compare(tileA)`),\n * a property needed for reliably sorting the tiles in TilesCollection.\n * To counteract this, tiles can indicate this is not the case for them and\n * when any other tile is being compared to a tile where this flag is true,\n * it should delegate the comparison to the given tile.\n * E.g. one example where this flag is used is DateTile. */\n get comparisonIsNotCommutative(): boolean;\n compareEntry(entry: BaseEntry): number;\n // update received for already included (falls within sort keys) entry\n updateEntry(entry: BaseEntry, param: any): UpdateAction;\n // return whether the tile should be removed\n // as SimpleTile only has one entry, the tile should be removed\n removeEntry(entry: BaseEntry): boolean\n // SimpleTile can only contain 1 entry\n tryIncludeEntry(entry: BaseEntry): boolean;\n // let item know it has a new sibling\n updatePreviousSibling(prev: ITile | undefined): void;\n // let item know it has a new sibling\n updateNextSibling(next: ITile | undefined): void;\n notifyVisible(): void;\n get needsDateSeparator(): boolean;\n createDateSeparator(): ITile | undefined;\n get shape(): TileShape;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class UpdateAction {\n constructor(remove, update, replace, updateParams) {\n this._remove = remove;\n this._update = update;\n this._replace = replace;\n this._updateParams = updateParams;\n }\n\n get shouldReplace() {\n return this._replace;\n }\n\n get shouldRemove() {\n return this._remove;\n }\n\n get shouldUpdate() {\n return this._update;\n }\n\n get updateParams() {\n return this._updateParams;\n }\n\n static Remove() {\n return new UpdateAction(true, false, false, null);\n }\n\n static Update(newParams) {\n return new UpdateAction(false, true, false, newParams);\n }\n\n static Nothing() {\n return new UpdateAction(false, false, false, null);\n }\n\n static Replace(params) {\n return new UpdateAction(false, false, true, params);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"../../../../observable/list/BaseObservableList\";\nimport {sortedIndex} from \"../../../../utils/sortedIndex\";\nimport {TileShape} from \"./tiles/ITile\";\n\n// maps 1..n entries to 0..1 tile. Entries are what is stored in the timeline, either an event or fragmentboundary\n// for now, tileClassForEntry should be stable in whether it returns a tile or not.\n// e.g. the decision to create a tile or not should be based on properties\n// not updated later on (e.g. event type)\n// also see big comment in onUpdate\nexport class TilesCollection extends BaseObservableList {\n constructor(entries, tileOptions) {\n super();\n this._entries = entries;\n this._tiles = null;\n this._entrySubscription = null;\n this._tileOptions = tileOptions;\n this._emitSpontanousUpdate = this._emitSpontanousUpdate.bind(this);\n }\n\n _createTile(entry) {\n const Tile = this._tileOptions.tileClassForEntry(entry, this._tileOptions);\n if (Tile) {\n return new Tile(entry, this._tileOptions);\n }\n }\n\n _emitSpontanousUpdate(tile, params) {\n const entry = tile.lowerEntry;\n const tileIdx = this._findTileIdx(entry);\n this.emitUpdate(tileIdx, tile, params);\n }\n\n onSubscribeFirst() {\n this._entrySubscription = this._entries.subscribe(this);\n this._populateTiles();\n }\n\n _populateTiles() {\n this._silent = true;\n this._tiles = [];\n let currentTile = null;\n for (let entry of this._entries) {\n if (!currentTile || !currentTile.tryIncludeEntry(entry)) {\n currentTile = this._createTile(entry);\n if (currentTile) {\n this._tiles.push(currentTile);\n }\n }\n }\n let prevTile = null;\n for (let tile of this._tiles) {\n if (prevTile) {\n prevTile.updateNextSibling(tile);\n }\n tile.updatePreviousSibling(prevTile);\n prevTile = tile;\n }\n if (prevTile) {\n prevTile.updateNextSibling(null);\n }\n // add date headers here\n for (let idx = 0; idx < this._tiles.length; idx += 1) {\n const tile = this._tiles[idx];\n if (tile.needsDateSeparator) {\n this._addTileAt(idx, tile.createDateSeparator(), true);\n idx += 1; // tile's index moved one up, don't process it again\n }\n }\n // now everything is wired up,\n // allow tiles to emit updates\n for (const tile of this._tiles) {\n tile.setUpdateEmit(this._emitSpontanousUpdate);\n }\n this._silent = false;\n }\n\n _findTileIdx(entry) {\n return sortedIndex(this._tiles, entry, (entry, tile) => {\n // negate result because we're switching the order of the params\n return -tile.compareEntry(entry);\n });\n }\n\n _findTileAtIdx(entry, idx) {\n const tile = this._getTileAtIdx(idx);\n if (tile && tile.compareEntry(entry) === 0) {\n return tile;\n }\n }\n\n _getTileAtIdx(tileIdx) {\n if (tileIdx >= 0 && tileIdx < this._tiles.length) {\n return this._tiles[tileIdx];\n }\n return null;\n }\n\n onUnsubscribeLast() {\n this._entrySubscription = this._entrySubscription();\n for(let i = 0; i < this._tiles.length; i+= 1) {\n this._tiles[i].dispose();\n }\n this._tiles = null;\n }\n\n onReset() {\n // if TileViewModel were disposable, dispose here, or is that for views to do? views I suppose ...\n this._buildInitialTiles();\n this.emitReset();\n }\n\n onAdd(index, entry) {\n const tileIdx = this._findTileIdx(entry);\n const prevTile = this._getTileAtIdx(tileIdx - 1);\n if (prevTile && prevTile.tryIncludeEntry(entry)) {\n this.emitUpdate(tileIdx - 1, prevTile);\n return;\n }\n // not + 1 because this entry hasn't been added yet\n const nextTile = this._getTileAtIdx(tileIdx);\n if (nextTile && nextTile.tryIncludeEntry(entry)) {\n this.emitUpdate(tileIdx, nextTile);\n return;\n }\n\n const newTile = this._createTile(entry);\n if (newTile) {\n this._addTileAt(tileIdx, newTile);\n this._evaluateDateHeaderAtIdx(tileIdx);\n }\n // find position by sort key\n // ask siblings to be included? both? yes, twice: a (insert c here) b, ask a(c), if yes ask b(a), else ask b(c)? if yes then b(a)?\n }\n\n _evaluateDateHeaderAtIdx(tileIdx) {\n // consider two tiles after the inserted tile, because\n // the first of the two tiles may be a DateTile in which case,\n // we remove it after looking at the needsDateSeparator prop of the\n // next next tile\n for (let i = 0; i < 3; i += 1) {\n const idx = tileIdx + i;\n if (idx >= this._tiles.length) {\n break;\n }\n const tile = this._tiles[idx];\n const prevTile = idx > 0 ? this._tiles[idx - 1] : undefined;\n const hasDateSeparator = prevTile?.shape === TileShape.DateHeader;\n if (tile.needsDateSeparator && !hasDateSeparator) {\n // adding a tile shift all the indices we need to consider\n // especially given we consider removals for the tile that\n // comes after a datetile\n tileIdx += 1;\n this._addTileAt(idx, tile.createDateSeparator());\n } else if (!tile.needsDateSeparator && hasDateSeparator) {\n // this is never triggered because needsDateSeparator is not cleared\n // when loading more items because we don't do anything once the\n // direct sibling is a DateTile\n this._removeTile(idx - 1, prevTile);\n }\n }\n }\n\n _addTileAt(idx, newTile, silent = false) {\n const prevTile = idx > 0 ? this._tiles[idx - 1] : undefined;\n const nextTile = this._tiles[idx];\n prevTile?.updateNextSibling(newTile);\n newTile.updatePreviousSibling(prevTile);\n newTile.updateNextSibling(nextTile);\n nextTile?.updatePreviousSibling(newTile);\n this._tiles.splice(idx, 0, newTile);\n if (!silent) {\n this.emitAdd(idx, newTile);\n }\n // add event is emitted, now the tile\n // can emit updates\n newTile.setUpdateEmit(this._emitSpontanousUpdate);\n }\n\n onUpdate(index, entry, params) {\n // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it\n if (!this._tiles) {\n return;\n }\n const tileIdx = this._findTileIdx(entry);\n const tile = this._findTileAtIdx(entry, tileIdx);\n if (tile) {\n const action = tile.updateEntry(entry, params);\n if (action.shouldReplace) {\n const newTile = this._createTile(entry);\n if (newTile) {\n this._replaceTile(tileIdx, tile, newTile, action.updateParams);\n newTile.setUpdateEmit(this._emitSpontanousUpdate);\n } else {\n this._removeTile(tileIdx, tile);\n }\n }\n if (action.shouldRemove) {\n this._removeTile(tileIdx, tile);\n }\n if (action.shouldUpdate) {\n this.emitUpdate(tileIdx, tile, action.updateParams);\n }\n }\n // technically we should handle adding a tile here as well\n // in case before we didn't have a tile for it but now we do\n // but in reality we don't have this use case as the type and msgtype\n // doesn't change. Decryption maybe is the exception?\n\n\n // outcomes here can be\n // tiles should be removed (got redacted and we don't want it in the timeline)\n // tile should be added where there was none before ... ?\n // entry should get it's own tile now\n // merge with neighbours? ... hard to imagine use case for this ...\n }\n\n _replaceTile(tileIdx, existingTile, newTile, updateParams) {\n existingTile.dispose();\n const prevTile = this._getTileAtIdx(tileIdx - 1);\n const nextTile = this._getTileAtIdx(tileIdx + 1);\n this._tiles[tileIdx] = newTile;\n prevTile?.updateNextSibling(newTile);\n newTile.updatePreviousSibling(prevTile);\n newTile.updateNextSibling(nextTile);\n nextTile?.updatePreviousSibling(newTile);\n this.emitUpdate(tileIdx, newTile, updateParams);\n }\n\n _removeTile(tileIdx, tile) {\n const prevTile = this._getTileAtIdx(tileIdx - 1);\n const nextTile = this._getTileAtIdx(tileIdx + 1);\n // applying and emitting the remove should happen\n // atomically, as updateNext/PreviousSibling might\n // emit an update with the wrong index otherwise \n this._tiles.splice(tileIdx, 1);\n tile.dispose();\n this.emitRemove(tileIdx, tile);\n prevTile?.updateNextSibling(nextTile);\n nextTile?.updatePreviousSibling(prevTile);\n\n if (prevTile && prevTile.shape === TileShape.DateHeader && (!nextTile || !nextTile.needsDateSeparator)) {\n this._removeTile(tileIdx - 1, prevTile);\n }\n }\n\n // would also be called when unloading a part of the timeline\n onRemove(index, entry) {\n const tileIdx = this._findTileIdx(entry);\n \n const tile = this._findTileAtIdx(entry, tileIdx);\n if (tile) {\n const removeTile = tile.removeEntry(entry);\n if (removeTile) {\n this._removeTile(tileIdx, tile);\n } else {\n this.emitUpdate(tileIdx, tile);\n }\n }\n }\n\n onMove(/*fromIdx, toIdx, value*/) {\n // this ... cannot happen in the timeline?\n // perhaps we can use this event to support a local echo (in a different fragment)\n // to be moved to the key of the remote echo, so we don't loose state ... ?\n }\n\n [Symbol.iterator]() {\n return this._tiles.values();\n }\n\n get length() {\n return this._tiles.length;\n }\n\n getFirst() {\n return this._tiles[0];\n }\n\n getTileIndex(searchTile) {\n const idx = sortedIndex(this._tiles, searchTile, (searchTile, tile) => {\n return searchTile.compare(tile);\n });\n const foundTile = this._tiles[idx];\n if (foundTile?.compare(searchTile) === 0) {\n return idx;\n }\n return -1;\n }\n\n sliceIterator(start, end) {\n return this._tiles.slice(start, end)[Symbol.iterator]();\n }\n}\n\nimport {ObservableArray} from \"../../../../observable/list/ObservableArray\";\nimport {UpdateAction} from \"./UpdateAction.js\";\n\nexport function tests() {\n class TestTile {\n constructor(entry) {\n this.entry = entry;\n this.update = null;\n this.needsDateSeparator = false;\n }\n setUpdateEmit(update) {\n this.update = update;\n }\n tryIncludeEntry() {\n return false;\n }\n compareEntry(b) {\n return this.entry.n - b.n;\n }\n removeEntry() {\n return true;\n }\n get upperEntry() {\n return this.entry;\n }\n\n get lowerEntry() {\n return this.entry;\n }\n updateNextSibling() {}\n updatePreviousSibling() {}\n updateEntry() {\n return UpdateAction.Nothing;\n }\n\n dispose() {}\n }\n\n class DateHeaderTile extends TestTile {\n get shape() { return TileShape.DateHeader; }\n updateNextSibling(next) {\n this.next = next;\n }\n updatePreviousSibling(prev) {\n this.next?.updatePreviousSibling(prev);\n }\n compareEntry(b) {\n // important that date tiles as sorted before their next item, but after their previous sibling\n return this.next.compareEntry(b) - 0.5;\n }\n }\n\n class MessageNeedingDateHeaderTile extends TestTile {\n get shape() { return TileShape.Message; }\n\n createDateSeparator() {\n return new DateHeaderTile(this.entry);\n }\n updatePreviousSibling(prev) {\n if (prev?.shape !== TileShape.DateHeader) {\n // 1 day is 10 \n this.needsDateSeparator = !prev || Math.floor(prev.entry.n / 10) !== Math.floor(this.entry.n / 10);\n }\n }\n }\n\n return {\n \"don't emit update before add\": assert => {\n class UpdateOnSiblingTile extends TestTile {\n updateNextSibling() {\n // this happens with isContinuation\n this.update && this.update(this, \"next\");\n }\n updatePreviousSibling() {\n // this happens with isContinuation\n this.update && this.update(this, \"previous\");\n }\n }\n const entries = new ObservableArray([{n: 5}, {n: 10}]);\n const tileOptions = {\n tileClassForEntry: () => UpdateOnSiblingTile,\n };\n const tiles = new TilesCollection(entries, tileOptions);\n let receivedAdd = false;\n tiles.subscribe({\n onAdd(idx, tile) {\n assert(tile.entry.n, 7);\n receivedAdd = true;\n },\n onUpdate(idx, tile) {\n if (tile.entry.n === 7) {\n assert(!receivedAdd, \"receiving update before add\");\n }\n }\n });\n entries.insert(1, {n: 7});\n assert(receivedAdd);\n },\n \"emit update with correct index in updatePreviousSibling during remove\": assert => {\n class UpdateOnSiblingTile extends TestTile {\n updatePreviousSibling() {\n this.update?.(this, \"previous\");\n }\n }\n const entries = new ObservableArray([{n: 5}, {n: 10}, {n: 15}]);\n const tileOptions = {\n tileClassForEntry: () => UpdateOnSiblingTile,\n };\n const tiles = new TilesCollection(entries, tileOptions);\n const events = [];\n tiles.subscribe({\n onUpdate(idx, tile) {\n assert.equal(idx, 1);\n assert.equal(tile.entry.n, 15);\n events.push(\"update\");\n },\n onRemove(idx, tile) {\n assert.equal(idx, 1);\n assert.equal(tile.entry.n, 10);\n events.push(\"remove\");\n }\n });\n entries.remove(1);\n assert.deepEqual(events, [\"remove\", \"update\"]);\n },\n \"date tile is added when needed when populating\": assert => {\n const entries = new ObservableArray([{n: 15}]);\n const tileOptions = {\n tileClassForEntry: () => MessageNeedingDateHeaderTile,\n };\n const tiles = new TilesCollection(entries, tileOptions);\n tiles.subscribe({});\n const tilesArray = Array.from(tiles);\n assert.equal(tilesArray.length, 2);\n assert.equal(tilesArray[0].shape, TileShape.DateHeader);\n assert.equal(tilesArray[1].shape, TileShape.Message);\n },\n \"date header is added when receiving addition\": assert => {\n const entries = new ObservableArray([{n: 15}]);\n const tileOptions = {\n tileClassForEntry: () => MessageNeedingDateHeaderTile,\n };\n const tiles = new TilesCollection(entries, tileOptions);\n tiles.subscribe({\n onAdd() {},\n onRemove() {}\n });\n entries.insert(0, {n: 5});\n const tilesArray = Array.from(tiles);\n assert.equal(tilesArray[0].shape, TileShape.DateHeader);\n assert.equal(tilesArray[1].shape, TileShape.Message);\n assert.equal(tilesArray[2].shape, TileShape.DateHeader);\n assert.equal(tilesArray[3].shape, TileShape.Message);\n assert.equal(tilesArray.length, 4);\n },\n \"date header is removed and added when loading more messages for the same day\": assert => {\n const entries = new ObservableArray([{n: 15}]);\n const tileOptions = {\n tileClassForEntry: () => MessageNeedingDateHeaderTile,\n };\n const tiles = new TilesCollection(entries, tileOptions);\n tiles.subscribe({\n onAdd() {},\n onRemove() {}\n });\n entries.insert(0, {n: 12});\n const tilesArray = Array.from(tiles);\n assert.equal(tilesArray[0].shape, TileShape.DateHeader);\n assert.equal(tilesArray[1].shape, TileShape.Message);\n assert.equal(tilesArray[2].shape, TileShape.Message);\n assert.equal(tilesArray.length, 3);\n },\n \"date header is removed at the end of the timeline\": assert => {\n const entries = new ObservableArray([{n: 5}, {n: 15}]);\n const tileOptions = {\n tileClassForEntry: () => MessageNeedingDateHeaderTile,\n };\n const tiles = new TilesCollection(entries, tileOptions);\n let removals = 0;\n tiles.subscribe({\n onAdd() {},\n onRemove() {\n removals += 1;\n }\n });\n entries.remove(1);\n const tilesArray = Array.from(tiles);\n assert.equal(tilesArray[0].shape, TileShape.DateHeader);\n assert.equal(tilesArray[1].shape, TileShape.Message);\n assert.equal(tilesArray.length, 2);\n assert.equal(removals, 2);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/*\nneed better naming, but\nentry = event or gap from matrix layer\ntile = item on visual timeline like event, date separator?, group of joined events\n\n\nshall we put date separators as marker in EventViewItem or separate item? binary search will be complicated ...\n\n\npagination ...\n\non the timeline viewmodel (containing the TilesCollection?) we'll have a method to (un)load a tail or head of\nthe timeline (counted in tiles), which results to a range in sortKeys we want on the screen. We pass that range\nto the room timeline, which unload entries from memory.\nwhen loading, it just reads events from a sortkey backwards or forwards...\n*/\nimport {TilesCollection} from \"./TilesCollection.js\";\nimport {ViewModel} from \"../../../ViewModel\";\n\nexport class TimelineViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {timeline, tileOptions} = options;\n this._timeline = this.track(timeline);\n this._tiles = new TilesCollection(timeline.entries, tileOptions);\n this._startTile = null;\n this._endTile = null;\n this._topLoadingPromise = null;\n this._requestedStartTile = null;\n this._requestedEndTile = null;\n this._requestScheduled = false;\n this._showJumpDown = false;\n }\n\n /** if this.tiles is empty, call this with undefined for both startTile and endTile */\n setVisibleTileRange(startTile, endTile) {\n // don't clear these once done as they are used to check\n // for more tiles once loadAtTop finishes\n this._requestedStartTile = startTile;\n this._requestedEndTile = endTile;\n if (!this._requestScheduled) {\n Promise.resolve().then(() => {\n this._setVisibleTileRange(this._requestedStartTile, this._requestedEndTile);\n this._requestScheduled = false;\n });\n this._requestScheduled = true;\n }\n }\n\n _setVisibleTileRange(startTile, endTile) {\n let loadTop;\n if (startTile && endTile) {\n // old tiles could have been removed from tilescollection once we support unloading\n this._startTile = startTile;\n this._endTile = endTile;\n const startIndex = this._tiles.getTileIndex(this._startTile);\n const endIndex = this._tiles.getTileIndex(this._endTile);\n for (const tile of this._tiles.sliceIterator(startIndex, endIndex + 1)) {\n tile.notifyVisible();\n }\n loadTop = startIndex < 10;\n this._setShowJumpDown(endIndex < (this._tiles.length - 1));\n } else {\n // tiles collection is empty, load more at top\n loadTop = true;\n this._setShowJumpDown(false);\n }\n\n if (loadTop && !this._topLoadingPromise) {\n this._topLoadingPromise = this._timeline.loadAtTop(10).then(hasReachedEnd => {\n this._topLoadingPromise = null;\n if (!hasReachedEnd) {\n // check if more items need to be loaded by recursing\n // use the requested start / end tile,\n // so we don't end up overwriting a newly requested visible range here\n this.setVisibleTileRange(this._requestedStartTile, this._requestedEndTile);\n }\n });\n }\n }\n\n get tiles() {\n return this._tiles;\n }\n\n _setShowJumpDown(show) {\n if (this._showJumpDown !== show) {\n this._showJumpDown = show;\n this.emitChange(\"showJumpDown\");\n }\n }\n\n get showJumpDown() {\n return this._showJumpDown;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\n\nexport class ComposerViewModel extends ViewModel {\n constructor(roomVM) {\n super(roomVM.options);\n this._roomVM = roomVM;\n this._isEmpty = true;\n this._replyVM = null;\n }\n\n setReplyingTo(entry) {\n const changed = new Boolean(entry) !== new Boolean(this._replyVM) || !this._replyVM?.id.equals(entry.asEventKey());\n if (changed) {\n this._replyVM = this.disposeTracked(this._replyVM);\n if (entry) {\n this._replyVM = this.track(this._roomVM._createTile(entry));\n this._replyVM.notifyVisible();\n }\n this.emitChange(\"replyViewModel\");\n this.emit(\"focus\");\n }\n }\n\n clearReplyingTo() {\n this.setReplyingTo(null);\n }\n\n get replyViewModel() {\n return this._replyVM;\n }\n\n get isEncrypted() {\n return this._roomVM.isEncrypted;\n }\n\n async sendMessage(message) {\n const success = await this._roomVM._sendMessage(message, this._replyVM);\n if (success) {\n this._isEmpty = true;\n this.emitChange(\"canSend\");\n this.clearReplyingTo();\n }\n return success;\n }\n\n sendPicture() {\n this._roomVM._pickAndSendPicture();\n }\n\n sendFile() {\n this._roomVM._pickAndSendFile();\n }\n\n sendVideo() {\n this._roomVM._pickAndSendVideo();\n }\n\n get canSend() {\n return !this._isEmpty;\n }\n\n async setInput(text) {\n const wasEmpty = this._isEmpty;\n this._isEmpty = text.length === 0;\n if (wasEmpty && !this._isEmpty) {\n this._roomVM._room.ensureMessageKeyIsShared();\n }\n if (wasEmpty !== this._isEmpty) {\n this.emitChange(\"canSend\");\n }\n }\n\n get kind() {\n return \"composer\";\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {BlobHandle} from \"../platform/web/dom/BlobHandle\";\nimport type {RequestFunction} from \"../platform/types/types\";\nimport type {Platform} from \"../platform/web/Platform\";\nimport type {ILogger} from \"../logging/types\";\nimport type { IDBLogPersister } from \"../logging/IDBLogPersister\";\nimport type { Session } from \"../matrix/Session\";\n\n// see https://github.com/matrix-org/rageshake#readme\ntype RageshakeData = {\n // A textual description of the problem. Included in the details.log.gz file.\n text?: string;\n // Application user-agent. Included in the details.log.gz file.\n userAgent: string;\n // Identifier for the application (eg 'riot-web'). Should correspond to a mapping configured in the configuration file for github issue reporting to work.\n app: string;\n // Application version. Included in the details.log.gz file.\n version: string;\n // Label to attach to the github issue, and include in the details file.\n label?: string;\n};\n\nexport async function submitLogsToRageshakeServer(data: RageshakeData, logsBlob: BlobHandle, submitUrl: string, request: RequestFunction): Promise {\n const formData = new Map();\n if (data.text) {\n formData.set(\"text\", data.text);\n }\n formData.set(\"user_agent\", data.userAgent);\n formData.set(\"app\", data.app);\n formData.set(\"version\", data.version);\n if (data.label) {\n formData.set(\"label\", data.label);\n }\n formData.set(\"file\", {name: \"logs.json\", blob: logsBlob});\n const headers: Map = new Map();\n headers.set(\"Accept\", \"application/json\");\n const result = request(submitUrl, {\n method: \"POST\",\n body: formData,\n headers\n });\n let response;\n try {\n response = await result.response();\n } catch (err) {\n throw new Error(`Could not submit logs to ${submitUrl}, got error ${err.message}`);\n }\n const {status, body} = response;\n if (status < 200 || status >= 300) {\n throw new Error(`Could not submit logs to ${submitUrl}, got status code ${status} with body ${body}`);\n }\n // we don't bother with reading report_url from the body as the rageshake server doesn't always return it\n // and would have to have CORS setup properly for us to be able to read it.\n}\n\n/** @throws {Error} */\nexport async function submitLogsFromSessionToDefaultServer(session: Session, platform: Platform): Promise {\n const {bugReportEndpointUrl} = platform.config;\n if (!bugReportEndpointUrl) {\n throw new Error(\"no server configured to submit logs\");\n }\n const logReporters = (platform.logger as ILogger).reporters;\n const exportReporter = logReporters.find(r => !!r[\"export\"]) as IDBLogPersister | undefined;\n if (!exportReporter) {\n throw new Error(\"No logger that can export configured\");\n }\n const logExport = await exportReporter.export();\n await submitLogsToRageshakeServer(\n {\n app: \"hydrogen\",\n userAgent: platform.description,\n version: platform.version,\n text: `Submit logs from settings for user ${session.userId} on device ${session.deviceId}`,\n },\n logExport.asBlob(),\n bugReportEndpointUrl,\n platform.request\n );\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { ViewModel, Options as BaseOptions } from \"./ViewModel\";\nimport {submitLogsFromSessionToDefaultServer} from \"./rageshake\";\nimport type { Session } from \"../matrix/Session\";\nimport type {SegmentType} from \"./navigation/index\";\n\ntype Options = {\n error: Error\n session: Session,\n onClose: () => void\n} & BaseOptions;\n\nexport class ErrorViewModel = Options> extends ViewModel {\n get message(): string {\n return this.error.message;\n }\n\n get error(): Error {\n return this.getOption(\"error\");\n }\n\n close() {\n this.getOption(\"onClose\")();\n }\n\n async submitLogs(): Promise {\n try {\n await submitLogsFromSessionToDefaultServer(this.getOption(\"session\"), this.platform);\n return true;\n } catch (err) {\n return false;\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { ViewModel } from \"./ViewModel\";\nimport type { Options as BaseOptions } from \"./ViewModel\";\nimport type { Session } from \"../matrix/Session\";\nimport { ErrorViewModel } from \"./ErrorViewModel\";\nimport type { LogCallback, LabelOrValues } from \"../logging/types\";\n\nexport type Options = BaseOptions & {\n session: Session\n};\n\n/** Base class for view models that need to report errors to the UI. */\nexport class ErrorReportViewModel = Options> extends ViewModel {\n private _errorViewModel?: ErrorViewModel;\n\n get errorViewModel(): ErrorViewModel | undefined {\n return this._errorViewModel;\n }\n\n /** Typically you'd want to use `logAndCatch` when implementing a view model method.\n * Use `reportError` when showing errors on your model that were set by\n * background processes using `ErrorBoundary` or you have some other\n * special low-level need to write your try/catch yourself. */\n protected reportError(error: Error) {\n if (this._errorViewModel?.error === error) {\n return;\n }\n this.disposeTracked(this._errorViewModel);\n this._errorViewModel = this.track(new ErrorViewModel(this.childOptions({\n error,\n onClose: () => {\n this._errorViewModel = this.disposeTracked(this._errorViewModel);\n this.emitChange(\"errorViewModel\");\n }\n })));\n this.emitChange(\"errorViewModel\");\n }\n\n /** Combines logging and error reporting in one method.\n * Wrap the implementation of public view model methods\n * with this to ensure errors are logged and reported.*/\n protected logAndCatch(labelOrValues: LabelOrValues, callback: LogCallback, errorValue: T = undefined as unknown as T): T {\n try {\n let result = this.logger.run(labelOrValues, callback);\n if (result instanceof Promise) {\n result = result.catch(err => {\n this.reportError(err);\n return errorValue;\n }) as unknown as T;\n }\n return result;\n } catch (err) {\n this.reportError(err);\n return errorValue;\n }\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AvatarSource} from \"../../AvatarSource\";\nimport type {ViewModel} from \"../../ViewModel\";\nimport {ErrorReportViewModel, Options as BaseOptions} from \"../../ErrorReportViewModel\";\nimport {getStreamVideoTrack, getStreamAudioTrack} from \"../../../matrix/calls/common\";\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\nimport {EventObservableValue} from \"../../../observable/value\";\nimport {ObservableValueMap, BaseObservableMap} from \"../../../observable/map\";\nimport {ErrorViewModel} from \"../../ErrorViewModel\";\nimport type {Room} from \"../../../matrix/room/Room\";\nimport type {GroupCall} from \"../../../matrix/calls/group/GroupCall\";\nimport type {Member} from \"../../../matrix/calls/group/Member\";\nimport type {RoomMember} from \"../../../matrix/room/members/RoomMember\";\nimport type {BaseObservableList} from \"../../../observable/list/BaseObservableList\";\nimport type {BaseObservableValue} from \"../../../observable/value\";\nimport type {Stream} from \"../../../platform/types/MediaDevices\";\nimport type {MediaRepository} from \"../../../matrix/net/MediaRepository\";\nimport type {Session} from \"../../../matrix/Session\";\nimport type {SegmentType} from \"../../navigation\";\n\ntype Options = BaseOptions & {\n call: GroupCall,\n room: Room,\n};\n\nexport class CallViewModel extends ErrorReportViewModel> {\n public readonly memberViewModels: BaseObservableList;\n\n constructor(options: Options) {\n super(options);\n const callObservable = new EventObservableValue(this.call, \"change\");\n this.track(callObservable.subscribe(() => this.onUpdate()));\n const ownMemberViewModelMap = new ObservableValueMap(\"self\", callObservable)\n .mapValues((call, emitChange) => new OwnMemberViewModel(this.childOptions({call, emitChange})), () => {});\n const otherMemberViewModels = this.call.members\n .filterValues(member => member.isConnected)\n .mapValues(\n (member, emitChange) => new CallMemberViewModel(this.childOptions({\n member,\n emitChange,\n mediaRepository: this.getOption(\"room\").mediaRepository\n })),\n (param, vm) => vm?.onUpdate(),\n ) as BaseObservableMap; \n this.memberViewModels = otherMemberViewModels\n .join(ownMemberViewModelMap)\n .sortValues((a, b) => a.compare(b));\n this.track(this.memberViewModels.subscribe({\n onRemove: () => {\n this.emitChange(); // update memberCount\n },\n onAdd: () => {\n this.emitChange(); // update memberCount\n },\n onUpdate: () => {},\n onReset: () => {},\n onMove: () => {}\n }))\n }\n\n get isCameraMuted(): boolean {\n return this.call.muteSettings?.camera ?? true;\n }\n\n get isMicrophoneMuted(): boolean {\n return this.call.muteSettings?.microphone ?? true;\n }\n\n get memberCount(): number {\n return this.memberViewModels.length;\n }\n\n get name(): string {\n return this.call.name;\n }\n\n get id(): string {\n return this.call.id;\n }\n\n private get call(): GroupCall {\n return this.getOption(\"call\");\n }\n\n private onUpdate() {\n if (this.call.error) {\n this.reportError(this.call.error);\n }\n }\n\n async hangup() {\n this.logAndCatch(\"CallViewModel.hangup\", async log => {\n if (this.call.hasJoined) {\n await this.call.leave(log);\n }\n });\n }\n\n async toggleCamera() {\n this.logAndCatch(\"Call.toggleCamera\", async log => {\n const {localMedia, muteSettings} = this.call;\n if (muteSettings && localMedia) {\n // unmute but no track?\n if (muteSettings.camera && !getStreamVideoTrack(localMedia.userMedia)) {\n const stream = await this.platform.mediaDevices.getMediaTracks(!muteSettings.microphone, true);\n await this.call.setMedia(localMedia.withUserMedia(stream));\n } else {\n await this.call.setMuted(muteSettings.toggleCamera());\n }\n this.emitChange();\n }\n });\n }\n\n async toggleMicrophone() {\n this.logAndCatch(\"Call.toggleMicrophone\", async log => {\n const {localMedia, muteSettings} = this.call;\n if (muteSettings && localMedia) {\n // unmute but no track?\n if (muteSettings.microphone && !getStreamAudioTrack(localMedia.userMedia)) {\n const stream = await this.platform.mediaDevices.getMediaTracks(true, !muteSettings.camera);\n await this.call.setMedia(localMedia.withUserMedia(stream));\n } else {\n await this.call.setMuted(muteSettings.toggleMicrophone());\n }\n this.emitChange();\n }\n });\n }\n}\n\nclass OwnMemberViewModel extends ErrorReportViewModel> implements IStreamViewModel {\n private memberObservable: undefined | BaseObservableValue;\n \n constructor(options: Options) {\n super(options);\n this.init();\n }\n\n async init() {\n const room = this.getOption(\"room\");\n this.memberObservable = await room.observeMember(room.user.id);\n this.track(this.memberObservable!.subscribe(() => {\n this.emitChange(undefined);\n }));\n }\n\n get errorViewModel(): ErrorViewModel | undefined {\n return undefined;\n }\n\n get stream(): Stream | undefined {\n return this.call.localPreviewMedia?.userMedia;\n }\n\n private get call(): GroupCall {\n return this.getOption(\"call\");\n }\n\n get isCameraMuted(): boolean {\n return this.call.muteSettings?.camera ?? true;\n }\n\n get isMicrophoneMuted(): boolean {\n return this.call.muteSettings?.microphone ?? true;\n }\n\n get avatarLetter(): string {\n const member = this.memberObservable?.get();\n if (member) {\n return avatarInitials(member.name);\n } else {\n return this.getOption(\"room\").user.id;\n }\n }\n\n get avatarColorNumber(): number {\n return getIdentifierColorNumber(this.getOption(\"room\").user.id);\n }\n\n avatarUrl(size: number): string | undefined {\n const member = this.memberObservable?.get();\n if (member) {\n return getAvatarHttpUrl(member.avatarUrl, size, this.platform, this.getOption(\"room\").mediaRepository);\n }\n }\n\n get avatarTitle(): string {\n const member = this.memberObservable?.get();\n if (member) {\n return member.name;\n } else {\n return this.getOption(\"room\").user.id;\n }\n }\n\n compare(other: IStreamViewModel): number {\n // I always come first.\n return -1;\n }\n}\n\ntype MemberOptions = BaseOptions & {\n member: Member,\n mediaRepository: MediaRepository,\n};\n\nexport class CallMemberViewModel extends ErrorReportViewModel> implements IStreamViewModel {\n get stream(): Stream | undefined {\n return this.member.remoteMedia?.userMedia;\n }\n\n private get member(): Member {\n return this.getOption(\"member\");\n }\n\n get isCameraMuted(): boolean {\n return this.member.remoteMuteSettings?.camera ?? true;\n }\n\n get isMicrophoneMuted(): boolean {\n return this.member.remoteMuteSettings?.microphone ?? true;\n }\n\n get avatarLetter(): string {\n return avatarInitials(this.member.member.name);\n }\n\n get avatarColorNumber(): number {\n return getIdentifierColorNumber(this.member.userId);\n }\n\n avatarUrl(size: number): string | undefined {\n const {avatarUrl} = this.member.member;\n const mediaRepository = this.getOption(\"mediaRepository\");\n return getAvatarHttpUrl(avatarUrl, size, this.platform, mediaRepository);\n }\n\n get avatarTitle(): string {\n return this.member.member.name;\n }\n\n onUpdate() {\n this.mapMemberSyncErrorIfNeeded();\n }\n\n private mapMemberSyncErrorIfNeeded() {\n if (this.member.error) {\n this.reportError(this.member.error);\n }\n }\n\n compare(other: IStreamViewModel): number {\n if (other instanceof CallMemberViewModel) {\n const myUserId = this.member.member.userId;\n const otherUserId = other.member.member.userId;\n if(myUserId === otherUserId) {\n return 0;\n }\n return myUserId < otherUserId ? -1 : 1;\n } else {\n return -other.compare(this);\n }\n }\n}\n\nexport interface IStreamViewModel extends AvatarSource, ViewModel {\n get stream(): Stream | undefined;\n get isCameraMuted(): boolean;\n get isMicrophoneMuted(): boolean;\n get errorViewModel(): ErrorViewModel | undefined;\n compare(other: IStreamViewModel): number;\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function imageToInfo(image) {\n return {\n w: image.width,\n h: image.height,\n mimetype: image.blob.mimeType,\n size: image.blob.size\n };\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SDPStreamMetadataPurpose} from \"./callEventTypes\";\nimport {Stream} from \"../../platform/types/MediaDevices\";\nimport {SDPStreamMetadata} from \"./callEventTypes\";\nimport {getStreamVideoTrack, getStreamAudioTrack} from \"./common\";\n\nexport class LocalMedia {\n\n constructor(\n public readonly userMedia?: Stream,\n public readonly screenShare?: Stream,\n public readonly dataChannelOptions?: RTCDataChannelInit,\n ) {}\n\n withUserMedia(stream: Stream) {\n return new LocalMedia(stream, this.screenShare?.clone(), this.dataChannelOptions);\n }\n\n withScreenShare(stream: Stream) {\n return new LocalMedia(this.userMedia?.clone(), stream, this.dataChannelOptions);\n }\n\n withDataChannel(options: RTCDataChannelInit): LocalMedia {\n return new LocalMedia(this.userMedia?.clone(), this.screenShare?.clone(), options);\n }\n\n /**\n * Create an instance of LocalMedia without audio track (for user preview)\n */\n asPreview(): LocalMedia {\n const media = this.clone();\n const userMedia = media.userMedia;\n if (userMedia && userMedia.getVideoTracks().length > 0) {\n const audioTrack = getStreamAudioTrack(userMedia);\n if (audioTrack) {\n audioTrack.stop();\n userMedia.removeTrack(audioTrack);\n }\n }\n return media;\n }\n\n /** @internal */\n replaceClone(oldClone: LocalMedia | undefined, oldOriginal: LocalMedia | undefined): LocalMedia {\n const cloneOrAdoptStream = (oldOriginalStream: Stream | undefined, oldCloneStream: Stream | undefined, newStream: Stream | undefined): Stream | undefined => {\n let stream;\n if (oldOriginalStream?.id === newStream?.id) {\n return oldCloneStream;\n } else {\n return newStream?.clone();\n }\n }\n return new LocalMedia(\n cloneOrAdoptStream(oldOriginal?.userMedia, oldClone?.userMedia, this.userMedia),\n cloneOrAdoptStream(oldOriginal?.screenShare, oldClone?.screenShare, this.screenShare),\n this.dataChannelOptions\n );\n }\n\n /** @internal */\n clone(): LocalMedia {\n return new LocalMedia(this.userMedia?.clone(),this.screenShare?.clone(), this.dataChannelOptions);\n }\n \n dispose() {\n getStreamAudioTrack(this.userMedia)?.stop();\n getStreamVideoTrack(this.userMedia)?.stop();\n getStreamVideoTrack(this.screenShare)?.stop();\n }\n}\n","import {ITile, TileShape, EmitUpdateFn} from \"./ITile\";\nimport {UpdateAction} from \"../UpdateAction\";\nimport {BaseEntry} from \"../../../../../matrix/room/timeline/entries/BaseEntry\";\nimport {BaseEventEntry} from \"../../../../../matrix/room/timeline/entries/BaseEventEntry\";\nimport {ViewModel} from \"../../../../ViewModel\";\nimport type {SegmentType} from \"../../../../navigation\";\nimport type {Options} from \"../../../../ViewModel\";\n\n/**\n * edge cases:\n * - be able to remove the tile in response to the sibling changing,\n * probably by letting updateNextSibling/updatePreviousSibling\n * return an UpdateAction and change TilesCollection accordingly.\n * this is relevant when next becomes undefined there when\n * a pending event is removed on remote echo.\n * */\n\nexport class DateTile extends ViewModel> implements ITile {\n private _emitUpdate?: EmitUpdateFn;\n private _dateString?: string;\n private _machineReadableString?: string;\n \n constructor(private _firstTileInDay: ITile, options: Options) {\n super(options);\n }\n\n setUpdateEmit(emitUpdate: EmitUpdateFn): void {\n this._emitUpdate = emitUpdate;\n }\n\n get upperEntry(): BaseEventEntry {\n return this.refEntry;\n }\n\n get lowerEntry(): BaseEventEntry {\n return this.refEntry;\n }\n\n /** the entry reference by this datetile, e.g. the entry of the first tile for this day */\n private get refEntry(): BaseEventEntry {\n // lowerEntry is the first entry... i think?\n // so given the date header always comes before,\n // this is our closest entry.\n return this._firstTileInDay.lowerEntry;\n }\n\n compare(tile: ITile): number {\n return this.compareEntry(tile.upperEntry);\n }\n\n get relativeDate(): string {\n if (!this._dateString) {\n this._dateString = this.timeFormatter.formatRelativeDate(new Date(this.refEntry.timestamp));\n }\n return this._dateString;\n }\n\n get machineReadableDate(): string {\n if (!this._machineReadableString) {\n this._machineReadableString = this.timeFormatter.formatMachineReadableDate(new Date(this.refEntry.timestamp));\n }\n return this._machineReadableString;\n }\n\n get shape(): TileShape {\n return TileShape.DateHeader;\n }\n\n get needsDateSeparator(): boolean {\n return false;\n }\n\n createDateSeparator(): undefined {\n return undefined;\n }\n\n/**\n * _findTileIdx in TilesCollection should never return\n * the index of a DateTile as that is mainly used\n * for mapping incoming event indices coming from the Timeline\n * to the tile index to propage the event.\n * This is not a path that is relevant to date headers as they\n * are added as a side-effect of adding other tiles and are generally\n * not updated (only removed in some cases). _findTileIdx is also\n * used for emitting spontanous updates, but that should also not be\n * needed for a DateTile.\n * The problem is basically that _findTileIdx maps an entry to\n * a tile, and DateTile adopts the entry of it's sibling tile (_firstTileInDay)\n * so now we have the entry pointing to two tiles. So we should avoid\n * returning the DateTile itself from the compare method.\n * We will always return -1 or 1 from here to signal an entry comes before or after us,\n * never 0\n * */\n compareEntry(entry: BaseEntry): number {\n const result = this.refEntry.compare(entry);\n if (result === 0) {\n // if it's a match for the reference entry (e.g. _firstTileInDay),\n // say it comes after us as the date tile always comes at the top\n // of the day.\n return -1;\n }\n // otherwise, assume the given entry is never for ourselves\n // as we don't have our own entry, we only borrow one from _firstTileInDay\n return result;\n }\n\n // update received for already included (falls within sort keys) entry\n updateEntry(entry, param): UpdateAction {\n return UpdateAction.Nothing();\n }\n\n // return whether the tile should be removed\n // as SimpleTile only has one entry, the tile should be removed\n removeEntry(entry: BaseEntry): boolean {\n return false;\n }\n\n // SimpleTile can only contain 1 entry\n tryIncludeEntry(): boolean {\n return false;\n }\n\n /**\n * This tile needs to do the comparison between tiles, as it uses the entry\n * from another tile to determine its sorting order.\n * */\n get comparisonIsNotCommutative(): boolean {\n return true;\n }\n\n // let item know it has a new sibling\n updatePreviousSibling(prev: ITile | undefined): void {\n // forward the sibling update to our next tile, so it is informed\n // about it's previous sibling beyond the date header (which is it's direct previous sibling)\n // so it can recalculate whether it still needs a date header\n this._firstTileInDay.updatePreviousSibling(prev);\n }\n\n // let item know it has a new sibling\n updateNextSibling(next: ITile | undefined): UpdateAction {\n if(!next) {\n // If we are the DateTile for the last tile in the timeline,\n // and that tile gets removed, next would be undefined\n // and this DateTile would be removed as well,\n // so do nothing\n return;\n }\n this._firstTileInDay = next;\n const prevDateString = this._dateString;\n this._dateString = undefined;\n this._machineReadableString = undefined;\n if (prevDateString && prevDateString !== this.relativeDate) {\n this._emitUpdate?.(this, \"relativeDate\");\n }\n }\n\n notifyVisible(): void {\n // trigger sticky logic here?\n }\n\n dispose(): void {\n\n }\n}\n\nimport { EventEntry } from \"../../../../../matrix/room/timeline/entries/EventEntry.js\";\nimport { SimpleTile } from \"./SimpleTile\";\n\nexport function tests() {\n return {\n \"date tile sorts before reference tile\": assert => {\n //@ts-ignore\n const a = new SimpleTile(new EventEntry({\n event: {},\n eventIndex: 2,\n fragmentId: 1\n }, undefined), {});\n //@ts-ignore\n const b = new SimpleTile(new EventEntry({\n event: {},\n eventIndex: 3,\n fragmentId: 1\n }, undefined), {});\n const d = new DateTile(b, {} as any);\n const tiles = [d, b, a];\n tiles.sort((a, b) => a.compare(b));\n assert.equal(tiles[0], a);\n assert.equal(tiles[1], d);\n assert.equal(tiles[2], b);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {UpdateAction} from \"../UpdateAction.js\";\nimport {ErrorReportViewModel} from \"../../../../ErrorReportViewModel\";\nimport {ITile, TileShape} from \"./ITile\";\nimport {SendStatus} from \"../../../../../matrix/room/sending/PendingEvent.js\";\nimport {DateTile} from \"./DateTile\";\nimport {Options as BaseOptions} from \"../../../../ErrorReportViewModel\";\nimport {EventEntry} from \"../../../../../matrix/room/timeline/entries/EventEntry.js\";\nimport type {RoomViewModel} from \"../../RoomViewModel.js\";\nimport type {Timeline} from \"../../../../../matrix/room/timeline/Timeline.js\";\nimport type {SegmentType} from \"../../../../navigation/index.js\";\n\nexport type Options = {\n roomVM: RoomViewModel; \n timeline: Timeline;\n} & BaseOptions;\n\ntype EmitUpdate = (tile: SimpleTile, params: any) => void; \n\n\nexport abstract class SimpleTile extends ErrorReportViewModel> implements ITile {\n private _entry: EventEntry;\n private _date?: Date;\n private _needsDateSeparator: boolean = false;\n private _emitUpdate?: EmitUpdate;\n \n constructor(entry: EventEntry, options: Options) {\n super(options);\n this._entry = entry;\n this._date = this._entry.timestamp ? new Date(this._entry.timestamp) : undefined;\n }\n // view model props for all subclasses\n // hmmm, could also do instanceof ... ?\n // \"gap\" | \"message\" | \"image\" | ... ?\n abstract get shape(): TileShape;\n\n // don't show display name / avatar\n // probably only for BaseMessageTiles of some sort?\n get isContinuation() {\n return false;\n }\n\n get needsDateSeparator() {\n return this._needsDateSeparator;\n }\n\n createDateSeparator() {\n return new DateTile(this, this.childOptions({}));\n }\n\n _updateDateSeparator(prev: SimpleTile) {\n if (prev && prev._date && this._date) {\n this._needsDateSeparator = prev._date.getFullYear() !== this._date.getFullYear() ||\n prev._date.getMonth() !== this._date.getMonth() ||\n prev._date.getDate() !== this._date.getDate();\n } else {\n this._needsDateSeparator = !!this._date;\n }\n }\n\n get id() {\n return this._entry.asEventKey();\n }\n\n get eventId() {\n return this._entry.id;\n }\n\n get isPending() {\n return this._entry.isPending;\n }\n\n get isUnsent() {\n return this._entry.isPending && this._entry.pendingEvent.status !== SendStatus.Sent;\n }\n\n get canAbortSending() {\n return this._entry.isPending &&\n !this._entry.pendingEvent.hasStartedSending;\n }\n\n async abortSending(): Promise {\n await this._entry.pendingEvent?.abort();\n }\n\n // TilesCollection contract below\n setUpdateEmit(emitUpdate?: EmitUpdate) {\n this._emitUpdate = emitUpdate;\n }\n\n /** overrides the emitChange in ViewModel to also emit the update over the tiles collection */\n emitChange(changedProps) {\n if (this._emitUpdate) {\n // it can happen that after some network call\n // we switched away from the room and the response\n // comes in, triggering an emitChange in a tile that\n // has been disposed already (and hence the change\n // callback has been cleared by dispose) We should just ignore this.\n this._emitUpdate(this, changedProps);\n }\n super.emitChange(changedProps);\n }\n\n get upperEntry() {\n return this._entry;\n }\n\n get lowerEntry() {\n return this._entry;\n }\n\n get comparisonIsNotCommutative() {\n return false;\n }\n\n compare(tile: SimpleTile) {\n if (tile.comparisonIsNotCommutative) {\n return -tile.compare(this);\n } else {\n return this.upperEntry.compare(tile.upperEntry);\n }\n }\n\n compareEntry(entry: EventEntry) {\n return this._entry.compare(entry);\n }\n\n // update received for already included (falls within sort keys) entry\n updateEntry(entry, param) {\n const renderedAsRedacted = this.shape === \"redacted\";\n if (!entry.isGap && entry.isRedacted !== renderedAsRedacted) {\n // recreate the tile if the entry becomes redacted\n return UpdateAction.Replace(\"shape\");\n } else {\n this._entry = entry;\n return UpdateAction.Update(param);\n }\n }\n\n // return whether the tile should be removed\n // as SimpleTile only has one entry, the tile should be removed\n removeEntry(/*entry*/) {\n return true;\n }\n\n // SimpleTile can only contain 1 entry\n tryIncludeEntry() {\n return false;\n }\n // let item know it has a new sibling\n updatePreviousSibling(prev) {\n if (prev?.shape !== TileShape.DateHeader) {\n this._updateDateSeparator(prev);\n }\n }\n\n // let item know it has a new sibling\n updateNextSibling(/*next*/) {\n \n }\n\n notifyVisible() {}\n\n dispose() {\n this.setUpdateEmit(undefined);\n super.dispose();\n }\n // TilesCollection contract above\n\n get _room() {\n return this._roomVM.room;\n }\n\n get _roomVM() {\n return this.options.roomVM;\n }\n\n get _timeline() {\n return this.options.timeline;\n }\n\n get _powerLevels() {\n return this._timeline.powerLevels;\n }\n\n get _ownMember() {\n return this.options.timeline.me;\n }\n\n get displayName() {\n return this._entry.displayName || this.sender;\n }\n\n get sender() {\n return this._entry.sender;\n }\n}\n\n\nexport function tests() {\n return {\n \"needsDateSeparator is false when previous sibling is for same date\": assert => {\n const fridayEntry = new EventEntry({\n event: {\n origin_server_ts: 1669376446222,\n type: \"m.room.message\",\n content: {}\n }\n }, undefined);\n const thursdayEntry = new EventEntry({\n event: {\n origin_server_ts: fridayEntry.timestamp - (60 * 60 * 8 * 1000),\n type: \"m.room.message\",\n content: {}\n }\n }, undefined);\n //@ts-ignore\n const fridayTile = new SimpleTile(fridayEntry, {});\n //@ts-ignore\n const thursdayTile = new SimpleTile(thursdayEntry, {});\n assert.equal(fridayTile.needsDateSeparator, false);\n fridayTile.updatePreviousSibling(thursdayTile);\n assert.equal(fridayTile.needsDateSeparator, false);\n },\n \"needsDateSeparator is true when previous sibling is for different date\": assert => {\n const fridayEntry = new EventEntry({\n event: {\n origin_server_ts: 1669376446222,\n type: \"m.room.message\",\n content: {}\n }\n }, undefined);\n const thursdayEntry = new EventEntry({\n event: {\n origin_server_ts: fridayEntry.timestamp - (60 * 60 * 24 * 1000),\n type: \"m.room.message\",\n content: {}\n }\n }, undefined);\n //@ts-ignore\n const fridayTile = new SimpleTile(fridayEntry, {});\n //@ts-ignore\n const thursdayTile = new SimpleTile(thursdayEntry, {});\n assert.equal(fridayTile.needsDateSeparator, false);\n fridayTile.updatePreviousSibling(thursdayTile);\n assert.equal(fridayTile.needsDateSeparator, true);\n },\n \"needsDateSeparator is true when previous sibling is undefined\": assert => {\n const fridayEntry = new EventEntry({\n event: {\n origin_server_ts: 1669376446222,\n type: \"m.room.message\",\n content: {}\n }\n }, undefined);\n //@ts-ignore\n const fridayTile = new SimpleTile(fridayEntry, {});\n assert.equal(fridayTile.needsDateSeparator, false);\n fridayTile.updatePreviousSibling(undefined);\n assert.equal(fridayTile.needsDateSeparator, true);\n },\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SimpleTile} from \"./SimpleTile\";\nimport {UpdateAction} from \"../UpdateAction.js\";\nimport {ConnectionError} from \"../../../../../matrix/error.js\";\nimport {ConnectionStatus} from \"../../../../../matrix/net/Reconnector\";\n\n// TODO: should this become an ITile and SimpleTile become EventTile?\nexport class GapTile extends SimpleTile {\n constructor(entry, options) {\n super(entry, options);\n this._loading = false;\n this._waitingForConnection = false;\n this._isAtTop = true;\n this._siblingChanged = false;\n }\n\n get needsDateSeparator() {\n return false;\n }\n\n async fill(isRetrying = false) {\n if (!this._loading && !this._entry.edgeReached) {\n this._loading = true;\n this.emitChange(\"isLoading\");\n try {\n await this._room.fillGap(this._entry, 10);\n } catch (err) {\n if (err instanceof ConnectionError) {\n await this._waitForReconnection();\n if (!isRetrying) {\n // retry after the connection comes back\n // if this wasn't already a retry after coming back online\n return await this.fill(true);\n } else {\n return false;\n }\n } else {\n this.reportError(err);\n return false;\n }\n } finally {\n this._loading = false;\n this.emitChange(\"isLoading\");\n }\n return true;\n }\n return false;\n }\n\n async notifyVisible() {\n // if any error happened before (apart from being offline),\n // let the user dismiss the error before trying to backfill\n // again so we don't try to do backfill the don't succeed\n // in quick succession\n if (this.errorViewModel) {\n return;\n }\n // we do (up to 10) backfills while no new tiles have been added to the timeline\n // because notifyVisible won't be called again until something gets added to the timeline\n let depth = 0;\n let canFillMore;\n this._siblingChanged = false;\n do {\n canFillMore = await this.fill();\n depth = depth + 1;\n } while (depth < 10 && !this._siblingChanged && canFillMore && !this.isDisposed);\n }\n\n get isAtTop() {\n return this._isAtTop;\n }\n\n updatePreviousSibling(prev) {\n super.updatePreviousSibling(prev);\n const isAtTop = !prev;\n if (this._isAtTop !== isAtTop) {\n this._isAtTop = isAtTop;\n this.emitChange(\"isAtTop\");\n }\n this._siblingChanged = true;\n }\n\n updateNextSibling() {\n // if the sibling of the gap changed while calling room.fill(),\n // we intepret this as at least one new tile has been added to\n // the timeline. See notifyVisible why this is important.\n this._siblingChanged = true;\n }\n\n updateEntry(entry, params) {\n super.updateEntry(entry, params);\n if (!entry.isGap) {\n return UpdateAction.Remove();\n } else {\n return UpdateAction.Nothing();\n }\n }\n\n async _waitForReconnection() {\n this._waitingForConnection = true;\n this.emitUpdate(\"status\");\n await this.options.client.reconnector.connectionStatus.waitFor(status => status === ConnectionStatus.Online).promise;\n this._waitingForConnection = false;\n this.emitUpdate(\"status\");\n }\n\n get shape() {\n return \"gap\";\n }\n\n get isLoading() {\n return this._loading;\n }\n\n get showSpinner() {\n return this.isLoading || this._waitingForConnection;\n }\n\n get status() {\n const dir = this._entry.prev_batch ? \"previous\" : \"next\";\n if (this._waitingForConnection) {\n return \"Waiting for connection…\";\n } else if (this.errorViewModel) {\n return `Could not load ${dir} messages`;\n } else if (this.isLoading) {\n return \"Loading more messages…\";\n } else {\n return \"Gave up loading more messages\";\n }\n }\n}\n\nimport {FragmentBoundaryEntry} from \"../../../../../matrix/room/timeline/entries/FragmentBoundaryEntry.js\";\nexport function tests() {\n return {\n \"uses updated token to fill\": async assert => {\n let currentToken = 5;\n const fragment = {\n id: 0,\n previousToken: currentToken,\n roomId: \"!abc\"\n };\n const room = {\n async fillGap(entry) {\n assert.equal(entry.token, currentToken);\n currentToken += 1;\n const newEntry = entry.withUpdatedFragment(Object.assign({}, fragment, {previousToken: currentToken}));\n tile.updateEntry(newEntry);\n }\n };\n const tile = new GapTile(new FragmentBoundaryEntry(fragment, true), {roomVM: {room}});\n await tile.fill();\n await tile.fill();\n await tile.fill();\n assert.equal(currentToken, 8);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {ObservableMap} from \"../../../../observable\";\n\nexport class ReactionsViewModel {\n constructor(parentTile) {\n this._parentTile = parentTile;\n this._map = new ObservableMap();\n this._reactions = this._map.sortValues((a, b) => a._compare(b));\n }\n\n /** @package */\n update(annotations, pendingAnnotations) {\n if (annotations) {\n for (const key in annotations) {\n if (annotations.hasOwnProperty(key)) {\n const annotation = annotations[key];\n const reaction = this._map.get(key);\n if (reaction) {\n if (reaction._tryUpdate(annotation)) {\n this._map.update(key);\n }\n } else {\n this._map.add(key, new ReactionViewModel(key, annotation, null, this._parentTile));\n }\n }\n }\n }\n if (pendingAnnotations) {\n for (const [key, annotation] of pendingAnnotations.entries()) {\n const reaction = this._map.get(key);\n if (reaction) {\n reaction._tryUpdatePending(annotation);\n this._map.update(key);\n } else {\n this._map.add(key, new ReactionViewModel(key, null, annotation, this._parentTile));\n }\n }\n }\n for (const existingKey of this._map.keys()) {\n const hasPending = pendingAnnotations?.has(existingKey);\n const hasRemote = annotations?.hasOwnProperty(existingKey);\n if (!hasRemote && !hasPending) {\n this._map.remove(existingKey);\n } else if (!hasRemote) {\n if (this._map.get(existingKey)._tryUpdate(null)) {\n this._map.update(existingKey);\n }\n } else if (!hasPending) {\n if (this._map.get(existingKey)._tryUpdatePending(null)) {\n this._map.update(existingKey);\n }\n }\n }\n }\n\n get reactions() {\n return this._reactions;\n }\n\n getReaction(key) {\n return this._map.get(key);\n }\n}\n\nclass ReactionViewModel {\n constructor(key, annotation, pending, parentTile) {\n this._key = key;\n this._annotation = annotation;\n this._pending = pending;\n this._parentTile = parentTile;\n this._isToggling = false;\n }\n\n _tryUpdate(annotation) {\n const oneSetAndOtherNot = !!this._annotation !== !!annotation;\n const bothSet = this._annotation && annotation;\n const areDifferent = bothSet && (\n annotation.me !== this._annotation.me ||\n annotation.count !== this._annotation.count ||\n annotation.firstTimestamp !== this._annotation.firstTimestamp\n );\n if (oneSetAndOtherNot || areDifferent) {\n this._annotation = annotation;\n return true;\n }\n return false;\n }\n\n _tryUpdatePending(pending) {\n if (!pending && !this._pending) {\n return false;\n }\n this._pending = pending;\n return true;\n }\n\n get key() {\n return this._key;\n }\n\n get count() {\n return (this._pending?.count || 0) + (this._annotation?.count || 0);\n }\n\n get isPending() {\n return this._pending !== null;\n }\n\n /** @returns {boolean} true if the user has a (pending) reaction\n * already for this key, or they have a pending redaction for\n * the reaction, false if there is nothing pending and\n * the user has not reacted yet. */\n get isActive() {\n return this._annotation?.me || this.isPending;\n }\n\n get firstTimestamp() {\n let ts = Number.MAX_SAFE_INTEGER;\n if (this._annotation) {\n ts = Math.min(ts, this._annotation.firstTimestamp);\n }\n if (this._pending) {\n ts = Math.min(ts, this._pending.firstTimestamp);\n }\n return ts;\n }\n\n _compare(other) {\n // the comparator is also used to test for equality by sortValues, if the comparison returns 0\n // given that the firstTimestamp isn't set anymore when the last reaction is removed,\n // the remove event wouldn't be able to find the correct index anymore. So special case equality.\n if (other === this) {\n return 0;\n }\n if (this.count !== other.count) {\n return other.count - this.count;\n } else {\n const cmp = this.firstTimestamp - other.firstTimestamp;\n if (cmp === 0) {\n return this.key < other.key ? -1 : 1;\n }\n return cmp;\n }\n }\n\n async toggle(log = null) {\n if (this._isToggling) {\n console.log(\"busy toggling reaction already\");\n return;\n }\n this._isToggling = true;\n try {\n await this._parentTile.toggleReaction(this.key, log);\n } finally {\n this._isToggling = false;\n }\n }\n}\n\n// matrix classes uses in the integration test below\nimport {User} from \"../../../../matrix/User.js\";\nimport {SendQueue} from \"../../../../matrix/room/sending/SendQueue.js\";\nimport {Timeline} from \"../../../../matrix/room/timeline/Timeline.js\";\nimport {EventEntry} from \"../../../../matrix/room/timeline/entries/EventEntry.js\";\nimport {RelationWriter} from \"../../../../matrix/room/timeline/persistence/RelationWriter.js\";\nimport {FragmentIdComparer} from \"../../../../matrix/room/timeline/FragmentIdComparer.js\";\nimport {createAnnotation} from \"../../../../matrix/room/timeline/relations.js\";\n// mocks\nimport {Clock as MockClock} from \"../../../../mocks/Clock.js\";\nimport {createMockStorage} from \"../../../../mocks/Storage\";\nimport {ListObserver} from \"../../../../mocks/ListObserver.js\";\nimport {createEvent, withTextBody, withContent} from \"../../../../mocks/event.js\";\nimport {NullLogItem, NullLogger} from \"../../../../logging/NullLogger\";\nimport {HomeServer as MockHomeServer} from \"../../../../mocks/HomeServer.js\";\n// other imports\nimport {BaseMessageTile} from \"./tiles/BaseMessageTile.js\";\nimport {MappedList} from \"../../../../observable/list/MappedList\";\nimport {ObservableValue} from \"../../../../observable/value\";\nimport {PowerLevels} from \"../../../../matrix/room/PowerLevels.js\";\n\nexport function tests() {\n const fragmentIdComparer = new FragmentIdComparer([]);\n const roomId = \"$abc\";\n const alice = \"@alice:hs.tld\";\n const bob = \"@bob:hs.tld\";\n const logger = new NullLogger();\n\n function findInIterarable(it, predicate) {\n let i = 0;\n for (const item of it) {\n if (predicate(item, i)) {\n return item;\n }\n i += 1;\n }\n throw new Error(\"not found\");\n }\n\n function mapMessageEntriesToBaseMessageTile(timeline, queue) {\n const room = {\n id: roomId,\n sendEvent(eventType, content, attachments, log) {\n return queue.enqueueEvent(eventType, content, attachments, log);\n },\n sendRedaction(eventIdOrTxnId, reason, log) {\n return queue.enqueueRedaction(eventIdOrTxnId, reason, log);\n }\n };\n const tiles = new MappedList(timeline.entries, entry => {\n if (entry.eventType === \"m.room.message\") {\n return new BaseMessageTile(entry, {roomVM: {room}, timeline, platform: {logger}});\n }\n return null;\n }, (tile, params, entry) => tile?.updateEntry(entry, params, function () {}));\n return tiles;\n }\n\n return {\n // these are more an integration test than unit tests,\n // but fully test the local echo when toggling and\n // the correct send queue modifications happen\n \"toggling reaction with own remote reaction\": async assert => {\n // 1. put message and reaction in storage\n const messageEvent = withTextBody(\"Dogs > Cats\", createEvent(\"m.room.message\", \"!abc\", bob));\n const myReactionEvent = withContent(createAnnotation(messageEvent.event_id, \"🐶\"), createEvent(\"m.reaction\", \"!def\", alice));\n myReactionEvent.origin_server_ts = 5;\n const myReactionEntry = new EventEntry({event: myReactionEvent, roomId}, fragmentIdComparer);\n const relationWriter = new RelationWriter({roomId, ownUserId: alice, fragmentIdComparer});\n const storage = await createMockStorage();\n const txn = await storage.readWriteTxn([\n storage.storeNames.timelineEvents,\n storage.storeNames.timelineRelations,\n storage.storeNames.timelineFragments\n ]);\n txn.timelineFragments.add({id: 1, roomId});\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 2, event: messageEvent, roomId}, new NullLogItem());\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 3, event: myReactionEvent, roomId}, new NullLogItem());\n await relationWriter.writeRelation(myReactionEntry, txn, new NullLogItem());\n await txn.complete();\n // 2. setup queue & timeline\n const queue = new SendQueue({roomId, storage, hsApi: new MockHomeServer().api});\n const powerLevelsObservable = new ObservableValue(new PowerLevels({ ownUserId: alice, membership: \"join\" }));\n const timeline = new Timeline({\n roomId,\n storage,\n fragmentIdComparer,\n clock: new MockClock(),\n pendingEvents: queue.pendingEvents,\n powerLevelsObservable\n });\n // 3. load the timeline, which will load the message with the reaction\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n const tiles = mapMessageEntriesToBaseMessageTile(timeline, queue);\n // 4. subscribe to the queue to observe, and the tiles (so we can safely iterate)\n const queueObserver = new ListObserver();\n queue.pendingEvents.subscribe(queueObserver);\n tiles.subscribe(new ListObserver());\n const messageTile = findInIterarable(tiles, e => !!e); // the other entries are mapped to null\n const reactionVM = messageTile.reactions.getReaction(\"🐶\");\n // 5. test toggling\n // make sure the preexisting reaction is counted\n assert.equal(reactionVM.count, 1);\n // 5.1. unset reaction, should redact the pre-existing reaction\n await reactionVM.toggle();\n {\n assert.equal(reactionVM.count, 0);\n const {value: redaction, type} = await queueObserver.next();\n assert.equal(\"add\", type);\n assert.equal(redaction.eventType, \"m.room.redaction\");\n assert.equal(redaction.relatedEventId, myReactionEntry.id);\n // SendQueue puts redaction in sending status, as it is first in the queue\n assert.equal(\"update\", (await queueObserver.next()).type);\n }\n // 5.2. set reaction, should send a new reaction as the redaction is already sending\n await reactionVM.toggle();\n let reactionIndex;\n {\n assert.equal(reactionVM.count, 1);\n const {value: reaction, type, index} = await queueObserver.next();\n assert.equal(\"add\", type);\n assert.equal(reaction.eventType, \"m.reaction\");\n assert.equal(reaction.relatedEventId, messageEvent.event_id);\n reactionIndex = index;\n }\n // 5.3. unset reaction, should abort the previous pending reaction as it hasn't started sending yet\n await reactionVM.toggle();\n {\n assert.equal(reactionVM.count, 0);\n const {index, type} = await queueObserver.next();\n assert.equal(\"remove\", type);\n assert.equal(reactionIndex, index);\n }\n },\n \"toggling reaction without own remote reaction\": async assert => {\n // 1. put message in storage\n const messageEvent = withTextBody(\"Dogs > Cats\", createEvent(\"m.room.message\", \"!abc\", bob));\n const storage = await createMockStorage();\n\n const txn = await storage.readWriteTxn([\n storage.storeNames.timelineEvents,\n storage.storeNames.timelineFragments\n ]);\n txn.timelineFragments.add({id: 1, roomId});\n txn.timelineEvents.tryInsert({fragmentId: 1, eventIndex: 2, event: messageEvent, roomId}, new NullLogItem());\n await txn.complete();\n // 2. setup queue & timeline\n const queue = new SendQueue({roomId, storage, hsApi: new MockHomeServer().api});\n const powerLevelsObservable = new ObservableValue(new PowerLevels({ ownUserId: alice, membership: \"join\" }));\n const timeline = new Timeline({roomId, storage, fragmentIdComparer,\n clock: new MockClock(), pendingEvents: queue.pendingEvents, powerLevelsObservable});\n\n // 3. load the timeline, which will load the message with the reaction\n await timeline.load(new User(alice), \"join\", new NullLogItem());\n const tiles = mapMessageEntriesToBaseMessageTile(timeline, queue);\n // 4. subscribe to the queue to observe, and the tiles (so we can safely iterate)\n const queueObserver = new ListObserver();\n queue.pendingEvents.subscribe(queueObserver);\n tiles.subscribe(new ListObserver());\n const messageTile = findInIterarable(tiles, e => !!e); // the other entries are mapped to null\n // 5. test toggling\n assert.equal(messageTile.reactions, null);\n // 5.1. set reaction, should send a new reaction as there is none yet\n await messageTile.react(\"🐶\");\n // now there should be a reactions view model\n const reactionVM = messageTile.reactions.getReaction(\"🐶\");\n let reactionTxnId;\n {\n assert.equal(reactionVM.count, 1);\n const {value: reaction, type} = await queueObserver.next();\n assert.equal(\"add\", type);\n assert.equal(reaction.eventType, \"m.reaction\");\n assert.equal(reaction.relatedEventId, messageEvent.event_id);\n // SendQueue puts reaction in sending status, as it is first in the queue\n assert.equal(\"update\", (await queueObserver.next()).type);\n reactionTxnId = reaction.txnId;\n }\n // 5.2. unset reaction, should redact the previous pending reaction as it has started sending already\n let redactionIndex;\n await reactionVM.toggle();\n {\n assert.equal(reactionVM.count, 0);\n const {value: redaction, type, index} = await queueObserver.next();\n assert.equal(\"add\", type);\n assert.equal(redaction.eventType, \"m.room.redaction\");\n assert.equal(redaction.relatedTxnId, reactionTxnId);\n redactionIndex = index;\n }\n // 5.3. set reaction, should abort the previous pending redaction as it hasn't started sending yet\n await reactionVM.toggle();\n {\n assert.equal(reactionVM.count, 1);\n const {index, type} = await queueObserver.next();\n assert.equal(\"remove\", type);\n assert.equal(redactionIndex, index);\n redactionIndex = index;\n }\n },\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SimpleTile} from \"./SimpleTile\";\nimport {ReactionsViewModel} from \"../ReactionsViewModel.js\";\nimport {getIdentifierColorNumber, avatarInitials, getAvatarHttpUrl} from \"../../../../avatar\";\n\n\nexport class BaseMessageTile extends SimpleTile {\n constructor(entry, options) {\n super(entry, options);\n this._isContinuation = false;\n this._reactions = null;\n this._replyTile = null;\n if (this._entry.annotations || this._entry.pendingAnnotations) {\n this._updateReactions();\n }\n this._updateReplyTileIfNeeded(undefined);\n }\n\n notifyVisible() {\n super.notifyVisible();\n this._replyTile?.notifyVisible();\n }\n\n\n get _mediaRepository() {\n return this._room.mediaRepository;\n }\n\n get permaLink() {\n return `https://matrix.to/#/${encodeURIComponent(this._room.id)}/${encodeURIComponent(this._entry.id)}`;\n }\n\n copyPermalink() {\n this.platform.copyPlaintext(this.permaLink);\n }\n\n get senderProfileLink() {\n return `https://matrix.to/#/${encodeURIComponent(this.sender)}`;\n }\n\n get memberPanelLink() {\n return `${this.urlRouter.urlUntilSegment(\"room\")}/member/${this.sender}`;\n }\n\n // Avatar view model contract\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._entry.sender);\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._entry.avatarUrl, size, this.platform, this._mediaRepository);\n }\n\n get avatarLetter() {\n return avatarInitials(this.sender);\n }\n\n get avatarTitle() {\n return this.sender;\n }\n\n get time() {\n return this._date && this.timeFormatter.formatTime(this._date);\n }\n\n get isOwn() {\n return this._entry.sender === this._ownMember.userId;\n }\n\n get isContinuation() {\n return this._isContinuation;\n }\n\n get isUnverified() {\n return this._entry.isUnverified;\n }\n\n get isReply() {\n return this._entry.isReply;\n }\n\n _getContent() {\n return this._entry.content;\n }\n\n updatePreviousSibling(prev) {\n super.updatePreviousSibling(prev);\n let isContinuation = false;\n if (prev && prev instanceof BaseMessageTile && prev.sender === this.sender) {\n // timestamp is null for pending events\n const myTimestamp = this._entry.timestamp;\n const otherTimestamp = prev._entry.timestamp;\n // other message was sent less than 5min ago\n isContinuation = (myTimestamp - otherTimestamp) < (5 * 60 * 1000);\n }\n if (isContinuation !== this._isContinuation) {\n this._isContinuation = isContinuation;\n this.emitChange(\"isContinuation\");\n }\n }\n\n updateEntry(entry, param) {\n const action = super.updateEntry(entry, param);\n if (action.shouldUpdate) {\n this._updateReactions();\n }\n this._updateReplyTileIfNeeded(param);\n return action;\n }\n\n _updateReplyTileIfNeeded(param) {\n const replyEntry = this._entry.contextEntry;\n if (replyEntry) {\n // this is an update to contextEntry used for replyPreview\n const action = this._replyTile?.updateEntry(replyEntry, param);\n if (action?.shouldReplace || !this._replyTile) {\n this.disposeTracked(this._replyTile);\n const tileClassForEntry = this._options.tileClassForEntry;\n const ReplyTile = tileClassForEntry(replyEntry, this._options);\n if (ReplyTile) {\n this._replyTile = new ReplyTile(replyEntry, this._options);\n }\n }\n if(action?.shouldUpdate) {\n this._replyTile?.emitChange();\n }\n }\n }\n\n startReply() {\n this._roomVM.startReply(this._entry);\n }\n\n createReplyContent(msgtype, body) {\n return this._entry.createReplyContent(msgtype, body);\n }\n\n redact(reason, log) {\n return this._room.sendRedaction(this._entry.id, reason, log);\n }\n\n get canRedact() {\n return this._powerLevels.canRedactFromSender(this._entry.sender);\n }\n\n get reactions() {\n if (this.shape !== \"redacted\") {\n return this._reactions;\n }\n return null;\n }\n\n get canReact() {\n return this._powerLevels.canSendType(\"m.reaction\");\n }\n\n react(key, log = null) {\n return this.logger.wrapOrRun(log, \"react\", async log => {\n if (!this.canReact) {\n log.set(\"powerlevel_lacking\", true);\n return;\n }\n if (this._entry.haveAnnotation(key)) {\n log.set(\"already_reacted\", true);\n return;\n }\n const redaction = this._entry.pendingAnnotations?.get(key)?.redactionEntry;\n if (redaction && !redaction.pendingEvent.hasStartedSending) {\n log.set(\"abort_redaction\", true);\n await redaction.pendingEvent.abort();\n } else {\n await this._room.sendEvent(\"m.reaction\", this._entry.annotate(key), null, log);\n }\n });\n }\n\n redactReaction(key, log = null) {\n return this.logger.wrapOrRun(log, \"redactReaction\", async log => {\n if (!this._powerLevels.canRedactFromSender(this._ownMember.userId)) {\n log.set(\"powerlevel_lacking\", true);\n return;\n }\n if (!this._entry.haveAnnotation(key)) {\n log.set(\"not_yet_reacted\", true);\n return;\n }\n let entry = this._entry.pendingAnnotations?.get(key)?.annotationEntry;\n if (!entry) {\n entry = await this._timeline.getOwnAnnotationEntry(this._entry.id, key);\n }\n if (entry) {\n await this._room.sendRedaction(entry.id, null, log);\n } else {\n log.set(\"no_reaction\", true);\n }\n });\n }\n\n toggleReaction(key, log = null) {\n return this.logger.wrapOrRun(log, \"toggleReaction\", async log => {\n if (this._entry.haveAnnotation(key)) {\n await this.redactReaction(key, log);\n } else {\n await this.react(key, log);\n }\n });\n }\n\n _updateReactions() {\n const {annotations, pendingAnnotations} = this._entry;\n if (!annotations && !pendingAnnotations) {\n if (this._reactions) {\n this._reactions = null;\n }\n } else {\n if (!this._reactions) {\n this._reactions = new ReactionsViewModel(this);\n }\n this._reactions.update(annotations, pendingAnnotations);\n }\n }\n\n get replyTile() {\n if (!this._entry.contextEventId) {\n return null;\n }\n return this._replyTile;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/*\nThe regex is split into component strings;\nmeaning that any escapes (\\) must also\nbe escaped.\n*/\nconst scheme = \"(?:https|http|ftp):\\\\/\\\\/\";\nconst noSpaceNorPunctuation = \"[^\\\\s.,?!)]\";\nconst hostCharacter = \"[a-zA-Z0-9:.\\\\[\\\\]-]\";\n\n/*\nUsing non-consuming group here to combine two criteria for the last character.\nSee point 1 below.\n*/\nconst host = `${hostCharacter}*(?=${hostCharacter})${noSpaceNorPunctuation}`;\n\n/*\nUse sub groups so we accept just / or #; but if anything comes after it,\nit should not end with punctuation or space.\n*/\nconst pathOrFragment = `(?:[\\\\/#](?:[^\\\\s]*${noSpaceNorPunctuation})?)`;\n\n/*\nThings to keep in mind:\n1. URL must not contain non-ascii characters in host but may contain\n them in path or fragment components.\n https://matrix.org/ - valid\n https://matrix.org - invalid\n2. Do not treat punctuation at the end as a part of the URL (.,?!)\n3. Path/fragment is optional.\n*/\nconst urlRegex = `${scheme}${host}${pathOrFragment}?`;\n\nexport const regex = new RegExp(urlRegex, \"gi\");\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { regex } from \"./regex.js\";\n\n/**\n * Splits text into links and non-links.\n * For each such separated token, callback is called\n * with the token and a boolean passed as argument.\n * The boolean indicates whether the token is a link or not.\n */\nexport function linkify(text: string, callback: (token: string, isLink: boolean) => void): void {\n const matches = text.matchAll(regex);\n let curr = 0;\n for (let match of matches) {\n const precedingText = text.slice(curr, match.index);\n callback(precedingText, false);\n callback(match[0], true);\n const len = match[0].length;\n curr = match.index! + len;\n }\n const remainingText = text.slice(curr);\n callback(remainingText, false);\n}\n\nexport function tests(): any {\n\n class MockCallback {\n result: { type: \"link\" | \"text\", text: string }[];\n\n mockCallback(text: string, isLink: boolean): void {\n if (!text.length) {\n return;\n }\n if (!this.result) {\n this.result = [];\n }\n const type = isLink ? \"link\" : \"text\";\n this.result.push({ type: type, text: text });\n }\n }\n\n function test(assert, input, output): void {\n const m = new MockCallback;\n linkify(input, m.mockCallback.bind(m));\n assert.deepEqual(output, m.result);\n }\n\n function testLink(assert, link, expectFail = false): void {\n const input = link;\n const output = expectFail ? [{ type: \"text\", text: input }] :\n [{ type: \"link\", text: input }];\n test(assert, input, output);\n }\n\n return {\n \"Link with host\": (assert): void => {\n testLink(assert, \"https://matrix.org\");\n },\n\n \"Link with host & path\": (assert): void => {\n testLink(assert, \"https://matrix.org/docs/develop\");\n },\n\n \"Link with host & fragment\": (assert): void => {\n testLink(assert, \"https://matrix.org#test\");\n },\n\n \"Link with host & query\": (assert): void => {\n testLink(assert, \"https://matrix.org/?foo=bar\");\n },\n\n \"Complex link\": (assert): void => {\n const link = \"https://www.foobar.com/url?sa=t&rct=j&q=&esrc=s&source\" +\n \"=web&cd=&cad=rja&uact=8&ved=2ahUKEwjyu7DJ-LHwAhUQyzgGHc\" +\n \"OKA70QFjAAegQIBBAD&url=https%3A%2F%2Fmatrix.org%2Fdocs%\" +\n \"2Fprojects%2Fclient%2Felement%2F&usg=AOvVaw0xpENrPHv_R-\" +\n \"ERkyacR2Bd\";\n testLink(assert, link);\n },\n\n \"Localhost link\": (assert): void => {\n testLink(assert, \"http://localhost\");\n testLink(assert, \"http://localhost:3000\");\n },\n\n \"IPV4 link\": (assert): void => {\n testLink(assert, \"https://192.0.0.1\");\n testLink(assert, \"https://250.123.67.23:5924\");\n },\n\n \"IPV6 link\": (assert): void => {\n testLink(assert, \"http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]\");\n testLink(assert, \"http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:7000\");\n },\n\n \"Missing scheme must not linkify\": (assert): void => {\n testLink(assert, \"matrix.org/foo/bar\", true);\n },\n\n \"Punctuation at end of link must not linkify\": (assert): void => {\n const link = \"https://foo.bar/?nenjil=lal810\";\n const end = \".,? \";\n for (const char of end) {\n const out = [{ type: \"link\", text: link }, { type: \"text\", text: char }];\n test(assert, link + char, out);\n }\n },\n\n \"Link doesn't adopt closing parenthesis\": (assert): void => {\n const link = \"(https://matrix.org)\";\n const out = [{ type: \"text\", text: \"(\" }, { type: \"link\", text: \"https://matrix.org\" }, { type: \"text\", text: \")\" }];\n test(assert, link, out);\n },\n\n \"Unicode in hostname must not linkify\": (assert): void => {\n const link = \"https://foo.bar\\uD83D\\uDE03.com\";\n const out = [{ type: \"link\", text: \"https://foo.bar\" },\n { type: \"text\", text: \"\\uD83D\\uDE03.com\" }];\n test(assert, link, out);\n },\n\n \"Link with unicode only after / must linkify\": (assert): void => {\n testLink(assert, \"https://foo.bar.com/\\uD83D\\uDE03\");\n },\n\n \"Link with unicode after fragment without path must linkify\": (assert): void => {\n testLink(assert, \"https://foo.bar.com#\\uD83D\\uDE03\");\n },\n\n \"Link ends with <\": (assert): void => {\n const link = \"https://matrix.org<\";\n const out = [{ type: \"link\", text: \"https://matrix.org\" }, { type: \"text\", text: \"<\" }];\n test(assert, link, out);\n }\n };\n}\n","import { linkify } from \"./linkify/linkify\";\nimport { getIdentifierColorNumber, avatarInitials } from \"../../../avatar\";\n\n/**\n * Parse text into parts such as newline, links and text.\n * @param {string} body A string to parse into parts\n * @returns {MessageBody} Parsed result\n */\nexport function parsePlainBody(body) {\n const parts = [];\n const lines = body.split(\"\\n\");\n\n // create callback outside of loop\n const linkifyCallback = (text, isLink) => {\n if (isLink) {\n parts.push(new LinkPart(text, [new TextPart(text)]));\n } else {\n parts.push(new TextPart(text));\n }\n };\n\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (line.length) {\n linkify(line, linkifyCallback);\n }\n const isLastLine = i >= (lines.length - 1);\n if (!isLastLine) {\n parts.push(new NewLinePart());\n }\n }\n\n return new MessageBody(body, parts);\n}\n\nexport function stringAsBody(body) {\n return new MessageBody(body, [new TextPart(body)]);\n}\n\nexport class HeaderBlock {\n constructor(level, inlines) {\n this.level = level;\n this.inlines = inlines;\n }\n\n get type() { return \"header\"; }\n}\n\nexport class CodeBlock {\n constructor(language, text) {\n this.language = language;\n this.text = text;\n }\n\n get type() { return \"codeblock\"; }\n}\n\nexport class ListBlock {\n constructor(startOffset, items) {\n this.items = items;\n this.startOffset = startOffset;\n }\n\n get type() { return \"list\"; }\n}\n\nexport class TableBlock {\n constructor(head, body) {\n this.head = head;\n this.body = body;\n }\n\n get type() { return \"table\"; }\n}\n\nexport class RulePart {\n get type() { return \"rule\"; }\n}\n\nexport class NewLinePart {\n get type() { return \"newline\"; }\n}\n\nexport class FormatPart {\n constructor(format, children) {\n this.format = format.toLowerCase();\n this.children = children;\n }\n\n get type() { return \"format\"; }\n}\n\nexport class ImagePart {\n constructor(src, width, height, alt, title) {\n this.src = src;\n this.width = width;\n this.height = height;\n this.alt = alt;\n this.title = title;\n }\n\n get type() { return \"image\"; }\n}\n\nexport class PillPart {\n constructor(id, href, children) {\n this.id = id;\n this.href = href;\n this.children = children;\n }\n\n get type() { return \"pill\"; }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this.id);\n }\n\n get avatarInitials() {\n return avatarInitials(this.id);\n }\n}\n\nexport class LinkPart {\n constructor(url, inlines) {\n this.url = url;\n this.inlines = inlines;\n }\n\n get type() { return \"link\"; }\n}\n\nexport class TextPart {\n constructor(text) {\n this.text = text;\n }\n\n get type() { return \"text\"; }\n}\n\nfunction isBlockquote(part){\n return part.type === \"format\" && part.format === \"blockquote\";\n}\n\nexport class MessageBody {\n constructor(sourceString, parts) {\n this.sourceString = sourceString;\n this.parts = parts;\n }\n\n insertEmote(string) {\n // We want to skip quotes introduced by replies when emoting.\n // We assume that such quotes are not TextParts, because replies\n // must have a formatted body.\n let i = 0;\n for (; i < this.parts.length && isBlockquote(this.parts[i]); i++);\n this.parts.splice(i, 0, new TextPart(string));\n }\n}\n\nexport function tests() {\n\n function test(assert, input, output) {\n assert.deepEqual(parsePlainBody(input), new MessageBody(input, output));\n }\n\n return {\n // Tests for text\n \"Text only\": assert => {\n const input = \"This is a sentence\";\n const output = [new TextPart(input)];\n test(assert, input, output);\n },\n\n \"Text with newline\": assert => {\n const input = \"This is a sentence.\\nThis is another sentence.\";\n const output = [\n new TextPart(\"This is a sentence.\"),\n new NewLinePart(),\n new TextPart(\"This is another sentence.\")\n ];\n test(assert, input, output);\n },\n\n \"Text with newline & trailing newline\": assert => {\n const input = \"This is a sentence.\\nThis is another sentence.\\n\";\n const output = [\n new TextPart(\"This is a sentence.\"),\n new NewLinePart(),\n new TextPart(\"This is another sentence.\"),\n new NewLinePart()\n ];\n test(assert, input, output);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageTile} from \"./BaseMessageTile.js\";\nimport {stringAsBody} from \"../MessageBody.js\";\nimport {createEnum} from \"../../../../../utils/enum\";\n\nexport const BodyFormat = createEnum(\"Plain\", \"Html\");\n\nexport class BaseTextTile extends BaseMessageTile {\n constructor(entry, options) {\n super(entry, options);\n this._messageBody = null;\n this._format = null\n }\n\n get shape() {\n return \"message\";\n }\n\n _parseBody(body) {\n return stringAsBody(body);\n }\n\n _getBodyFormat() {\n return BodyFormat.Plain;\n }\n\n get body() {\n const body = this._getBody();\n const format = this._getBodyFormat();\n // body is a string, so we can check for difference by just\n // doing an equality check\n // Even if the body hasn't changed, but the format has, we need\n // to re-fill our cache.\n if (!this._messageBody || this._messageBody.sourceString !== body || this._format !== format) {\n // body with markup is an array of parts,\n // so we should not recreate it for the same body string,\n // or else the equality check in the binding will always fail.\n // So cache it here.\n this._messageBody = this._parseBody(body, format);\n this._format = format;\n }\n return this._messageBody;\n }\n\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { MessageBody, HeaderBlock, TableBlock, ListBlock, CodeBlock, PillPart, FormatPart, NewLinePart, RulePart, TextPart, LinkPart, ImagePart } from \"./MessageBody.js\"\nimport {linkify} from \"./linkify/linkify\";\n\n/* At the time of writing (Jul 1 2021), Matrix Spec recommends\n * allowing the following HTML tags:\n * font, del, h1, h2, h3, h4, h5, h6, blockquote, p, a, ul, ol, sup, sub, li, b, i, u,\n * strong, em, strike, code, hr, br, div, table, thead, tbody, tr, th, td, caption, pre, span, img\n */\n\n/**\n * Nodes that don't have any properties to them other than their tag.\n * While has `href`, and has `src`, these have... themselves.\n */\nconst basicInline = [\"EM\", \"STRONG\", \"CODE\", \"DEL\", \"SPAN\" ];\nconst basicBlock = [\"DIV\", \"BLOCKQUOTE\"];\nconst safeSchemas = [\"https\", \"http\", \"ftp\", \"mailto\", \"magnet\"].map(name => `${name}://`);\nconst baseUrl = 'https://matrix.to';\nconst linkPrefix = `${baseUrl}/#/`;\n\nclass Deserializer {\n constructor(result, mediaRepository) {\n this.result = result;\n this.mediaRepository = mediaRepository;\n }\n\n parsePillLink(link) {\n if (!link.startsWith(linkPrefix)) {\n return null;\n }\n const contents = link.substring(linkPrefix.length);\n if (contents[0] === '@') {\n return contents;\n }\n return null;\n }\n\n parseLink(node, children) {\n const href = this.result.getAttributeValue(node, \"href\");\n const lcUrl = href?.toLowerCase();\n // urls should be absolute and with a safe schema, as listed in the spec\n if (!lcUrl || !safeSchemas.some(schema => lcUrl.startsWith(schema))) {\n return new FormatPart(\"span\", children);\n }\n const pillId = this.parsePillLink(href);\n if (pillId) {\n return new PillPart(pillId, href, children);\n }\n return new LinkPart(href, children);\n }\n\n parseList(node) {\n const result = this.result;\n let start = null;\n if (result.getNodeElementName(node) === \"OL\") {\n // Will return 1 for, say, '1A', which may not be intended?\n start = parseInt(result.getAttributeValue(node, \"start\")) || 1;\n }\n const items = [];\n for (const child of result.getChildNodes(node)) {\n if (result.getNodeElementName(child) !== \"LI\") {\n continue;\n }\n const item = this.parseAnyNodes(result.getChildNodes(child));\n items.push(item);\n }\n return new ListBlock(start, items);\n }\n\n _ensureElement(node, tag) {\n return node &&\n this.result.isElementNode(node) &&\n this.result.getNodeElementName(node) === tag;\n }\n\n parseCodeBlock(node) {\n const result = this.result;\n let codeNode;\n for (const child of result.getChildNodes(node)) {\n codeNode = child;\n break;\n }\n let language = null;\n if (!this._ensureElement(codeNode, \"CODE\")) {\n return new CodeBlock(language, this.result.getNodeText(node));\n }\n const cl = result.getAttributeValue(codeNode, \"class\") || \"\"\n for (const clname of cl.split(\" \")) {\n if (clname.startsWith(\"language-\") && !clname.startsWith(\"language-_\")) {\n language = clname.substring(9) // \"language-\".length\n break;\n }\n }\n return new CodeBlock(language, this.result.getNodeText(codeNode));\n }\n\n parseImage(node) {\n const result = this.result;\n const src = result.getAttributeValue(node, \"src\") || \"\";\n const url = this.mediaRepository.mxcUrl(src);\n // We just ignore non-mxc `src` attributes.\n if (!url) {\n return null;\n }\n const width = parseInt(result.getAttributeValue(node, \"width\")) || null;\n const height = parseInt(result.getAttributeValue(node, \"height\")) || null;\n const alt = result.getAttributeValue(node, \"alt\");\n const title = result.getAttributeValue(node, \"title\");\n return new ImagePart(url, width, height, alt, title);\n }\n\n parseTableRow(row, tag) {\n const cells = [];\n for (const node of this.result.getChildNodes(row)) {\n if(!this._ensureElement(node, tag)) {\n continue;\n }\n const children = this.result.getChildNodes(node);\n const inlines = this.parseInlineNodes(children);\n cells.push(inlines);\n }\n return cells;\n }\n\n parseTableHead(head) {\n let headRow = null;\n for (const node of this.result.getChildNodes(head)) {\n headRow = node;\n break;\n }\n if (this._ensureElement(headRow, \"TR\")) {\n return this.parseTableRow(headRow, \"TH\");\n }\n return null;\n }\n\n parseTableBody(body) {\n const rows = [];\n for (const node of this.result.getChildNodes(body)) {\n if(!this._ensureElement(node, \"TR\")) {\n continue;\n }\n rows.push(this.parseTableRow(node, \"TD\"));\n }\n return rows;\n }\n\n parseTable(node) {\n // We are only assuming iterable, so convert to arrary for indexing.\n const children = Array.from(this.result.getChildNodes(node));\n let head, body;\n if (this._ensureElement(children[0], \"THEAD\") && this._ensureElement(children[1], \"TBODY\")) {\n head = this.parseTableHead(children[0]);\n body = this.parseTableBody(children[1]);\n } else if (this._ensureElement(children[0], \"TBODY\")) {\n head = null;\n body = this.parseTableBody(children[0]);\n }\n return new TableBlock(head, body);\n }\n\n /** Once a node is known to be an element,\n * attempt to interpret it as an inline element.\n *\n * @returns the inline message part, or null if the element\n * is not inline or not allowed.\n */\n parseInlineElement(node) {\n const result = this.result;\n const tag = result.getNodeElementName(node);\n const children = result.getChildNodes(node);\n switch (tag) {\n case \"A\": {\n const inlines = this.parseInlineNodes(children);\n return this.parseLink(node, inlines);\n }\n case \"BR\":\n return new NewLinePart();\n default: {\n if (!basicInline.includes(tag)) {\n return null;\n }\n const inlines = this.parseInlineNodes(children);\n return new FormatPart(tag, inlines);\n }\n }\n }\n\n /** Attempt to interpret a node as inline.\n *\n * @returns the inline message part, or null if the\n * element is not inline or not allowed.\n */\n parseInlineNode(node) {\n if (this.result.isElementNode(node)) {\n return this.parseInlineElement(node);\n }\n return null;\n }\n\n /** Once a node is known to be an element, attempt\n * to interpret it as a block element.\n *\n * @returns the block message part, or null of the\n * element is not a block or not allowed.\n */\n parseBlockElement(node) {\n const result = this.result;\n const tag = result.getNodeElementName(node);\n const children = result.getChildNodes(node);\n switch (tag) {\n case \"H1\":\n case \"H2\":\n case \"H3\":\n case \"H4\":\n case \"H5\":\n case \"H6\": {\n const inlines = this.parseInlineNodes(children);\n return new HeaderBlock(parseInt(tag[1]), inlines)\n }\n case \"UL\":\n case \"OL\":\n return this.parseList(node);\n case \"PRE\":\n return this.parseCodeBlock(node);\n case \"HR\":\n return new RulePart();\n case \"IMG\":\n return this.parseImage(node);\n case \"P\": {\n const inlines = this.parseInlineNodes(children);\n return new FormatPart(tag, inlines);\n }\n case \"TABLE\":\n return this.parseTable(node);\n default: {\n if (!basicBlock.includes(tag)) {\n return null;\n }\n const blocks = this.parseAnyNodes(children);\n return new FormatPart(tag, blocks);\n }\n }\n }\n\n /** Attempt to parse a node as a block.\n *\n * @return the block message part, or null if the node\n * is not a block element.\n */\n parseBlockNode(node) {\n if (this.result.isElementNode(node)) {\n return this.parseBlockElement(node);\n }\n return null;\n }\n\n _parseTextParts(node, into) {\n if(!this.result.isTextNode(node)) {\n return false;\n }\n\n // XXX pretty much identical to `MessageBody`'s.\n const linkifyCallback = (text, isLink) => {\n if (isLink) {\n into.push(new LinkPart(text, [new TextPart(text)]));\n } else {\n into.push(new TextPart(text));\n }\n };\n linkify(this.result.getNodeText(node), linkifyCallback);\n return true;\n }\n\n _isAllowedNode(node) {\n return !this._ensureElement(node, \"MX-REPLY\");\n }\n\n _parseInlineNodes(nodes, into) {\n for (const htmlNode of nodes) {\n if (this._parseTextParts(htmlNode, into)) {\n // This was a text node, and we already\n // dumped its parts into our list.\n continue;\n }\n const node = this.parseInlineNode(htmlNode);\n if (node) {\n into.push(node);\n continue;\n }\n // Node is either block or unrecognized. In\n // both cases, just move on to its children.\n if (this._isAllowedNode(htmlNode)) {\n this._parseInlineNodes(this.result.getChildNodes(htmlNode), into);\n }\n }\n }\n\n parseInlineNodes(nodes) {\n const into = [];\n this._parseInlineNodes(nodes, into);\n return into;\n }\n\n // XXX very similar to `_parseInlineNodes`.\n _parseAnyNodes(nodes, into) {\n for (const htmlNode of nodes) {\n if (this._parseTextParts(htmlNode, into)) {\n // This was a text node, and we already\n // dumped its parts into our list.\n continue;\n }\n const node = this.parseInlineNode(htmlNode) || this.parseBlockNode(htmlNode);\n if (node) {\n into.push(node);\n continue;\n }\n // Node is unrecognized. Just move on to its children.\n if (this._isAllowedNode(htmlNode)) {\n this._parseAnyNodes(this.result.getChildNodes(htmlNode), into);\n }\n }\n }\n\n parseAnyNodes(nodes) {\n const into = [];\n this._parseAnyNodes(nodes, into);\n return into;\n }\n}\n\nexport function parseHTMLBody(platform, mediaRepository, html) {\n const parseResult = platform.parseHTML(html);\n const deserializer = new Deserializer(parseResult, mediaRepository);\n const parts = deserializer.parseAnyNodes(parseResult.rootNodes);\n return new MessageBody(html, parts);\n}\n\n\nexport async function tests() {\n // don't import node-html-parser until it's safe to assume we're actually in a unit test,\n // as this is a devDependency\n const nodeHtmlParser = await import(\"node-html-parser\");\n const {parse} = nodeHtmlParser.default;\n\n class HTMLParseResult {\n constructor(bodyNode) {\n this._bodyNode = bodyNode;\n }\n\n get rootNodes() {\n return this._bodyNode.childNodes;\n }\n\n getChildNodes(node) {\n return node.childNodes;\n }\n\n getAttributeNames(node) {\n return node.getAttributeNames();\n }\n\n getAttributeValue(node, attr) {\n return node.getAttribute(attr);\n }\n\n isTextNode(node) {\n return !node.tagName;\n }\n\n getNodeText(node) {\n return node.text;\n }\n\n isElementNode(node) {\n return !!node.tagName;\n }\n\n getNodeElementName(node) {\n return node.tagName;\n }\n }\n\n const platform = {\n parseHTML: (html) => new HTMLParseResult(parse(html))\n };\n\n function test(assert, input, output) {\n assert.deepEqual(parseHTMLBody(platform, null, input), new MessageBody(input, output));\n }\n\n return {\n \"Text only\": assert => {\n const input = \"This is a sentence\";\n const output = [new TextPart(input)];\n test(assert, input, output);\n },\n \"Text with inline code format\": assert => {\n const input = \"Here's some code!\";\n const output = [\n new TextPart(\"Here's \"),\n new FormatPart(\"em\", [new TextPart(\"some\")]),\n new TextPart(\" \"),\n new FormatPart(\"code\", [new TextPart(\"code\")]),\n new TextPart(\"!\")\n ];\n test(assert, input, output);\n },\n \"Text with ordered list with no attributes\": assert => {\n const input = \"
  1. Lorem
  2. Ipsum
\";\n const output = [\n new ListBlock(1, [\n [ new TextPart(\"Lorem\") ],\n [ new TextPart(\"Ipsum\") ]\n ])\n ];\n test(assert, input, output);\n },\n \"Text with ordered list starting at 3\": assert => {\n const input = '
  1. Lorem
  2. Ipsum
';\n const output = [\n new ListBlock(3, [\n [ new TextPart(\"Lorem\") ],\n [ new TextPart(\"Ipsum\") ]\n ])\n ];\n test(assert, input, output);\n },\n \"Text with unordered list\": assert => {\n const input = '
  • Lorem
  • Ipsum
';\n const output = [\n new ListBlock(null, [\n [ new TextPart(\"Lorem\") ],\n [ new TextPart(\"Ipsum\") ]\n ])\n ];\n test(assert, input, output);\n },\n \"Auto-closed tags\": assert => {\n const input = '

hello

world

';\n const output = [\n new FormatPart(\"p\", [new TextPart(\"hello\")]),\n new FormatPart(\"p\", [new TextPart(\"world\")])\n ];\n test(assert, input, output);\n },\n \"Block elements ignored inside inline elements\": assert => {\n const input = '

Hello

';\n const output = [\n new FormatPart(\"span\", [new FormatPart(\"code\", [new TextPart(\"Hello\")])])\n ];\n test(assert, input, output);\n },\n \"Unknown tags are ignored, but their children are kept\": assert => {\n const input = 'Hello
World
';\n const output = [\n new FormatPart(\"span\", [\n new FormatPart(\"code\", [new TextPart(\"Hello\")]),\n new FormatPart(\"em\", [new TextPart(\"World\")])\n ])\n ];\n test(assert, input, output);\n },\n \"Unknown and invalid attributes are stripped\": assert => {\n const input = 'Hello';\n const output = [\n new FormatPart(\"em\", [new TextPart(\"Hello\")])\n ];\n test(assert, input, output);\n },\n \"Text with code block but no tag\": assert => {\n const code = 'main :: IO ()\\nmain = putStrLn \"Hello\"'\n const input = `
${code}
`;\n const output = [\n new CodeBlock(null, code)\n ];\n test(assert, input, output);\n },\n \"Text with code block and 'unsupported' tag\": assert => {\n const code = 'Hello, world'\n const input = `
${code}
`;\n const output = [\n new CodeBlock(null, code)\n ];\n test(assert, input, output);\n },\n \"Reply fallback is always stripped\": assert => {\n const input = 'Hello, World!';\n const output = [\n new TextPart('Hello, '),\n new FormatPart(\"em\", []),\n new TextPart('!'),\n ];\n assert.deepEqual(parseHTMLBody(platform, null, input), new MessageBody(input, output));\n }\n /* Doesnt work: HTML library doesn't handle
 properly.\n        \"Text with code block\": assert => {\n            const code = 'main :: IO ()\\nmain = putStrLn \"Hello\"'\n            const input = `
${code}
`;\n const output = [\n new CodeBlock(null, code)\n ];\n test(assert, input, output);\n }\n */\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseTextTile, BodyFormat} from \"./BaseTextTile.js\";\nimport {parsePlainBody} from \"../MessageBody.js\";\nimport {parseHTMLBody} from \"../deserialize.js\";\n\nexport class TextTile extends BaseTextTile {\n _getContentString(key) {\n return this._getContent()?.[key] || \"\";\n }\n\n _getPlainBody() {\n return this._getContentString(\"body\");\n }\n\n _getFormattedBody() {\n return this._getContentString(\"formatted_body\");\n }\n\n _getBody() {\n if (this._getBodyFormat() === BodyFormat.Html) {\n return this._getFormattedBody();\n } else {\n return this._getPlainBody();\n }\n }\n\n _getBodyFormat() {\n if (this._getContent()?.format === \"org.matrix.custom.html\") {\n return BodyFormat.Html;\n } else {\n return BodyFormat.Plain;\n }\n }\n\n _parseBody(body, format) {\n let messageBody;\n if (format === BodyFormat.Html) {\n messageBody = parseHTMLBody(this.platform, this._mediaRepository, body);\n } else {\n messageBody = parsePlainBody(body);\n }\n if (this._getContent()?.msgtype === \"m.emote\") {\n messageBody.insertEmote(`* ${this.displayName} `);\n }\n return messageBody;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageTile} from \"./BaseMessageTile.js\";\n\nexport class RedactedTile extends BaseMessageTile {\n get shape() {\n return \"redacted\";\n }\n\n get description() {\n const {redactionReason} = this._entry;\n if (this.isRedacting) {\n if (redactionReason) {\n return this.i18n`This message is being deleted (${redactionReason})…`;\n } else {\n return this.i18n`This message is being deleted…`;\n }\n } else {\n if (redactionReason) {\n return this.i18n`This message has been deleted (${redactionReason}).`;\n } else {\n return this.i18n`This message has been deleted.`;\n }\n }\n }\n\n get isRedacting() {\n return this._entry.isRedacting;\n }\n \n /** override parent property to disable redacting, even if still pending */\n get canRedact() {\n return false;\n }\n\n abortPendingRedaction() {\n return this._entry.abortPendingRedaction();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageTile} from \"./BaseMessageTile.js\";\nimport {SendStatus} from \"../../../../../matrix/room/sending/PendingEvent.js\";\nconst MAX_HEIGHT = 300;\nconst MAX_WIDTH = 400;\n\nexport class BaseMediaTile extends BaseMessageTile {\n constructor(entry, options) {\n super(entry, options);\n this._decryptedThumbnail = null;\n this._decryptedFile = null;\n this._isVisible = false;\n this._error = null;\n this._downloading = false;\n this._downloadError = null;\n }\n\n async downloadMedia() {\n if (this._downloading || this.isPending) {\n return;\n }\n const content = this._getContent();\n const filename = content.body;\n this._downloading = true;\n this.emitChange(\"status\");\n let blob;\n try {\n blob = await this._mediaRepository.downloadAttachment(content);\n this.platform.saveFileAs(blob, filename);\n } catch (err) {\n this._downloadError = err;\n } finally {\n blob?.dispose();\n this._downloading = false;\n }\n this.emitChange(\"status\");\n }\n\n get isUploading() {\n return this.isPending && this._entry.pendingEvent.status === SendStatus.UploadingAttachments;\n }\n\n get uploadPercentage() {\n const {pendingEvent} = this._entry;\n return pendingEvent && Math.round((pendingEvent.attachmentsSentBytes / pendingEvent.attachmentsTotalBytes) * 100);\n }\n\n get status() {\n const {pendingEvent} = this._entry;\n switch (pendingEvent?.status) {\n case SendStatus.Waiting:\n return this.i18n`Waiting…`;\n case SendStatus.EncryptingAttachments:\n case SendStatus.Encrypting:\n return this.i18n`Encrypting…`;\n case SendStatus.UploadingAttachments:\n return this.i18n`Uploading…`;\n case SendStatus.Sending:\n return this.i18n`Sending…`;\n case SendStatus.Error:\n return this.i18n`Error: ${pendingEvent.error.message}`;\n default:\n if (this._downloadError) {\n return `Download failed`;\n }\n if (this._downloading) {\n return this.i18n`Downloading…`;\n }\n return \"\";\n }\n }\n\n get thumbnailUrl() {\n if (!this._isVisible) {\n return \"\";\n }\n if (this._decryptedThumbnail) {\n return this._decryptedThumbnail.url;\n } else {\n const thumbnailMxc = this._getContent().info?.thumbnail_url;\n if (thumbnailMxc) {\n return this._mediaRepository.mxcUrlThumbnail(thumbnailMxc, this.width, this.height, \"scale\");\n }\n }\n if (this._entry.isPending) {\n const attachment = this._entry.pendingEvent.getAttachment(\"info.thumbnail_url\");\n return attachment && attachment.localPreview.url;\n }\n if (this._isMainResourceImage()) {\n if (this._decryptedFile) {\n return this._decryptedFile.url;\n } else {\n const mxcUrl = this._getContent()?.url;\n if (typeof mxcUrl === \"string\") {\n return this._mediaRepository.mxcUrlThumbnail(mxcUrl, this.width, this.height, \"scale\");\n }\n }\n }\n return \"\";\n }\n\n notifyVisible() {\n super.notifyVisible();\n this._isVisible = true;\n this.emitChange(\"thumbnailUrl\");\n if (!this.isPending) {\n this._tryLoadEncryptedThumbnail();\n }\n }\n\n get width() {\n const info = this._getContent()?.info;\n return Math.round(info?.w * this._scaleFactor());\n }\n\n get height() {\n const info = this._getContent()?.info;\n return Math.round(info?.h * this._scaleFactor());\n }\n\n get mimeType() {\n const info = this._getContent()?.info;\n return info?.mimetype;\n }\n\n get label() {\n return this._getContent().body;\n }\n\n get error() {\n if (this._error) {\n return `Could not load media: ${this._error.message}`;\n }\n return null;\n }\n\n setViewError(err) {\n this._error = err;\n this.emitChange(\"error\");\n }\n\n async _loadEncryptedFile(file) {\n const blob = await this._mediaRepository.downloadEncryptedFile(file, true);\n if (this.isDisposed) {\n blob.dispose();\n return;\n }\n return this.track(blob);\n }\n\n async _tryLoadEncryptedThumbnail() {\n try {\n const thumbnailFile = this._getContent().info?.thumbnail_file;\n const file = this._getContent().file;\n if (thumbnailFile) {\n this._decryptedThumbnail = await this._loadEncryptedFile(thumbnailFile);\n this.emitChange(\"thumbnailUrl\");\n } else if (file && this._isMainResourceImage()) { // is the main resource an image? then try that for a thumbnail\n this._decryptedFile = await this._loadEncryptedFile(file);\n this.emitChange(\"thumbnailUrl\");\n }\n } catch (err) {\n this._error = err;\n this.emitChange(\"error\");\n }\n }\n\n _scaleFactor() {\n const info = this._getContent()?.info;\n const scaleHeightFactor = MAX_HEIGHT / info?.h;\n const scaleWidthFactor = MAX_WIDTH / info?.w;\n // take the smallest scale factor, to respect all constraints\n // we should not upscale images, so limit scale factor to 1 upwards\n return Math.min(scaleWidthFactor, scaleHeightFactor, 1);\n }\n\n _isMainResourceImage() {\n return true; // overwritten in VideoTile\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMediaTile} from \"./BaseMediaTile.js\";\n\nexport class ImageTile extends BaseMediaTile {\n constructor(entry, options) {\n super(entry, options);\n this._lightboxUrl = this.urlRouter.urlForSegments([\n // ensure the right room is active if in grid view\n this.navigation.segment(\"room\", this._room.id),\n this.navigation.segment(\"lightbox\", this._entry.id)\n ]);\n }\n\n get lightboxUrl() {\n if (!this.isPending) {\n return this._lightboxUrl;\n }\n return \"\";\n }\n\n get shape() {\n return \"image\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMediaTile} from \"./BaseMediaTile.js\";\n\nexport class VideoTile extends BaseMediaTile {\n async loadVideo() {\n const file = this._getContent().file;\n if (file && !this._decryptedFile) {\n this._decryptedFile = await this._loadEncryptedFile(file);\n this.emitChange(\"videoUrl\");\n }\n }\n\n get videoUrl() {\n if (this._decryptedFile) {\n return this._decryptedFile.url;\n }\n const mxcUrl = this._getContent()?.url;\n if (typeof mxcUrl === \"string\") {\n return this._mediaRepository.mxcUrl(mxcUrl);\n }\n return \"\";\n }\n\n get shape() {\n return \"video\";\n }\n\n _isMainResourceImage() {\n return false;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n\nexport function formatSize(size: number, decimals: number = 2): string {\n if (Number.isSafeInteger(size)) {\n const base = Math.min(3, Math.floor(Math.log(size) / Math.log(1024)));\n const formattedSize = Math.round(size / Math.pow(1024, base)).toFixed(decimals);\n switch (base) {\n case 0: return `${formattedSize} bytes`;\n case 1: return `${formattedSize} KB`;\n case 2: return `${formattedSize} MB`;\n case 3: return `${formattedSize} GB`;\n }\n }\n return \"\";\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageTile} from \"./BaseMessageTile.js\";\nimport {formatSize} from \"../../../../../utils/formatSize\";\nimport {SendStatus} from \"../../../../../matrix/room/sending/PendingEvent.js\";\n\nexport class FileTile extends BaseMessageTile {\n constructor(entry, options) {\n super(entry, options);\n this._downloadError = null;\n this._downloading = false;\n }\n\n async download() {\n if (this._downloading || this.isPending) {\n return;\n }\n const content = this._getContent();\n const filename = content.body;\n this._downloading = true;\n this.emitChange(\"label\");\n let blob;\n try {\n blob = await this._mediaRepository.downloadAttachment(content);\n this.platform.saveFileAs(blob, filename);\n } catch (err) {\n this._downloadError = err;\n } finally {\n blob?.dispose();\n this._downloading = false;\n }\n this.emitChange(\"label\");\n }\n\n get label() {\n if (this._downloadError) {\n return `Could not download file: ${this._downloadError.message}`;\n }\n const content = this._getContent();\n const filename = content.body;\n\n if (this._entry.isPending) {\n const {pendingEvent} = this._entry;\n switch (pendingEvent?.status) {\n case SendStatus.Waiting:\n return this.i18n`Waiting to send ${filename}…`;\n case SendStatus.EncryptingAttachments:\n case SendStatus.Encrypting:\n return this.i18n`Encrypting ${filename}…`;\n case SendStatus.UploadingAttachments:{\n const percent = Math.round((pendingEvent.attachmentsSentBytes / pendingEvent.attachmentsTotalBytes) * 100);\n return this.i18n`Uploading ${filename}: ${percent}%`;\n }\n case SendStatus.Sending:\n case SendStatus.Sent:\n return this.i18n`Sending ${filename}…`;\n case SendStatus.Error:\n return this.i18n`Error: could not send ${filename}: ${pendingEvent.error.message}`;\n default:\n return `Unknown send status for ${filename}`;\n }\n } else {\n const size = formatSize(this._getContent().info?.size);\n if (this._downloading) {\n return this.i18n`Downloading ${filename} (${size})…`;\n } else {\n return this.i18n`Download ${filename} (${size})`;\n } \n }\n }\n\n get shape() {\n return \"file\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageTile} from \"./BaseMessageTile.js\";\n\nexport class LocationTile extends BaseMessageTile {\n get shape() {\n return \"location\";\n }\n\n get mapsLink() {\n try {\n const url = new URL(this._getContent().geo_uri);\n if (url.protocol !== \"geo:\") {\n return \"\";\n }\n const [locationStr, ...namedParams] = url.pathname.split(\";\");\n const [latStr, longStr] = locationStr.split(\",\");\n const lat = parseFloat(latStr);\n const long = parseFloat(longStr);\n let uncertainty;\n for (const namedParam of namedParams) {\n const [name, value] = namedParam.split(\"=\");\n if (name === \"u\") {\n uncertainty = parseFloat(value);\n }\n }\n if (this.platform.isIOS) {\n return `http://maps.apple.com/?ll=${lat},${long}`;\n } else {\n let uri = `geo:${lat},${long}`;\n if (uncertainty) {\n uri = uri + `;u=${uncertainty}`;\n }\n return uri;\n }\n } catch {\n return \"\";\n }\n }\n\n get label() {\n return this.i18n`${this.displayName} sent their location`;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SimpleTile} from \"./SimpleTile\";\n\nexport class RoomNameTile extends SimpleTile {\n \n get shape() {\n return \"announcement\";\n }\n\n get announcement() {\n const content = this._entry.content;\n return `${this._entry.displayName || this._entry.sender} named the room \"${content?.name}\"`\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SimpleTile} from \"./SimpleTile\";\n\nexport class RoomMemberTile extends SimpleTile {\n\n get shape() {\n return \"announcement\";\n }\n\n get announcement() {\n const {sender, content, prevContent, stateKey} = this._entry;\n const senderName = this._entry.displayName || sender;\n const targetName = sender === stateKey ? senderName : (this._entry.content?.displayname || stateKey);\n const membership = content && content.membership;\n const prevMembership = prevContent && prevContent.membership;\n\n if (prevMembership === \"join\" && membership === \"join\") {\n if (content.avatar_url !== prevContent.avatar_url) {\n return `${senderName} changed their avatar`; \n } else if (content.displayname !== prevContent.displayname) {\n if (!content.displayname) {\n return `${stateKey} removed their name (${prevContent.displayname})`;\n }\n return `${prevContent.displayname ?? stateKey} changed their name to ${content.displayname}`; \n }\n } else if (membership === \"join\") {\n return `${targetName} joined the room`;\n } else if (membership === \"invite\") {\n return `${targetName} was invited to the room by ${senderName}`;\n } else if (prevMembership === \"invite\") {\n if (membership === \"join\") {\n return `${targetName} accepted the invitation to join the room`;\n } else if (membership === \"leave\") {\n return `${targetName} declined the invitation to join the room`;\n }\n } else if (membership === \"leave\") {\n if (stateKey === sender) {\n return `${targetName} left the room`;\n } else {\n const reason = content.reason;\n return `${targetName} was kicked from the room by ${senderName}${reason ? `: ${reason}` : \"\"}`;\n }\n } else if (membership === \"ban\") {\n return `${targetName} was banned from the room by ${senderName}`;\n }\n \n return `${sender} membership changed to ${content.membership}`;\n }\n}\n\nexport function tests() {\n return {\n \"user removes display name\": (assert) => {\n const tile = new RoomMemberTile(\n {\n prevContent: {displayname: \"foo\", membership: \"join\"},\n content: {membership: \"join\"},\n stateKey: \"foo@bar.com\",\n },\n {}\n );\n assert.strictEqual(tile.announcement, \"foo@bar.com removed their name (foo)\");\n },\n \"user without display name sets a new display name\": (assert) => {\n const tile = new RoomMemberTile(\n {\n prevContent: {membership: \"join\"},\n content: {displayname: \"foo\", membership: \"join\" },\n stateKey: \"foo@bar.com\",\n },\n {}\n );\n assert.strictEqual(tile.announcement, \"foo@bar.com changed their name to foo\");\n },\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseTextTile} from \"./BaseTextTile.js\";\nimport {UpdateAction} from \"../UpdateAction.js\";\n\nexport class EncryptedEventTile extends BaseTextTile {\n updateEntry(entry, params) {\n const parentResult = super.updateEntry(entry, params);\n // event got decrypted, recreate the tile and replace this one with it\n if (entry.eventType !== \"m.room.encrypted\") {\n // the \"shape\" parameter trigger tile recreation in TimelineView\n return UpdateAction.Replace(\"shape\");\n } else {\n return parentResult;\n }\n }\n\n get shape() {\n return \"message-status\"\n }\n\n _getBody() {\n const decryptionError = this._entry.decryptionError;\n const code = decryptionError?.code;\n let string;\n if (code === \"MEGOLM_NO_SESSION\") {\n string = this.i18n`The sender hasn't sent us the key for this message yet.`;\n } else {\n string = decryptionError?.message || this.i18n`Could not decrypt message because of unknown reason.`;\n }\n return string;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SimpleTile} from \"./SimpleTile\";\n\nexport class EncryptionEnabledTile extends SimpleTile {\n get shape() {\n return \"announcement\";\n }\n\n get announcement() {\n const senderName = this._entry.displayName || this._entry.sender;\n return this.i18n`${senderName} has enabled end-to-end encryption`;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageTile} from \"./BaseMessageTile.js\";\n\nexport class MissingAttachmentTile extends BaseMessageTile {\n get shape() {\n return \"missing-attachment\"\n }\n\n get label() {\n const name = this._getContent().body;\n const msgtype = this._getContent().msgtype;\n if (msgtype === \"m.image\") {\n return this.i18n`The image ${name} wasn't fully sent previously and could not be recovered.`;\n } else {\n return this.i18n`The file ${name} wasn't fully sent previously and could not be recovered.`;\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SimpleTile} from \"./SimpleTile\";\nimport {ViewModel} from \"../../../../ViewModel\";\nimport {LocalMedia} from \"../../../../../matrix/calls/LocalMedia\";\nimport {CallType} from \"../../../../../matrix/calls/callEventTypes\";\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../../../avatar\";\n\n// TODO: timeline entries for state events with the same state key and type\n// should also update previous entries in the timeline, so we can update the name of the call, whether it is terminated, etc ...\n\n// alternatively, we could just subscribe to the GroupCall and spontanously emit an update when it updates\n\nexport class CallTile extends SimpleTile {\n constructor(entry, options) {\n super(entry, options);\n const calls = this.getOption(\"session\").callHandler.calls;\n this._callSubscription = undefined;\n this._memberSizeSubscription = undefined;\n const call = calls.get(this._entry.stateKey);\n if (call && !call.isTerminated) {\n this._call = call;\n this.memberViewModels = this._setupMembersList(this._call);\n this._callSubscription = this.track(this._call.disposableOn(\"change\", () => {\n this._onCallUpdate();\n }));\n this._memberSizeSubscription = this.track(this._call.members.observeSize().subscribe(() => {\n this.emitChange(\"memberCount\");\n }));\n this._onCallUpdate();\n }\n }\n\n _onCallUpdate() {\n // unsubscribe when terminated\n if (this._call.isTerminated) {\n this._durationInterval = this.disposeTracked(this._durationInterval);\n this._callSubscription = this.disposeTracked(this._callSubscription);\n this._call = undefined;\n } else if (!this._durationInterval) {\n this._durationInterval = this.track(this.platform.clock.createInterval(() => {\n this.emitChange(\"duration\");\n }, 1000));\n }\n this.emitChange();\n }\n\n _setupMembersList(call) {\n return call.members.mapValues(\n (member, emitChange) => new MemberAvatarViewModel(this.childOptions({\n member,\n emitChange,\n mediaRepository: this.getOption(\"room\").mediaRepository\n })),\n ).sortValues((a, b) => a.userId.localeCompare(b.userId));\n }\n\n get memberCount() {\n // TODO: emit updates for this property\n if (this._call) {\n return this._call.members.size;\n }\n return 0;\n }\n\n get confId() {\n return this._entry.stateKey;\n }\n\n get duration() {\n if (this._call && this._call.duration) {\n return this.timeFormatter.formatDuration(this._call.duration);\n } else {\n return \"\";\n }\n }\n \n get shape() {\n return \"call\";\n }\n\n get canJoin() {\n return this._call && !this._call.hasJoined && !this._call.usesFoci;\n }\n\n get canLeave() {\n return this._call && this._call.hasJoined;\n }\n\n get title() {\n if (this._call) {\n if (this.type === CallType.Video) {\n return `${this.displayName} started a video call`;\n } else {\n return `${this.displayName} started a voice call`;\n }\n } else {\n if (this.type === CallType.Video) {\n return `Video call ended`;\n } else {\n return `Voice call ended`;\n }\n }\n }\n\n get typeLabel() {\n if (this._call && this._call.usesFoci) {\n return `This call uses a stream-forwarding unit, which isn't supported yet, so you can't join this call.`;\n }\n if (this.type === CallType.Video) {\n return `Video call`;\n } else {\n return `Voice call`;\n }\n }\n\n get type() {\n return this._entry.event.content[\"m.type\"];\n }\n\n async join() {\n await this.logAndCatch(\"CallTile.join\", async log => {\n if (this.canJoin) {\n const stream = await this.platform.mediaDevices.getMediaTracks(false, true);\n const localMedia = new LocalMedia().withUserMedia(stream);\n await this._call.join(localMedia, log);\n }\n });\n }\n\n async leave() {\n await this.logAndCatch(\"CallTile.leave\", async log => {\n if (this.canLeave) {\n await this._call.leave(log);\n }\n });\n }\n}\n\nclass MemberAvatarViewModel extends ViewModel {\n get _member() {\n return this.getOption(\"member\");\n }\n\n get userId() {\n return this._member.userId;\n }\n\n get avatarLetter() {\n return avatarInitials(this._member.member.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._member.userId);\n }\n\n avatarUrl(size) {\n const {avatarUrl} = this._member.member;\n const mediaRepository = this.getOption(\"mediaRepository\");\n return getAvatarHttpUrl(avatarUrl, size, this.platform, mediaRepository);\n }\n\n get avatarTitle() {\n return this._member.member.name;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SASRequest} from \"../../../../../matrix/verification/SAS/SASRequest\";\nimport {TileShape} from \"./ITile\";\nimport {SimpleTile} from \"./SimpleTile\";\nimport {UpdateAction} from \"../UpdateAction.js\"\nimport {VerificationEventType} from \"../../../../../matrix/verification/SAS/channel/types\";\nimport type {EventEntry} from \"../../../../../matrix/room/timeline/entries/EventEntry.js\";\nimport type {Options} from \"./SimpleTile\";\n\nexport const enum Status {\n Ready,\n InProgress,\n Completed,\n Cancelled,\n};\n\nexport class VerificationTile extends SimpleTile {\n private request: SASRequest;\n public isCancelledByUs: boolean;\n public status: Status = Status.Ready;\n\n constructor(entry: EventEntry, options: Options) {\n super(entry, options);\n this.request = new SASRequest(this.lowerEntry);\n // Calculate status based on available context-for entries\n // Needed so that tiles reflect their final status when\n // events are loaded from storage i.e after a reload.\n this.updateStatusFromAvailableContextForEntries();\n }\n\n get shape(): TileShape {\n return TileShape.Verification;\n }\n\n get description(): string {\n return this.i18n`${this.sender} wants to verify`;\n }\n\n accept(): void {\n const crossSigning = this.getOption(\"session\").crossSigning.get();\n crossSigning.receivedSASVerifications.set(this.eventId, this.request);\n this.openVerificationPanel(this.eventId);\n }\n\n async reject(): Promise {\n await this.logAndCatch(\"VerificationTile.reject\", async (log) => {\n const crossSigning = this.getOption(\"session\").crossSigning.get();\n await this.request.reject(crossSigning, this._room, log);\n });\n }\n\n private openVerificationPanel(eventId: string): void {\n let path = this.navigation.path.until(\"room\");\n path = path.with(this.navigation.segment(\"right-panel\", true))!;\n path = path.with(this.navigation.segment(\"verification\", eventId))!;\n this.navigation.applyPath(path);\n }\n\n updateEntry(entry: EventEntry, param: any) {\n if (param === \"context-added\") {\n /**\n * We received a new contextForEntry, maybe it tells us that\n * this request was cancelled or that the verification is completed?\n * Let's check.\n */\n if (this.updateStatusFromAvailableContextForEntries()) {\n return UpdateAction.Update(param);\n }\n return UpdateAction.Nothing();\n } \n return super.updateEntry(entry, param);\n }\n\n private updateStatusFromAvailableContextForEntries(): boolean {\n let needsUpdate = false;\n for (const e of this.lowerEntry.contextForEntries ?? []) {\n switch (e.eventType) {\n case VerificationEventType.Cancel:\n this.status = Status.Cancelled;\n this.isCancelledByUs = e.sender === this.getOption(\"session\").userId;\n return true;\n case VerificationEventType.Done:\n this.status = Status.Completed;\n return true;\n default:\n this.status = Status.InProgress;\n needsUpdate = true;\n }\n }\n return needsUpdate;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {GapTile} from \"./GapTile.js\";\nimport {TextTile} from \"./TextTile.js\";\nimport {RedactedTile} from \"./RedactedTile.js\";\nimport {ImageTile} from \"./ImageTile.js\";\nimport {VideoTile} from \"./VideoTile.js\";\nimport {FileTile} from \"./FileTile.js\";\nimport {LocationTile} from \"./LocationTile.js\";\nimport {RoomNameTile} from \"./RoomNameTile.js\";\nimport {RoomMemberTile} from \"./RoomMemberTile.js\";\nimport {EncryptedEventTile} from \"./EncryptedEventTile.js\";\nimport {EncryptionEnabledTile} from \"./EncryptionEnabledTile.js\";\nimport {MissingAttachmentTile} from \"./MissingAttachmentTile.js\";\nimport {CallTile} from \"./CallTile.js\";\nimport {VerificationTile} from \"./VerificationTile.js\";\n\nimport type {ITile, TileShape} from \"./ITile\";\nimport type {Room} from \"../../../../../matrix/room/Room\";\nimport type {Session} from \"../../../../../matrix/Session\";\nimport type {Timeline} from \"../../../../../matrix/room/timeline/Timeline\";\nimport type {FragmentBoundaryEntry} from \"../../../../../matrix/room/timeline/entries/FragmentBoundaryEntry\";\nimport type {EventEntry} from \"../../../../../matrix/room/timeline/entries/EventEntry\";\nimport type {PendingEventEntry} from \"../../../../../matrix/room/timeline/entries/PendingEventEntry\";\nimport type {Options as ViewModelOptions} from \"../../../../ViewModel\";\n\nexport type TimelineEntry = FragmentBoundaryEntry | EventEntry | PendingEventEntry;\nexport type TileClassForEntryFn = (entry: TimelineEntry) => TileConstructor | undefined;\nexport type Options = ViewModelOptions & {\n session: Session,\n room: Room,\n timeline: Timeline\n tileClassForEntry: TileClassForEntryFn;\n};\nexport type TileConstructor = new (entry: TimelineEntry, options: Options) => ITile;\n\nexport function tileClassForEntry(entry: TimelineEntry, options: Options): TileConstructor | undefined {\n if (entry.isGap) {\n return GapTile;\n } else if (entry.isPending && entry.pendingEvent.isMissingAttachments) {\n return MissingAttachmentTile;\n } else if (entry.eventType) {\n switch (entry.eventType) {\n case \"m.room.message\": {\n if (entry.isRedacted) {\n return RedactedTile;\n }\n const content = entry.content;\n const msgtype = content && content.msgtype;\n switch (msgtype) {\n case \"m.text\":\n case \"m.notice\":\n case \"m.emote\":\n return TextTile;\n case \"m.image\":\n return ImageTile;\n case \"m.video\":\n return VideoTile;\n case \"m.file\":\n return FileTile;\n case \"m.location\":\n return LocationTile;\n case \"m.key.verification.request\":\n const isCrossSigningDisabled = !options.session.features.crossSigning;\n const userId = options.session.userId;\n if (isCrossSigningDisabled || entry.sender === userId) {\n return undefined;\n }\n return VerificationTile as unknown as TileConstructor;\n default:\n // unknown msgtype not rendered\n return undefined;\n }\n }\n case \"m.room.name\":\n return RoomNameTile;\n case \"m.room.member\":\n return RoomMemberTile;\n case \"m.room.encrypted\":\n if (entry.isRedacted) {\n return RedactedTile;\n }\n return EncryptedEventTile;\n case \"m.room.encryption\":\n return EncryptionEnabledTile;\n case \"org.matrix.msc3401.call\": {\n // if prevContent is present, it's an update to a call event, which we don't render\n // as the original event is updated through the call object which receive state event updates\n if (options.features.calls && entry.stateKey && !entry.prevContent) {\n return CallTile;\n }\n return undefined;\n }\n default:\n // unknown type not rendered\n return undefined;\n }\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {Session} from \"../Session.js\";\nimport {RoomStatus} from \"./common\";\n\n/**\n * Join a room and wait for it to arrive in the next sync\n * @param roomId The id of the room to join\n * @param session A session instance\n */\nexport async function joinRoom(roomId: string, session: Session): Promise {\n try {\n const internalRoomId = await session.joinRoom(roomId);\n const roomStatusObservable = await session.observeRoomStatus(internalRoomId);\n await roomStatusObservable.waitFor((status: RoomStatus) => status === RoomStatus.Joined);\n return internalRoomId;\n }\n catch (e) {\n if ((e.statusCode ?? e.status) === 400) {\n throw new Error(`'${roomId}' is not a legal room ID or alias`);\n } else if ((e.statusCode ?? e.status) === 404 || (e.statusCode ?? e.status) === 502 || e.message == \"Internal Server eor\") {\n throw new Error(`Room '${roomId}' could not be found`);\n } else if ((e.statusCode ?? e.status) === 403) {\n throw new Error(`You are not invited to join '${roomId}'`);\n } else {\n throw e;\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TimelineViewModel} from \"./timeline/TimelineViewModel.js\";\nimport {ComposerViewModel} from \"./ComposerViewModel.js\"\nimport {CallViewModel} from \"./CallViewModel\"\nimport {PickMapObservableValue} from \"../../../observable/value\";\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\nimport {ErrorReportViewModel} from \"../../ErrorReportViewModel\";\nimport {ViewModel} from \"../../ViewModel\";\nimport {imageToInfo} from \"../common.js\";\nimport {LocalMedia} from \"../../../matrix/calls/LocalMedia\";\n// TODO: remove fallback so default isn't included in bundle for SDK users that have their custom tileClassForEntry\n// this is a breaking SDK change though to make this option mandatory\nimport {tileClassForEntry as defaultTileClassForEntry} from \"./timeline/tiles/index\";\nimport {joinRoom} from \"../../../matrix/room/joinRoom\";\n\nexport class RoomViewModel extends ErrorReportViewModel {\n constructor(options) {\n super(options);\n const {room, tileClassForEntry} = options;\n this._sendReadReceipt = options.sendReadReceipt ?? true;\n this._room = room;\n this._timelineVM = null;\n this._tileClassForEntry = tileClassForEntry ?? defaultTileClassForEntry;\n this._tileOptions = undefined;\n this._onRoomChange = this._onRoomChange.bind(this);\n this._composerVM = null;\n if (room.isArchived) {\n this._composerVM = this.track(new ArchivedViewModel(this.childOptions({archivedRoom: room})));\n } else {\n this._recreateComposerOnPowerLevelChange();\n }\n this._clearUnreadTimout = null;\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n this._setupCallViewModel();\n }\n\n _setupCallViewModel() {\n if (!this.features.calls) {\n return;\n }\n // pick call for this room with lowest key\n const calls = this.getOption(\"session\").callHandler.calls;\n this._callObservable = new PickMapObservableValue(calls.filterValues(c => {\n return c.roomId === this._room.id && c.hasJoined;\n }));\n this._callViewModel = undefined;\n this.track(this._callObservable.subscribe(call => {\n if (call && this._callViewModel && call.id === this._callViewModel.id) {\n return;\n }\n this._callViewModel = this.disposeTracked(this._callViewModel);\n if (call) {\n this._callViewModel = this.track(new CallViewModel(this.childOptions({call, room: this._room})));\n }\n this.emitChange(\"callViewModel\");\n }));\n const call = this._callObservable.get();\n // TODO: cleanup this duplication to create CallViewModel\n if (call) {\n this._callViewModel = this.track(new CallViewModel(this.childOptions({call, room: this._room})));\n }\n }\n\n async load() {\n await this.logAndCatch(\"RoomViewModel.load\", async log => {\n this._room.on(\"change\", this._onRoomChange);\n const timeline = await this._room.openTimeline(log);\n this.track(() => timeline.release());\n this._tileOptions = this.childOptions({\n session: this.getOption(\"session\"),\n roomVM: this,\n timeline,\n tileClassForEntry: this._tileClassForEntry,\n });\n this._timelineVM = this.track(new TimelineViewModel(this.childOptions({\n tileOptions: this._tileOptions,\n timeline,\n })));\n this.emitChange(\"timelineViewModel\");\n await this._clearUnreadAfterDelay(log);\n });\n }\n\n async _recreateComposerOnPowerLevelChange() {\n const powerLevelObservable = await this._room.observePowerLevels();\n const canSendMessage = () => powerLevelObservable.get().canSendType(\"m.room.message\");\n let oldCanSendMessage = canSendMessage();\n const recreateComposer = newCanSendMessage => {\n this._composerVM = this.disposeTracked(this._composerVM);\n if (newCanSendMessage) {\n this._composerVM = this.track(new ComposerViewModel(this));\n }\n else {\n this._composerVM = this.track(new LowerPowerLevelViewModel(this.childOptions()));\n }\n this.emitChange(\"powerLevelObservable\")\n };\n this.track(powerLevelObservable.subscribe(() => {\n const newCanSendMessage = canSendMessage();\n if (oldCanSendMessage !== newCanSendMessage) {\n recreateComposer(newCanSendMessage);\n oldCanSendMessage = newCanSendMessage;\n }\n }));\n recreateComposer(oldCanSendMessage);\n }\n\n async _clearUnreadAfterDelay(log) {\n if (this._room.isArchived || this._clearUnreadTimout) {\n return;\n }\n this._clearUnreadTimout = this.clock.createTimeout(2000);\n try {\n await this._clearUnreadTimout.elapsed();\n await this._room.clearUnread(log, this._sendReadReceipt);\n this._clearUnreadTimout = null;\n } catch (err) {\n if (err.name === \"AbortError\") {\n log.set(\"clearUnreadCancelled\", true);\n } else {\n throw err;\n }\n }\n }\n\n focus() {\n this.logAndCatch(\"RoomViewModel.focus\", async log => {\n this._clearUnreadAfterDelay(log);\n });\n }\n\n dispose() {\n super.dispose();\n this._room.off(\"change\", this._onRoomChange);\n if (this._room.isArchived) {\n this._room.release();\n }\n if (this._clearUnreadTimout) {\n this._clearUnreadTimout.abort();\n this._clearUnreadTimout = null;\n }\n }\n\n // room doesn't tell us yet which fields changed,\n // so emit all fields originating from summary\n _onRoomChange() {\n // propagate the update to the child view models so it's bindings can update based on room changes\n this._composerVM?.emitChange();\n this.emitChange();\n }\n\n get kind() { return \"room\"; }\n get closeUrl() { return this._closeUrl; }\n get name() { return this._room.name || this.i18n`Empty Room`; }\n get id() { return this._room.id; }\n get timelineViewModel() { return this._timelineVM; }\n get isEncrypted() { return this._room.isEncrypted; }\n\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._room.avatarColorId)\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._room.avatarUrl, size, this.platform, this._room.mediaRepository);\n }\n\n get avatarTitle() {\n return this.name;\n }\n\n get canLeave() {\n return this._room.isJoined;\n }\n\n leaveRoom() {\n this._room.leave();\n }\n\n get canForget() {\n return this._room.isArchived;\n }\n\n forgetRoom() {\n this._room.forget();\n }\n\n get canRejoin() {\n return this._room.isArchived;\n }\n\n rejoinRoom() {\n this._room.join();\n }\n\n _createTile(entry) {\n if (this._tileOptions) {\n const Tile = this._tileOptions.tileClassForEntry(entry, this._tileOptions);\n if (Tile) {\n return new Tile(entry, this._tileOptions);\n }\n }\n }\n \n _sendMessage(message, replyingTo) {\n return this.logAndCatch(\"RoomViewModel.sendMessage\", async log => {\n let success = false;\n if (!this._room.isArchived && message) {\n let msgtype = \"m.text\";\n if (message.startsWith(\"//\")) {\n message = message.substring(1).trim();\n } else if (message.startsWith(\"/\")) {\n const result = await this._processCommand(message);\n msgtype = result.msgtype;\n message = result.message;\n }\n let content;\n if (replyingTo) {\n log.set(\"replyingTo\", replyingTo.eventId);\n content = await replyingTo.createReplyContent(msgtype, message);\n } else {\n content = {msgtype, body: message};\n }\n await this._room.sendEvent(\"m.room.message\", content, undefined, log);\n success = true;\n }\n log.set(\"success\", success);\n return success;\n }, false);\n }\n\n async _processCommandJoin(roomName) {\n try {\n const session = this._options.client.session;\n const roomId = await joinRoom(roomName, session);\n this.navigation.push(\"room\", roomId);\n } catch (err) {\n this.reportError(err);\n }\n } \n\n async _processCommand(message) {\n let msgtype;\n const [commandName, ...args] = message.substring(1).split(\" \");\n switch (commandName) {\n case \"me\":\n message = args.join(\" \");\n msgtype = \"m.emote\";\n break;\n case \"join\":\n if (args.length === 1) {\n const roomName = args[0];\n await this._processCommandJoin(roomName);\n } else {\n this.reportError(new Error(\"join syntax: /join \"));\n }\n break;\n case \"invite\":\n if (args.length === 1) {\n const userId = args[0];\n await this._room.inviteUser(userId);\n } else {\n this.reportError(new Error(\"invite syntax: /invite \"));\n }\n break;\n case \"shrug\":\n message = \"¯\\\\_(ツ)_/¯ \" + args.join(\" \");\n msgtype = \"m.text\";\n break;\n case \"tableflip\":\n message = \"(╯°□°)╯︵ ┻━┻ \" + args.join(\" \");\n msgtype = \"m.text\";\n break;\n case \"unflip\":\n message = \"┬──┬ ノ( ゜-゜ノ) \" + args.join(\" \");\n msgtype = \"m.text\";\n break;\n case \"lenny\":\n message = \"( ͡° ͜ʖ ͡°) \" + args.join(\" \");\n msgtype = \"m.text\";\n break;\n default:\n this.reportError(new Error(`no command name \"${commandName}\". To send the message instead of executing, please type \"/${message}\"`));\n message = undefined;\n }\n return {msgtype, message: message};\n }\n\n _pickAndSendFile() {\n return this.logAndCatch(\"RoomViewModel.sendFile\", async log => {\n const file = await this.platform.openFile();\n if (!file) {\n log.set(\"cancelled\", true);\n return;\n }\n return this._sendFile(file, log);\n });\n }\n\n async _sendFile(file, log) {\n const content = {\n body: file.name,\n msgtype: \"m.file\"\n };\n await this._room.sendEvent(\"m.room.message\", content, {\n \"url\": this._room.createAttachment(file.blob, file.name)\n }, log);\n }\n\n _pickAndSendVideo() {\n return this.logAndCatch(\"RoomViewModel.sendVideo\", async log => {\n if (!this.platform.hasReadPixelPermission()) {\n throw new Error(\"Please allow canvas image data access, so we can scale your images down.\");\n }\n const file = await this.platform.openFile(\"video/*\");\n if (!file) {\n return;\n }\n if (!file.blob.mimeType.startsWith(\"video/\")) {\n return this._sendFile(file, log);\n }\n let video;\n try {\n video = await this.platform.loadVideo(file.blob);\n } catch (err) {\n // TODO: extract platform dependent code from view model\n if (err instanceof window.MediaError && err.code === 4) {\n throw new Error(`this browser does not support videos of type ${file?.blob.mimeType}.`);\n } else {\n throw err;\n }\n }\n const content = {\n body: file.name,\n msgtype: \"m.video\",\n info: videoToInfo(video)\n };\n const attachments = {\n \"url\": this._room.createAttachment(video.blob, file.name),\n };\n\n const limit = await this.platform.settingsStorage.getInt(\"sentImageSizeLimit\");\n const maxDimension = limit || Math.min(video.maxDimension, 800);\n const thumbnail = await video.scale(maxDimension);\n content.info.thumbnail_info = imageToInfo(thumbnail);\n attachments[\"info.thumbnail_url\"] = \n this._room.createAttachment(thumbnail.blob, file.name);\n await this._room.sendEvent(\"m.room.message\", content, attachments, log);\n });\n }\n\n async _pickAndSendPicture() {\n this.logAndCatch(\"RoomViewModel.sendPicture\", async log => {\n if (!this.platform.hasReadPixelPermission()) {\n alert(\"Please allow canvas image data access, so we can scale your images down.\");\n return;\n }\n const file = await this.platform.openFile(\"image/*\");\n if (!file) {\n log.set(\"cancelled\", true);\n return;\n }\n if (!file.blob.mimeType.startsWith(\"image/\")) {\n return this._sendFile(file, log);\n }\n let image = await this.platform.loadImage(file.blob);\n const limit = await this.platform.settingsStorage.getInt(\"sentImageSizeLimit\");\n if (limit && image.maxDimension > limit) {\n const scaledImage = await image.scale(limit);\n image.dispose();\n image = scaledImage;\n }\n const content = {\n body: file.name,\n msgtype: \"m.image\",\n info: imageToInfo(image)\n };\n const attachments = {\n \"url\": this._room.createAttachment(image.blob, file.name),\n };\n if (image.maxDimension > 600) {\n const thumbnail = await image.scale(400);\n content.info.thumbnail_info = imageToInfo(thumbnail);\n attachments[\"info.thumbnail_url\"] = \n this._room.createAttachment(thumbnail.blob, file.name);\n }\n await this._room.sendEvent(\"m.room.message\", content, attachments, log);\n });\n }\n\n get room() {\n return this._room;\n }\n\n get composerViewModel() {\n return this._composerVM;\n }\n\n get callViewModel() {\n return this._callViewModel;\n }\n\n openDetailsPanel() {\n let path = this.navigation.path.until(\"room\");\n path = path.with(this.navigation.segment(\"right-panel\", true));\n path = path.with(this.navigation.segment(\"details\", true));\n this.navigation.applyPath(path);\n }\n\n startReply(entry) {\n if (!this._room.isArchived) {\n this._composerVM.setReplyingTo(entry);\n }\n }\n\n startCall() {\n return this.logAndCatch(\"RoomViewModel.startCall\", async log => {\n if (!this.features.calls) {\n log.set(\"feature_disbled\", true);\n return;\n }\n log.set(\"roomId\", this._room.id);\n let localMedia;\n try {\n const stream = await this.platform.mediaDevices.getMediaTracks(false, true);\n localMedia = new LocalMedia().withUserMedia(stream);\n } catch (err) {\n throw new Error(`Could not get local audio and/or video stream: ${err.message}`);\n }\n const session = this.getOption(\"session\");\n let call;\n try {\n // this will set the callViewModel above as a call will be added to callHandler.calls\n call = await session.callHandler.createCall(\n this._room.id,\n \"m.video\",\n \"A call \" + Math.round(this.platform.random() * 100),\n undefined,\n log\n );\n } catch (err) {\n throw new Error(`Could not create call: ${err.message}`);\n }\n try {\n await call.join(localMedia, log);\n } catch (err) {\n throw new Error(`Could not join call: ${err.message}`);\n }\n });\n }\n}\n\nfunction videoToInfo(video) {\n const info = imageToInfo(video);\n info.duration = video.duration;\n return info;\n}\n\nclass ArchivedViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._archivedRoom = options.archivedRoom;\n }\n\n get description() {\n if (this._archivedRoom.isKicked) {\n if (this._archivedRoom.kickReason) {\n return this.i18n`You were kicked from the room by ${this._archivedRoom.kickedBy.name} because: ${this._archivedRoom.kickReason}`;\n } else {\n return this.i18n`You were kicked from the room by ${this._archivedRoom.kickedBy.name}.`;\n }\n } else if (this._archivedRoom.isBanned) {\n if (this._archivedRoom.kickReason) {\n return this.i18n`You were banned from the room by ${this._archivedRoom.kickedBy.name} because: ${this._archivedRoom.kickReason}`;\n } else {\n return this.i18n`You were banned from the room by ${this._archivedRoom.kickedBy.name}.`;\n }\n } else {\n return this.i18n`You left this room`;\n }\n }\n\n get kind() {\n return \"disabled\";\n }\n}\n\nclass LowerPowerLevelViewModel extends ViewModel {\n get description() {\n return this.i18n`You do not have the powerlevel necessary to send messages`;\n }\n\n get kind() {\n return \"disabled\";\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\n\nexport class UnknownRoomViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {roomIdOrAlias, session} = options;\n this._session = session;\n this.roomIdOrAlias = roomIdOrAlias;\n this._error = null;\n this._busy = false;\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n }\n\n get closeUrl() {\n return this._closeUrl;\n }\n\n get error() {\n return this._error?.message;\n }\n\n async join() {\n this._busy = true;\n this.emitChange(\"busy\");\n try {\n const roomId = await this._session.joinRoom(this.roomIdOrAlias);\n // navigate to roomId if we were at the alias\n // so we're subscribed to the right room status\n // and we'll switch to the room view model once\n // the join is synced\n this.navigation.push(\"room\", roomId);\n // keep busy on true while waiting for the join to sync\n } catch (err) {\n this._error = err;\n this._busy = false;\n this.emitChange(\"error\");\n }\n }\n\n get busy() {\n return this._busy;\n }\n\n get kind() {\n return \"unknown\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\nimport {ViewModel} from \"../../ViewModel\";\n\nexport class InviteViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {invite, mediaRepository} = options;\n this._invite = invite;\n this._mediaRepository = mediaRepository;\n this._onInviteChange = this._onInviteChange.bind(this);\n this._error = null;\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n this._invite.on(\"change\", this._onInviteChange);\n this._inviter = null;\n if (this._invite.inviter) {\n this._inviter = new RoomMemberViewModel(this._invite.inviter, mediaRepository, this.platform);\n }\n this._roomDescription = this._createRoomDescription();\n }\n\n get kind() { return \"invite\"; }\n get closeUrl() { return this._closeUrl; }\n get name() { return this._invite.name; }\n get id() { return this._invite.id; }\n get isEncrypted() { return this._invite.isEncrypted; }\n get isDirectMessage() { return this._invite.isDirectMessage; }\n get inviter() { return this._inviter; }\n get busy() { return this._invite.accepting || this._invite.rejecting; }\n\n get error() {\n if (this._error) {\n return `Something went wrong: ${this._error.message}`;\n }\n return \"\";\n }\n\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._invite.avatarColorId)\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._invite.avatarUrl, size, this.platform, this._mediaRepository);\n }\n\n _createRoomDescription() {\n const parts = [];\n if (this._invite.isPublic) {\n parts.push(\"Public room\");\n } else {\n parts.push(\"Private room\");\n }\n\n if (this._invite.canonicalAlias) {\n parts.push(this._invite.canonicalAlias);\n }\n return parts.join(\" • \")\n }\n\n get roomDescription() {\n return this._roomDescription;\n }\n\n get avatarTitle() {\n return this.name;\n }\n\n focus() {}\n\n async accept() {\n try {\n await this._invite.accept();\n } catch (err) {\n this._error = err;\n this.emitChange(\"error\");\n }\n }\n\n async reject() {\n try {\n await this._invite.reject();\n } catch (err) {\n this._error = err;\n this.emitChange(\"error\");\n }\n }\n\n _onInviteChange() {\n this.emitChange();\n }\n\n dispose() {\n super.dispose();\n this._invite.off(\"change\", this._onInviteChange);\n }\n}\n\nclass RoomMemberViewModel {\n constructor(member, mediaRepository, platform) {\n this._member = member;\n this._mediaRepository = mediaRepository;\n this._platform = platform;\n }\n\n get id() {\n return this._member.userId;\n }\n\n get name() {\n return this._member.name;\n }\n\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._member.userId);\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._member.avatarUrl, size, this._platform, this._mediaRepository);\n }\n\n get avatarTitle() {\n return this.name;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020, 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\nimport {ViewModel} from \"../../ViewModel\";\n\nexport class RoomBeingCreatedViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {roomBeingCreated, mediaRepository} = options;\n this._roomBeingCreated = roomBeingCreated;\n this._mediaRepository = mediaRepository;\n this._onRoomChange = this._onRoomChange.bind(this);\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n this._roomBeingCreated.on(\"change\", this._onRoomChange);\n }\n\n get kind() { return \"roomBeingCreated\"; }\n get closeUrl() { return this._closeUrl; }\n get name() { return this._roomBeingCreated.name; }\n get id() { return this._roomBeingCreated.id; }\n get isEncrypted() { return this._roomBeingCreated.isEncrypted; }\n get error() {\n const {error} = this._roomBeingCreated;\n if (error) {\n if (error.name === \"ConnectionError\") {\n return this.i18n`You seem to be offline`;\n } else {\n return error.message;\n }\n }\n return \"\";\n }\n get avatarLetter() { return avatarInitials(this.name); }\n get avatarColorNumber() { return getIdentifierColorNumber(this._roomBeingCreated.avatarColorId); }\n get avatarTitle() { return this.name; }\n\n avatarUrl(size) {\n // allow blob url which doesn't need mxc => http resolution\n return this._roomBeingCreated.avatarBlobUrl ??\n getAvatarHttpUrl(this._roomBeingCreated.avatarUrl, size, this.platform, this._mediaRepository);\n }\n\n focus() {}\n\n _onRoomChange() {\n this.emitChange();\n }\n\n cancel() {\n this._roomBeingCreated.cancel();\n // navigate away from the room\n this.navigation.applyPath(this.navigation.path.until(\"session\"));\n }\n\n dispose() {\n super.dispose();\n this._roomBeingCreated.off(\"change\", this._onRoomChange);\n }\n}\n\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\n\nexport class LightboxViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._eventId = options.eventId;\n this._unencryptedImageUrl = null;\n this._decryptedImage = null;\n this._closeUrl = this.urlRouter.urlUntilSegment(\"room\");\n this._date = null;\n this._subscribeToEvent(options.room, options.eventId);\n }\n\n _subscribeToEvent(room, eventId) {\n const eventObservable = room.observeEvent(eventId);\n this.track(eventObservable.subscribe(eventEntry => {\n this._loadEvent(room, eventEntry);\n }));\n this._loadEvent(room, eventObservable.get());\n }\n\n async _loadEvent(room, eventEntry) {\n if (!eventEntry) {\n return;\n }\n const {mediaRepository} = room;\n this._eventEntry = eventEntry;\n const {content} = this._eventEntry;\n this._date = this._eventEntry.timestamp ? new Date(this._eventEntry.timestamp) : null;\n if (content.url) {\n this._unencryptedImageUrl = mediaRepository.mxcUrl(content.url);\n this.emitChange(\"imageUrl\");\n } else if (content.file) {\n this._decryptedImage = this.track(await mediaRepository.downloadEncryptedFile(content.file));\n this.emitChange(\"imageUrl\");\n }\n }\n\n get imageWidth() {\n return this._eventEntry?.content?.info?.w;\n }\n\n get imageHeight() {\n return this._eventEntry?.content?.info?.h;\n }\n\n get name() {\n return this._eventEntry?.content?.body;\n }\n\n get sender() {\n return this._eventEntry?.displayName;\n }\n\n get imageUrl() {\n if (this._decryptedImage) {\n return this._decryptedImage.url;\n } else if (this._unencryptedImageUrl) {\n return this._unencryptedImageUrl;\n } else {\n return \"\";\n }\n }\n\n get date() {\n return this._date && this._date.toLocaleDateString({}, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });\n }\n\n get time() {\n return this._date && this._date.toLocaleTimeString({}, {hour: \"numeric\", minute: \"2-digit\"});\n }\n\n get closeUrl() {\n return this._closeUrl;\n }\n\n close() {\n this.platform.history.pushUrl(this.closeUrl);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../ViewModel\";\nimport {createEnum} from \"../../utils/enum\";\nimport {ConnectionStatus} from \"../../matrix/net/Reconnector\";\nimport {SyncStatus} from \"../../matrix/Sync.js\";\n\nconst SessionStatus = createEnum(\n \"Disconnected\",\n \"Connecting\",\n \"FirstSync\",\n \"Sending\",\n \"Syncing\",\n \"SyncError\"\n);\n\nexport class SessionStatusViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {sync, reconnector, session} = options;\n this._sync = sync;\n this._reconnector = reconnector;\n this._status = this._calculateState(reconnector.connectionStatus.get(), sync.status.get());\n this._session = session;\n this._setupKeyBackupUrl = this.urlRouter.urlForSegment(\"settings\");\n this._dismissSecretStorage = false;\n }\n\n start() {\n const update = () => this._updateStatus();\n this.track(this._sync.status.subscribe(update));\n this.track(this._reconnector.connectionStatus.subscribe(update));\n this.track(this._session.needsKeyBackup.subscribe(() => {\n this.emitChange();\n }));\n }\n\n get setupKeyBackupUrl () {\n return this._setupKeyBackupUrl;\n }\n\n get isShown() {\n return (this._session.needsKeyBackup.get() && !this._dismissSecretStorage) || this._status !== SessionStatus.Syncing;\n }\n\n get statusLabel() {\n switch (this._status) {\n case SessionStatus.Disconnected:{\n const retryIn = Math.round(this._reconnector.retryIn / 1000);\n return this.i18n`Disconnected, trying to reconnect in ${retryIn}s…`;\n }\n case SessionStatus.Connecting:\n return this.i18n`Trying to reconnect now…`;\n case SessionStatus.FirstSync:\n return this.i18n`Catching up with your conversations…`;\n case SessionStatus.SyncError:\n return this.i18n`Sync failed because of ${this._sync.error}`;\n }\n if (this._session.needsKeyBackup.get()) {\n return this.i18n`Set up session backup to decrypt older messages.`;\n }\n return \"\";\n }\n\n get isWaiting() {\n switch (this._status) {\n case SessionStatus.Connecting:\n case SessionStatus.FirstSync:\n return true;\n default:\n return false;\n }\n }\n\n _updateStatus() {\n const newStatus = this._calculateState(\n this._reconnector.connectionStatus.get(),\n this._sync.status.get()\n );\n if (newStatus !== this._status) {\n if (newStatus === SessionStatus.Disconnected) {\n this._retryTimer = this.track(this.clock.createInterval(() => {\n this.emitChange(\"statusLabel\");\n }, 1000));\n } else {\n this._retryTimer = this.disposeTracked(this._retryTimer);\n }\n this._status = newStatus;\n this.emitChange();\n }\n }\n\n _calculateState(connectionStatus, syncStatus) {\n if (connectionStatus !== ConnectionStatus.Online) {\n switch (connectionStatus) {\n case ConnectionStatus.Reconnecting:\n return SessionStatus.Connecting;\n case ConnectionStatus.Waiting:\n return SessionStatus.Disconnected;\n }\n } else if (syncStatus !== SyncStatus.Syncing) {\n switch (syncStatus) {\n // InitialSync should be awaited in the SessionLoadViewModel,\n // but include it here anyway\n case SyncStatus.InitialSync:\n case SyncStatus.CatchupSync:\n return SessionStatus.FirstSync;\n case SyncStatus.Stopped:\n return SessionStatus.SyncError;\n }\n } /* else if (session.pendingMessageCount) {\n return SessionStatus.Sending;\n } */ else {\n return SessionStatus.Syncing;\n }\n }\n\n get isConnectNowShown() {\n return this._status === SessionStatus.Disconnected;\n }\n\n get isSecretStorageShown() {\n // TODO: we need a model here where we can have multiple messages queued up and their buttons don't bleed into each other.\n return this._status === SessionStatus.Syncing && this._session.needsKeyBackup.get() && !this._dismissSecretStorage;\n }\n\n get canDismiss() {\n return this.isSecretStorageShown;\n }\n\n dismiss() {\n if (this.isSecretStorageShown) {\n this._dismissSecretStorage = true;\n this.emitChange();\n }\n }\n\n connectNow() {\n if (this.isConnectNowShown) {\n this._reconnector.tryNow();\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../ViewModel\";\nimport {addPanelIfNeeded} from \"../navigation/index\";\n\nfunction dedupeSparse(roomIds) {\n return roomIds.map((id, idx) => {\n if (roomIds.slice(0, idx).includes(id)) {\n return undefined;\n } else {\n return id;\n }\n });\n}\n\nexport class RoomGridViewModel extends ViewModel {\n constructor(options) {\n super(options);\n\n this._width = options.width;\n this._height = options.height;\n this._createRoomViewModelObservable = options.createRoomViewModelObservable;\n this._selectedIndex = 0;\n this._viewModelsObservables = [];\n this._setupNavigation();\n }\n\n _setupNavigation() {\n const focusTileIndex = this.navigation.observe(\"empty-grid-tile\");\n this.track(focusTileIndex.subscribe(index => {\n if (typeof index === \"number\") {\n this._setFocusIndex(index);\n }\n }));\n if (typeof focusTileIndex.get() === \"number\") {\n this._selectedIndex = focusTileIndex.get();\n }\n\n const focusedRoom = this.navigation.observe(\"room\");\n this.track(focusedRoom.subscribe(roomId => {\n if (roomId) {\n // as the room will be in the \"rooms\" observable\n // (monitored by the parent vmo) as well,\n // we only change the focus here and trust\n // setRoomIds to have created the vmo already\n this._setFocusRoom(roomId);\n }\n }));\n // initial focus for a room is set by initializeRoomIdsAndTransferVM\n }\n\n roomViewModelAt(i) {\n return this._viewModelsObservables[i]?.get();\n }\n\n get focusIndex() {\n return this._selectedIndex;\n }\n\n get width() {\n return this._width;\n }\n\n get height() {\n return this._height;\n }\n\n _switchToRoom(roomId) {\n let path = this.navigation.path.until(\"rooms\");\n path = path.with(this.navigation.segment(\"room\", roomId));\n path = addPanelIfNeeded(this.navigation, path);\n this.navigation.applyPath(path);\n }\n\n focusTile(index) {\n if (index === this._selectedIndex) {\n return;\n }\n const vmo = this._viewModelsObservables[index];\n if (vmo) {\n this._switchToRoom(vmo.id);\n } else {\n this.navigation.push(\"empty-grid-tile\", index);\n }\n }\n\n /** called from SessionViewModel */\n initializeRoomIdsAndTransferVM(roomIds, existingRoomVM) {\n roomIds = dedupeSparse(roomIds);\n let transfered = false;\n if (existingRoomVM) {\n const index = roomIds.indexOf(existingRoomVM.id);\n if (index !== -1) {\n this._viewModelsObservables[index] = this.track(existingRoomVM);\n existingRoomVM.subscribe(viewModel => this._refreshRoomViewModel(viewModel));\n transfered = true;\n }\n }\n this.setRoomIds(roomIds);\n // now all view models exist, set the focus to the selected room\n const focusedRoom = this.navigation.path.get(\"room\");\n if (focusedRoom) {\n const index = this._viewModelsObservables.findIndex(vmo => vmo && vmo.id === focusedRoom.value);\n if (index !== -1) {\n this._selectedIndex = index;\n }\n }\n return transfered;\n }\n\n /** called from SessionViewModel */\n setRoomIds(roomIds) {\n roomIds = dedupeSparse(roomIds);\n let changed = false;\n const len = this._height * this._width;\n for (let i = 0; i < len; i += 1) {\n const newId = roomIds[i];\n const vmo = this._viewModelsObservables[i];\n // did anything change?\n if ((!vmo && newId) || (vmo && vmo.id !== newId)) {\n if (vmo) {\n this._viewModelsObservables[i] = this.disposeTracked(vmo);\n }\n if (newId) {\n const vmo = this._createRoomViewModelObservable(newId);\n this._viewModelsObservables[i] = this.track(vmo);\n vmo.subscribe(viewModel => this._refreshRoomViewModel(viewModel));\n vmo.initialize();\n }\n changed = true;\n }\n }\n if (changed) {\n this.emitChange();\n }\n return changed;\n }\n\n _refreshRoomViewModel(viewModel) {\n this.emitChange();\n viewModel?.focus();\n }\n\n /** called from SessionViewModel */\n releaseRoomViewModel(roomId) {\n const index = this._viewModelsObservables.findIndex(vmo => vmo && vmo.id === roomId);\n if (index !== -1) {\n const vmo = this._viewModelsObservables[index];\n this.untrack(vmo);\n vmo.unsubscribeAll();\n this._viewModelsObservables[index] = null;\n return vmo;\n }\n }\n\n _setFocusIndex(idx) {\n if (idx === this._selectedIndex || idx >= (this._width * this._height)) {\n return;\n }\n this._selectedIndex = idx;\n const vmo = this._viewModelsObservables[this._selectedIndex];\n vmo?.get()?.focus();\n this.emitChange(\"focusIndex\");\n }\n\n _setFocusRoom(roomId) {\n const index = this._viewModelsObservables.findIndex(vmo => vmo?.id === roomId);\n if (index >= 0) {\n this._setFocusIndex(index);\n }\n }\n}\n\nimport {createNavigation} from \"../navigation/index\";\nimport {ObservableValue} from \"../../observable/value\";\n\nexport function tests() { \n class RoomVMMock {\n constructor(id) {\n this.id = id;\n this.disposed = false;\n this.focused = false;\n }\n dispose() {\n this.disposed = true;\n }\n focus() {\n this.focused = true;\n }\n }\n\n class RoomViewModelObservableMock extends ObservableValue {\n async initialize() {}\n dispose() { this.get()?.dispose(); }\n get id() { return this.get()?.id; }\n }\n\n function createNavigationForRoom(rooms, room) {\n const navigation = createNavigation();\n navigation.applyPath(navigation.pathFrom([\n navigation.segment(\"session\", \"1\"),\n navigation.segment(\"rooms\", rooms),\n navigation.segment(\"room\", room),\n ]));\n return navigation;\n }\n\n function createNavigationForEmptyTile(rooms, idx) {\n const navigation = createNavigation();\n navigation.applyPath(navigation.pathFrom([\n navigation.segment(\"session\", \"1\"),\n navigation.segment(\"rooms\", rooms),\n navigation.segment(\"empty-grid-tile\", idx),\n ]));\n return navigation;\n }\n\n return {\n \"initialize with duplicate set of rooms\": assert => {\n const navigation = createNavigationForRoom([\"c\", \"a\", \"b\", undefined, \"a\"], \"a\");\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: id => new RoomViewModelObservableMock(new RoomVMMock(id)),\n navigation,\n width: 3,\n height: 2,\n });\n gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value);\n assert.equal(gridVM.focusIndex, 1);\n assert.equal(gridVM.roomViewModelAt(0).id, \"c\");\n assert.equal(gridVM.roomViewModelAt(1).id, \"a\");\n assert.equal(gridVM.roomViewModelAt(2).id, \"b\");\n assert.equal(gridVM.roomViewModelAt(3), undefined);\n assert.equal(gridVM.roomViewModelAt(4), undefined);\n assert.equal(gridVM.roomViewModelAt(5), undefined);\n },\n \"transfer room view model\": assert => {\n const navigation = createNavigationForRoom([\"a\"], \"a\");\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: () => assert.fail(\"no vms should be created\"),\n navigation,\n width: 3,\n height: 2,\n });\n const existingRoomVM = new RoomViewModelObservableMock(new RoomVMMock(\"a\"));\n const transfered = gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value, existingRoomVM);\n assert.equal(transfered, true);\n assert.equal(gridVM.focusIndex, 0);\n assert.equal(gridVM.roomViewModelAt(0).id, \"a\");\n },\n \"reject transfer for non-matching room view model\": assert => {\n const navigation = createNavigationForRoom([\"a\"], \"a\");\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: id => new RoomViewModelObservableMock(new RoomVMMock(id)),\n navigation,\n width: 3,\n height: 2,\n });\n const existingRoomVM = new RoomViewModelObservableMock(new RoomVMMock(\"f\"));\n const transfered = gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value, existingRoomVM);\n assert.equal(transfered, false);\n assert.equal(gridVM.focusIndex, 0);\n assert.equal(gridVM.roomViewModelAt(0).id, \"a\");\n },\n \"created & released room view model is not disposed\": assert => {\n const navigation = createNavigationForRoom([\"a\"], \"a\");\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: id => new RoomViewModelObservableMock(new RoomVMMock(id)),\n navigation,\n width: 3,\n height: 2,\n });\n const transfered = gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value);\n assert.equal(transfered, false);\n const releasedVM = gridVM.releaseRoomViewModel(\"a\");\n gridVM.dispose();\n assert.equal(releasedVM.get().disposed, false);\n },\n \"transfered & released room view model is not disposed\": assert => {\n const navigation = createNavigationForRoom([undefined, \"a\"], \"a\");\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: () => assert.fail(\"no vms should be created\"),\n navigation,\n width: 3,\n height: 2,\n });\n const existingRoomVM = new RoomViewModelObservableMock(new RoomVMMock(\"a\"));\n const transfered = gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value, existingRoomVM);\n assert.equal(transfered, true);\n const releasedVM = gridVM.releaseRoomViewModel(\"a\");\n gridVM.dispose();\n assert.equal(releasedVM.get().disposed, false);\n },\n \"try release non-existing room view model is\": assert => {\n const navigation = createNavigationForEmptyTile([undefined, \"b\"], 3);\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: id => new RoomViewModelObservableMock(new RoomVMMock(id)),\n navigation,\n width: 3,\n height: 2,\n });\n gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value);\n const releasedVM = gridVM.releaseRoomViewModel(\"c\");\n assert(!releasedVM);\n },\n \"initial focus is set to empty tile\": assert => {\n const navigation = createNavigationForEmptyTile([\"a\"], 1);\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: id => new RoomViewModelObservableMock(new RoomVMMock(id)),\n navigation,\n width: 3,\n height: 2,\n });\n gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value);\n assert.equal(gridVM.focusIndex, 1);\n assert.equal(gridVM.roomViewModelAt(0).id, \"a\");\n },\n \"change room ids after creation\": assert => {\n const navigation = createNavigationForRoom([\"a\", \"b\"], \"a\");\n const gridVM = new RoomGridViewModel({\n createRoomViewModelObservable: id => new RoomViewModelObservableMock(new RoomVMMock(id)),\n navigation,\n width: 3,\n height: 2,\n });\n navigation.observe(\"rooms\").subscribe(roomIds => {\n gridVM.setRoomIds(roomIds);\n });\n gridVM.initializeRoomIdsAndTransferVM(navigation.path.get(\"rooms\").value);\n const oldA = gridVM.roomViewModelAt(0);\n const oldB = gridVM.roomViewModelAt(1);\n assert.equal(oldA.id, \"a\");\n assert.equal(oldB.id, \"b\");\n navigation.applyPath(navigation.path\n .with(navigation.segment(\"rooms\", [\"b\", \"c\", \"b\"]))\n .with(navigation.segment(\"room\", \"c\"))\n );\n assert.equal(oldA.disposed, true);\n assert.equal(oldB.disposed, true);\n assert.equal(gridVM.focusIndex, 1);\n assert.equal(gridVM.roomViewModelAt(0).id, \"b\");\n assert.equal(gridVM.roomViewModelAt(0).disposed, false);\n assert.equal(gridVM.roomViewModelAt(1).id, \"c\");\n assert.equal(gridVM.roomViewModelAt(1).focused, true);\n assert.equal(gridVM.roomViewModelAt(2), undefined);\n }\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {SegmentType} from \"../../navigation/index\";\nimport {KeyType} from \"../../../matrix/ssss/index\";\n\nimport type {Options as BaseOptions} from \"../../ViewModel\";\nimport type {Session} from \"../../../matrix/Session\";\nimport type {Disposable} from \"../../../utils/Disposables\";\nimport type {KeyBackup, Progress} from \"../../../matrix/e2ee/megolm/keybackup/KeyBackup\";\nimport type {CrossSigning} from \"../../../matrix/verification/CrossSigning\";\n\nexport enum Status {\n Enabled,\n SetupWithPassphrase,\n SetupWithRecoveryKey,\n Pending,\n NewVersionAvailable\n};\n\nexport enum BackupWriteStatus {\n Writing,\n Stopped,\n Done,\n Pending\n};\n\ntype Options = {\n session: Session,\n} & BaseOptions;\n\nexport class KeyBackupViewModel extends ViewModel {\n private _error?: Error = undefined;\n private _isBusy = false;\n private _dehydratedDeviceId?: string = undefined;\n private _status = Status.Pending;\n private _backupOperationSubscription?: Disposable = undefined;\n private _keyBackupSubscription?: Disposable = undefined;\n private _progress?: Progress = undefined;\n private _setupKeyType = KeyType.RecoveryKey;\n\n constructor(options) {\n super(options);\n const onKeyBackupSet = (keyBackup: KeyBackup | undefined) => {\n if (keyBackup && !this._keyBackupSubscription) {\n this._keyBackupSubscription = this.track(this._session.keyBackup.get().disposableOn(\"change\", () => {\n this._onKeyBackupChange();\n }));\n } else if (!keyBackup && this._keyBackupSubscription) {\n this._keyBackupSubscription = this.disposeTracked(this._keyBackupSubscription);\n }\n this._onKeyBackupChange(); // update status\n };\n this.track(this._session.keyBackup.subscribe(onKeyBackupSet));\n this.track(this._session.crossSigning.subscribe(() => {\n this.emitChange(\"crossSigning\");\n }));\n onKeyBackupSet(this._keyBackup);\n }\n\n private get _session(): Session {\n return this.getOption(\"session\");\n }\n\n private get _keyBackup(): KeyBackup | undefined {\n return this._session.keyBackup.get();\n }\n\n private get _crossSigning(): CrossSigning | undefined {\n return this._session.crossSigning.get();\n }\n\n private _onKeyBackupChange() {\n const keyBackup = this._keyBackup;\n if (keyBackup) {\n const {operationInProgress} = keyBackup;\n if (operationInProgress && !this._backupOperationSubscription) {\n this._backupOperationSubscription = this.track(operationInProgress.disposableOn(\"change\", () => {\n this._progress = operationInProgress.progress;\n this.emitChange(\"backupPercentage\");\n }));\n } else if (this._backupOperationSubscription && !operationInProgress) {\n this._backupOperationSubscription = this.disposeTracked(this._backupOperationSubscription);\n this._progress = undefined;\n }\n }\n this.emitChange(\"status\");\n }\n\n get status(): Status {\n const keyBackup = this._keyBackup;\n if (keyBackup) {\n if (keyBackup.needsNewKey) {\n return Status.NewVersionAvailable;\n } else if (keyBackup.version === undefined) {\n return Status.Pending;\n } else {\n return keyBackup.needsNewKey ? Status.NewVersionAvailable : Status.Enabled;\n }\n } else {\n switch (this._setupKeyType) {\n case KeyType.RecoveryKey: return Status.SetupWithRecoveryKey;\n case KeyType.Passphrase: return Status.SetupWithPassphrase;\n }\n }\n }\n\n get decryptAction(): string {\n return this.i18n`Set up`;\n }\n\n get purpose(): string {\n return this.i18n`set up key backup`;\n }\n\n offerDehydratedDeviceSetup(): boolean {\n return true;\n }\n\n get dehydratedDeviceId(): string | undefined {\n return this._dehydratedDeviceId;\n }\n \n get isBusy(): boolean {\n return this._isBusy;\n }\n\n get backupVersion(): string {\n return this._keyBackup?.version ?? \"\";\n }\n\n get isMasterKeyTrusted(): boolean {\n return this._crossSigning?.isMasterKeyTrusted ?? false;\n }\n\n get canSignOwnDevice(): boolean {\n return !!this._crossSigning;\n }\n\n private async _signOwnDevice(): Promise {\n const crossSigning = this._crossSigning;\n if (crossSigning) {\n await this.logger.run(\"KeyBackupViewModel.signOwnDevice\", async log => {\n await crossSigning.signOwnDevice(log);\n });\n }\n }\n\n navigateToVerification(): void {\n this.navigation.push(\"device-verification\", true);\n }\n\n get backupWriteStatus(): BackupWriteStatus {\n const keyBackup = this._keyBackup;\n if (!keyBackup || keyBackup.version === undefined) {\n return BackupWriteStatus.Pending;\n } else if (keyBackup.hasStopped) {\n return BackupWriteStatus.Stopped;\n }\n const operation = keyBackup.operationInProgress;\n if (operation) {\n return BackupWriteStatus.Writing;\n } else if (keyBackup.hasBackedUpAllKeys) {\n return BackupWriteStatus.Done;\n } else {\n return BackupWriteStatus.Pending;\n }\n }\n\n get backupError(): string | undefined {\n return this._keyBackup?.error?.message;\n }\n\n get error(): string | undefined {\n return this._error?.message;\n }\n\n showPhraseSetup(): void {\n this._setupKeyType = KeyType.Passphrase;\n this.emitChange(\"status\");\n }\n\n showKeySetup(): void {\n this._setupKeyType = KeyType.RecoveryKey;\n this.emitChange(\"status\");\n }\n\n private async _enterCredentials(keyType, credential, setupDehydratedDevice): Promise {\n if (credential) {\n try {\n this._isBusy = true;\n this.emitChange(\"isBusy\");\n const key = await this._session.enableSecretStorage(keyType, credential);\n if (setupDehydratedDevice) {\n this._dehydratedDeviceId = await this._session.setupDehydratedDevice(key);\n }\n await this._signOwnDevice();\n } catch (err) {\n console.error(err);\n this._error = err;\n this.emitChange(\"error\");\n } finally {\n this._isBusy = false;\n this.emitChange();\n }\n }\n }\n\n enterSecurityPhrase(passphrase, setupDehydratedDevice): Promise {\n return this._enterCredentials(KeyType.Passphrase, passphrase, setupDehydratedDevice);\n }\n\n enterSecurityKey(securityKey, setupDehydratedDevice): Promise {\n return this._enterCredentials(KeyType.RecoveryKey, securityKey, setupDehydratedDevice);\n }\n\n async disable(): Promise {\n try {\n this._isBusy = true;\n this.emitChange(\"isBusy\");\n await this._session.disableSecretStorage();\n } catch (err) {\n console.error(err);\n this._error = err;\n this.emitChange(\"error\");\n } finally {\n this._isBusy = false;\n this.emitChange();\n }\n }\n\n get isBackingUp(): boolean {\n return this._keyBackup?.operationInProgress !== undefined;\n }\n\n get backupPercentage(): number {\n if (this._progress) {\n return Math.round((this._progress.finished / this._progress.total) * 100);\n }\n return 0;\n }\n\n get backupInProgressLabel(): string {\n if (this._progress) {\n return this.i18n`${this._progress.finished} of ${this._progress.total}`;\n }\n return this.i18n`…`;\n }\n\n cancelBackup(): void {\n this._keyBackup?.operationInProgress?.abort();\n }\n\n startBackup(): void {\n this.logger.run(\"KeyBackupViewModel.startBackup\", log => {\n this._keyBackup?.flush(log);\n });\n }\n}\n\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport type {Options as BaseOptions} from \"../../ViewModel\";\nimport {FeatureFlag, FeatureSet} from \"../../../features\";\nimport type {SegmentType} from \"../../navigation/index\";\n\nexport class FeaturesViewModel extends ViewModel {\n public readonly featureViewModels: ReadonlyArray;\n\n constructor(options) {\n super(options);\n this.featureViewModels = [\n new FeatureViewModel(this.childOptions({\n name: this.i18n`Audio/video calls`,\n description: this.i18n`Allows starting and participating in A/V calls compatible with Element Call (MSC3401). Look for the start call option in the room menu ((...) in the right corner) to start a call.`,\n feature: FeatureFlag.Calls\n })),\n new FeatureViewModel(this.childOptions({\n name: this.i18n`Cross-Signing`,\n description: this.i18n`Allows verifying the identity of people you chat with. This feature is still evolving constantly, expect things to break.`,\n feature: FeatureFlag.CrossSigning\n })),\n ];\n }\n}\n\ntype FeatureOptions = BaseOptions & {\n feature: FeatureFlag,\n description: string,\n name: string\n};\n\nexport class FeatureViewModel extends ViewModel {\n get enabled(): boolean {\n return this.features.isFeatureEnabled(this.getOption(\"feature\"));\n }\n\n async enableFeature(enabled: boolean): Promise {\n let newFeatures;\n if (enabled) {\n newFeatures = this.features.withFeature(this.getOption(\"feature\"));\n } else {\n newFeatures = this.features.withoutFeature(this.getOption(\"feature\"));\n }\n await newFeatures.store(this.platform.settingsStorage);\n this.platform.restart();\n }\n\n get id(): string {\n return `${this.getOption(\"feature\")}`;\n }\n\n get name(): string {\n return this.getOption(\"name\");\n }\n\n get description(): string {\n return this.getOption(\"description\");\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {KeyBackupViewModel} from \"./KeyBackupViewModel\";\nimport {FeaturesViewModel} from \"./FeaturesViewModel\";\nimport {submitLogsFromSessionToDefaultServer} from \"../../../domain/rageshake\";\n\nclass PushNotificationStatus {\n constructor() {\n this.supported = null;\n this.enabled = false;\n this.updating = false;\n this.enabledOnServer = null;\n this.serverError = null;\n }\n}\n\nfunction formatKey(key) {\n const partLength = 4;\n const partCount = Math.ceil(key.length / partLength);\n let formattedKey = \"\";\n for (let i = 0; i < partCount; i += 1) {\n formattedKey += (formattedKey.length ? \" \" : \"\") + key.slice(i * partLength, (i + 1) * partLength);\n }\n return formattedKey;\n}\n\nexport class SettingsViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._updateService = options.updateService;\n const {client} = options;\n this._client = client;\n this._keyBackupViewModel = this.track(new KeyBackupViewModel(this.childOptions({session: this._session})));\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n this._estimate = null;\n this.sentImageSizeLimit = null;\n this.minSentImageSizeLimit = 400;\n this.maxSentImageSizeLimit = 4000;\n this.pushNotifications = new PushNotificationStatus();\n this._activeTheme = undefined;\n this._logsFeedbackMessage = undefined;\n this._featuresViewModel = new FeaturesViewModel(this.childOptions());\n }\n\n get _session() {\n return this._client.session;\n }\n\n async logout() {\n this.navigation.push(\"logout\", this._client.sessionId);\n }\n\n setSentImageSizeLimit(size) {\n if (size > this.maxSentImageSizeLimit || size < this.minSentImageSizeLimit) {\n this.sentImageSizeLimit = null;\n this.platform.settingsStorage.remove(\"sentImageSizeLimit\");\n } else {\n this.sentImageSizeLimit = Math.round(size);\n this.platform.settingsStorage.setInt(\"sentImageSizeLimit\", size);\n }\n this.emitChange(\"sentImageSizeLimit\");\n }\n\n async load() {\n this._estimate = await this.platform.estimateStorageUsage();\n this.sentImageSizeLimit = await this.platform.settingsStorage.getInt(\"sentImageSizeLimit\");\n this.pushNotifications.supported = await this.platform.notificationService.supportsPush();\n this.pushNotifications.enabled = await this._session.arePushNotificationsEnabled();\n if (!import.meta.env.DEV) {\n this._activeTheme = await this.platform.themeLoader.getActiveTheme();\n }\n this.emitChange(\"\");\n }\n\n get closeUrl() {\n return this._closeUrl;\n }\n\n get fingerprintKey() {\n const key = this._session.fingerprintKey;\n if (!key) {\n return null;\n }\n return formatKey(key);\n }\n\n get deviceId() {\n return this._session.deviceId;\n }\n\n get userId() {\n return this._session.userId;\n }\n\n get version() {\n const {updateService} = this.platform; \n if (updateService) {\n return `${updateService.version} (${updateService.buildHash})`;\n }\n return this.i18n`development version`;\n }\n\n checkForUpdate() {\n this.platform.updateService?.checkForUpdate();\n }\n\n get showUpdateButton() {\n return !!this.platform.updateService;\n }\n\n get keyBackupViewModel() {\n return this._keyBackupViewModel;\n }\n\n get featuresViewModel() {\n return this._featuresViewModel;\n }\n\n get storageQuota() {\n return this._formatBytes(this._estimate?.quota);\n }\n\n get storageUsage() {\n return this._formatBytes(this._estimate?.usage);\n }\n\n get themeMapping() {\n return this.platform.themeLoader.themeMapping;\n }\n\n get activeTheme() {\n return this._activeTheme;\n }\n\n _formatBytes(n) {\n if (typeof n === \"number\") {\n return Math.round(n / (1024 * 1024)).toFixed(1) + \" MB\";\n } else {\n return this.i18n`unknown`;\n }\n }\n\n async exportLogs() {\n const logs = await this.exportLogsBlob();\n this.platform.saveFileAs(logs, `hydrogen-logs-${this.platform.clock.now()}.json`);\n }\n\n async exportLogsBlob() {\n const persister = this.logger.reporters.find(r => typeof r.export === \"function\");\n const logExport = await persister.export();\n return logExport.asBlob();\n }\n\n get canSendLogsToServer() {\n return !!this.platform.config.bugReportEndpointUrl;\n }\n\n get logsServer() {\n const {bugReportEndpointUrl} = this.platform.config;\n try {\n if (bugReportEndpointUrl) {\n return new URL(bugReportEndpointUrl).hostname;\n }\n } catch (e) {}\n return \"\";\n }\n\n async sendLogsToServer() {\n this._logsFeedbackMessage = this.i18n`Sending logs…`;\n try {\n await submitLogsFromSessionToDefaultServer(this._session, this.platform);\n this._logsFeedbackMessage = this.i18n`Logs sent succesfully!`;\n } catch (err) {\n this._logsFeedbackMessage = err.message;\n this.emitChange();\n }\n }\n\n get logsFeedbackMessage() {\n return this._logsFeedbackMessage;\n }\n\n async togglePushNotifications() {\n this.pushNotifications.updating = true;\n this.pushNotifications.enabledOnServer = null;\n this.pushNotifications.serverError = null;\n this.emitChange(\"pushNotifications.updating\");\n try {\n if (await this._session.enablePushNotifications(!this.pushNotifications.enabled)) {\n this.pushNotifications.enabled = !this.pushNotifications.enabled;\n if (this.pushNotifications.enabled) {\n this.platform.notificationService.showNotification(this.i18n`Push notifications are now enabled`);\n }\n }\n } finally {\n this.pushNotifications.updating = false;\n this.emitChange(\"pushNotifications.updating\");\n }\n }\n\n async checkPushEnabledOnServer() {\n this.pushNotifications.enabledOnServer = null;\n this.pushNotifications.serverError = null;\n try {\n this.pushNotifications.enabledOnServer = await this._session.checkPusherEnabledOnHomeserver();\n this.emitChange(\"pushNotifications.enabledOnServer\");\n } catch (err) {\n this.pushNotifications.serverError = err;\n this.emitChange(\"pushNotifications.serverError\");\n }\n }\n\n changeThemeOption(themeName, themeVariant) {\n this.platform.themeLoader.setTheme(themeName, themeVariant);\n // emit so that radio-buttons become displayed/hidden\n this.emitChange(\"themeOption\");\n }\n}\n\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../ViewModel\";\nimport {imageToInfo} from \"./common.js\";\nimport {RoomType} from \"../../matrix/room/common\";\n\nexport class CreateRoomViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {session} = options;\n this._session = session;\n this._name = undefined;\n this._topic = undefined;\n this._roomAlias = undefined;\n this._isPublic = false;\n this._isEncrypted = true;\n this._isAdvancedShown = false;\n this._isFederationDisabled = false;\n this._avatarScaledBlob = undefined;\n this._avatarFileName = undefined;\n this._avatarInfo = undefined;\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n }\n\n get isPublic() { return this._isPublic; }\n get isEncrypted() { return this._isEncrypted; }\n get canCreate() { return !!this._name; }\n avatarUrl() { return this._avatarScaledBlob.url; }\n get avatarTitle() { return this._name; }\n get avatarLetter() { return \"\"; }\n get avatarColorNumber() { return 0; }\n get hasAvatar() { return !!this._avatarScaledBlob; }\n get isFederationDisabled() { return this._isFederationDisabled; }\n get isAdvancedShown() { return this._isAdvancedShown; }\n get closeUrl() { return this._closeUrl; }\n\n setName(name) {\n this._name = name;\n this.emitChange(\"canCreate\");\n }\n\n setRoomAlias(roomAlias) {\n this._roomAlias = roomAlias;\n }\n\n setTopic(topic) {\n this._topic = topic;\n }\n\n setPublic(isPublic) {\n this._isPublic = isPublic;\n this.emitChange(\"isPublic\");\n }\n\n setEncrypted(isEncrypted) {\n this._isEncrypted = isEncrypted;\n this.emitChange(\"isEncrypted\");\n }\n\n setFederationDisabled(disable) {\n this._isFederationDisabled = disable;\n this.emitChange(\"isFederationDisabled\");\n }\n\n toggleAdvancedShown() {\n this._isAdvancedShown = !this._isAdvancedShown;\n this.emitChange(\"isAdvancedShown\");\n }\n\n create() {\n let avatar;\n if (this._avatarScaledBlob) {\n avatar = {\n info: this._avatarInfo,\n name: this._avatarFileName,\n blob: this._avatarScaledBlob\n }\n }\n const roomBeingCreated = this._session.createRoom({\n type: this.isPublic ? RoomType.Public : RoomType.Private,\n name: this._name ?? undefined,\n topic: this._topic ?? undefined,\n isEncrypted: !this.isPublic && this._isEncrypted,\n isFederationDisabled: this._isFederationDisabled,\n alias: this.isPublic ? ensureAliasIsLocalPart(this._roomAlias) : undefined,\n avatar,\n });\n this.navigation.push(\"room\", roomBeingCreated.id);\n }\n\n async selectAvatar() {\n if (!this.platform.hasReadPixelPermission()) {\n alert(\"Please allow canvas image data access, so we can scale your images down.\");\n return;\n }\n if (this._avatarScaledBlob) {\n this._avatarScaledBlob.dispose();\n }\n this._avatarScaledBlob = undefined;\n this._avatarFileName = undefined;\n this._avatarInfo = undefined;\n\n const file = await this.platform.openFile(\"image/*\");\n if (!file || !file.blob.mimeType.startsWith(\"image/\")) {\n // allow to clear the avatar by not selecting an image\n this.emitChange(\"hasAvatar\");\n return;\n }\n let image = await this.platform.loadImage(file.blob);\n const limit = 800;\n if (image.maxDimension > limit) {\n const scaledImage = await image.scale(limit);\n image.dispose();\n image = scaledImage;\n }\n this._avatarScaledBlob = image.blob;\n this._avatarInfo = imageToInfo(image);\n this._avatarFileName = file.name;\n this.emitChange(\"hasAvatar\");\n }\n}\n\nfunction ensureAliasIsLocalPart(roomAliasLocalPart) {\n if (roomAliasLocalPart.startsWith(\"#\")) {\n roomAliasLocalPart = roomAliasLocalPart.substr(1);\n }\n const colonIdx = roomAliasLocalPart.indexOf(\":\");\n if (colonIdx !== -1) {\n roomAliasLocalPart = roomAliasLocalPart.substr(0, colonIdx);\n }\n return roomAliasLocalPart;\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel, Options as BaseOptions} from \"../ViewModel\";\nimport {SegmentType} from \"../navigation/index\";\nimport type {Session} from \"../../matrix/Session.js\";\nimport {joinRoom} from \"../../matrix/room/joinRoom\";\n\ntype Options = BaseOptions & {\n session: Session;\n};\n\nexport class JoinRoomViewModel extends ViewModel {\n private _session: Session;\n private _joinInProgress: boolean = false;\n private _error: Error | undefined;\n private _closeUrl: string;\n\n constructor(options: Readonly) {\n super(options);\n this._session = options.session;\n this._closeUrl = this.urlRouter.urlUntilSegment(\"session\");\n }\n\n get closeUrl(): string { return this._closeUrl; }\n\n async join(roomId: string): Promise {\n this._error = undefined;\n this._joinInProgress = true;\n this.emitChange(\"joinInProgress\");\n try {\n const id = await joinRoom(roomId, this._session);\n this.navigation.push(\"room\", id);\n }\n catch (e) {\n this._error = e;\n this._joinInProgress = false;\n this.emitChange(\"error\");\n }\n }\n\n get joinInProgress(): boolean {\n return this._joinInProgress;\n }\n\n get status(): string | undefined {\n if (this._error) {\n return this._error.message;\n } \n else if(this._joinInProgress){\n return \"Joining room\";\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel, Options as BaseOptions} from \"../../../ViewModel\";\nimport {SegmentType} from \"../../../navigation/index\";\nimport type {SASVerification} from \"../../../../matrix/verification/SAS/SASVerification\";\n\ntype Options = BaseOptions & {\n sas: SASVerification;\n};\n\nexport class WaitingForOtherUserViewModel extends ViewModel {\n async cancel() {\n await this.options.sas.abort();\n }\n\n get title() {\n const message = this.getOption(\"sas\").isCrossSigningAnotherUser\n ? \"Waiting for the other user to accept the verification request\"\n : \"Waiting for any of your device to accept the verification request\";\n return this.i18n`${message}`;\n }\n\n get description() {\n const message = this.getOption(\"sas\").isCrossSigningAnotherUser\n ? \"Ask the other user to accept the request from their client!\"\n : \"Accept the request from the device you wish to verify!\";\n return this.i18n`${message}`;\n }\n\n get kind(): string {\n return \"waiting-for-user\";\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SegmentType} from \"../../../navigation/index\";\nimport {ErrorReportViewModel} from \"../../../ErrorReportViewModel\";\nimport type {Options as BaseOptions} from \"../../../ViewModel\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {SASVerification} from \"../../../../matrix/verification/SAS/SASVerification\";\n\ntype Options = BaseOptions & {\n sas: SASVerification;\n session: Session;\n};\n\nexport abstract class DismissibleVerificationViewModel extends ErrorReportViewModel {\n dismiss(): void {\n /**\n * If we're cross-signing another user, redirect to the room (which will just close the right panel).\n * If we're verifying a device, redirect to settings.\n */\n if (this.getOption(\"sas\").isCrossSigningAnotherUser) {\n const path = this.navigation.path.until(\"room\");\n this.navigation.applyPath(path);\n } else {\n this.navigation.push(\"settings\", true);\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Options as BaseOptions} from \"../../../ViewModel\";\nimport {DismissibleVerificationViewModel} from \"./DismissibleVerificationViewModel\";\nimport {CancelReason} from \"../../../../matrix/verification/SAS/channel/types\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {IChannel} from \"../../../../matrix/verification/SAS/channel/IChannel\";\nimport type {SASVerification} from \"../../../../matrix/verification/SAS/SASVerification\";\n\ntype Options = BaseOptions & {\n cancellation: IChannel[\"cancellation\"];\n session: Session;\n sas: SASVerification; \n};\n\nexport class VerificationCancelledViewModel extends DismissibleVerificationViewModel {\n get cancelCode(): CancelReason {\n return this.options.cancellation!.code;\n }\n\n get isCancelledByUs(): boolean {\n return this.options.cancellation!.cancelledByUs;\n }\n\n get kind(): string {\n return \"verification-cancelled\";\n }\n\n get title(): string {\n if (this.isCancelledByUs) {\n return this.i18n`You cancelled the verification!`;\n }\n if (this.getOption(\"sas\").isCrossSigningAnotherUser) {\n return this.i18n`The other user cancelled the verification!`;\n }\n else {\n return this.i18n`The other device cancelled the verification!`;\n }\n }\n\n get description(): string {\n const descriptionsWhenWeCancelledForDeviceVerification = {\n [CancelReason.InvalidMessage]: \"Your other device sent an invalid message.\",\n [CancelReason.KeyMismatch]: \"The key could not be verified.\",\n [CancelReason.TimedOut]: \"The verification process timed out.\",\n [CancelReason.UnexpectedMessage]: \"Your other device sent an unexpected message.\",\n [CancelReason.UnknownMethod]: \"Your other device is using an unknown method for verification.\",\n [CancelReason.UnknownTransaction]: \"Your other device sent a message with an unknown transaction id.\",\n [CancelReason.UserMismatch]: \"The expected user did not match the user verified.\",\n [CancelReason.MismatchedCommitment]: \"The hash commitment does not match.\",\n [CancelReason.MismatchedSAS]: \"The emoji/decimal did not match.\",\n }\n const descriptionsWhenTheyCancelledForDeviceVerification = {\n [CancelReason.UserCancelled]: \"Your other device cancelled the verification!\",\n [CancelReason.InvalidMessage]: \"Invalid message sent to the other device.\",\n [CancelReason.KeyMismatch]: \"The other device could not verify our keys\",\n [CancelReason.TimedOut]: \"The verification process timed out.\",\n [CancelReason.UnexpectedMessage]: \"Unexpected message sent to the other device.\",\n [CancelReason.UnknownMethod]: \"Your other device does not understand the method you chose\",\n [CancelReason.UnknownTransaction]: \"Your other device rejected our message.\",\n [CancelReason.UserMismatch]: \"The expected user did not match the user verified.\",\n [CancelReason.MismatchedCommitment]: \"Your other device was not able to verify the hash commitment\",\n [CancelReason.MismatchedSAS]: \"The emoji/decimal did not match.\",\n }\n const descriptionsWhenWeCancelledForCrossSigning = {\n [CancelReason.InvalidMessage]: \"The other user sent an invalid message.\",\n [CancelReason.KeyMismatch]: \"The key could not be verified.\",\n [CancelReason.TimedOut]: \"The verification process timed out.\",\n [CancelReason.UnexpectedMessage]: \"The other user sent an unexpected message.\",\n [CancelReason.UnknownMethod]: \"The other user is using an unknown method for verification.\",\n [CancelReason.UnknownTransaction]: \"The other user sent a message with an unknown transaction id.\",\n [CancelReason.UserMismatch]: \"The expected user did not match the user verified.\",\n [CancelReason.MismatchedCommitment]: \"The hash commitment does not match.\",\n [CancelReason.MismatchedSAS]: \"The emoji/decimal did not match.\",\n }\n const descriptionsWhenTheyCancelledForCrossSigning = {\n [CancelReason.UserCancelled]: \"The other user cancelled the verification!\",\n [CancelReason.InvalidMessage]: \"Invalid message sent to the other user.\",\n [CancelReason.KeyMismatch]: \"The other user could not verify our keys\",\n [CancelReason.TimedOut]: \"The verification process timed out.\",\n [CancelReason.UnexpectedMessage]: \"Unexpected message sent to the other user.\",\n [CancelReason.UnknownMethod]: \"The other user does not understand the method you chose\",\n [CancelReason.UnknownTransaction]: \"The other user rejected our message.\",\n [CancelReason.UserMismatch]: \"The expected user did not match the user verified.\",\n [CancelReason.MismatchedCommitment]: \"The other user was not able to verify the hash commitment\",\n [CancelReason.MismatchedSAS]: \"The emoji/decimal did not match.\",\n }\n let map;\n if (this.getOption(\"sas\").isCrossSigningAnotherUser) {\n map = this.isCancelledByUs ? descriptionsWhenWeCancelledForCrossSigning : descriptionsWhenTheyCancelledForCrossSigning;\n } else {\n map = this.isCancelledByUs ? descriptionsWhenWeCancelledForDeviceVerification : descriptionsWhenTheyCancelledForDeviceVerification;\n }\n const description = map[this.cancelCode] ?? \"\"\n return this.i18n`${description}`;\n \n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SegmentType} from \"../../../navigation/index\";\nimport {ErrorReportViewModel} from \"../../../ErrorReportViewModel\";\nimport type {Options as BaseOptions} from \"../../../ViewModel\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {SASVerification} from \"../../../../matrix/verification/SAS/SASVerification\";\nimport type {SelectVerificationMethodStage} from \"../../../../matrix/verification/SAS/stages/SelectVerificationMethodStage\";\n\ntype Options = BaseOptions & {\n sas: SASVerification;\n stage: SelectVerificationMethodStage;\n session: Session;\n};\n\nexport class SelectMethodViewModel extends ErrorReportViewModel {\n public hasProceeded: boolean = false;\n\n async proceed() {\n await this.logAndCatch(\"SelectMethodViewModel.proceed\", async (log) => {\n await this.options.stage.selectEmojiMethod(log);\n this.hasProceeded = true;\n this.emitChange(\"hasProceeded\");\n });\n }\n\n async cancel() {\n await this.logAndCatch(\"SelectMethodViewModel.cancel\", async () => {\n await this.options.sas.abort();\n });\n }\n\n get deviceName() {\n return this.options.stage.otherDeviceName;\n }\n\n get otherUserId() {\n return this.getOption(\"sas\").otherUserId;\n }\n\n get kind(): string {\n return \"select-method\";\n }\n\n get isCrossSigningAnotherUser(): boolean {\n return this.getOption(\"sas\").isCrossSigningAnotherUser;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SegmentType} from \"../../../navigation/index\";\nimport {ErrorReportViewModel} from \"../../../ErrorReportViewModel\";\nimport type {Options as BaseOptions} from \"../../../ViewModel\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {CalculateSASStage} from \"../../../../matrix/verification/SAS/stages/CalculateSASStage\";\n\ntype Options = BaseOptions & {\n stage: CalculateSASStage;\n session: Session;\n};\n\nexport class VerifyEmojisViewModel extends ErrorReportViewModel {\n private _isWaiting: boolean = false;\n\n async setEmojiMatch(match: boolean) {\n await this.logAndCatch(\"VerifyEmojisViewModel.setEmojiMatch\", async () => {\n await this.options.stage.setEmojiMatch(match);\n this._isWaiting = true;\n this.emitChange(\"isWaiting\");\n });\n }\n\n get emojis() {\n return this.options.stage.emoji;\n }\n\n get kind(): string {\n return \"verify-emojis\";\n }\n\n get isWaiting(): boolean {\n return this._isWaiting;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {DismissibleVerificationViewModel} from \"./DismissibleVerificationViewModel\";\nimport type {Options as BaseOptions} from \"../../../ViewModel\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {SASVerification} from \"../../../../matrix/verification/SAS/SASVerification\";\n\ntype Options = BaseOptions & {\n deviceId: string;\n session: Session;\n sas: SASVerification;\n};\n\nexport class VerificationCompleteViewModel extends DismissibleVerificationViewModel {\n get otherDeviceId(): string {\n return this.options.deviceId;\n }\n\n get otherUsername(): string {\n return this.getOption(\"sas\").otherUserId;\n }\n\n get kind(): string {\n return \"verification-completed\";\n }\n\n get verificationSuccessfulMessage(): string {\n if (this.getOption(\"sas\").isCrossSigningAnotherUser) {\n return this.i18n`You successfully verified user ${this.otherUsername}`;\n }\n else {\n return this.i18n`You successfully verified device ${this.otherDeviceId}`;\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel, Options} from \"../../../ViewModel\";\nimport type {SegmentType} from \"../../../navigation/index\";\n\nexport class MissingKeysViewModel extends ViewModel {\n gotoSettings() {\n this.navigation.push(\"settings\", true);\n }\n\n get kind(): string {\n return \"keys-missing\";\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Options as BaseOptions} from \"../../ViewModel\";\nimport {SegmentType} from \"../../navigation/index\";\nimport {ErrorReportViewModel} from \"../../ErrorReportViewModel\";\nimport {WaitingForOtherUserViewModel} from \"./stages/WaitingForOtherUserViewModel\";\nimport {VerificationCancelledViewModel} from \"./stages/VerificationCancelledViewModel\";\nimport {SelectMethodViewModel} from \"./stages/SelectMethodViewModel\";\nimport {VerifyEmojisViewModel} from \"./stages/VerifyEmojisViewModel\";\nimport {VerificationCompleteViewModel} from \"./stages/VerificationCompleteViewModel\";\nimport {MissingKeysViewModel} from \"./stages/MissingKeysViewModel\";\nimport type {Session} from \"../../../matrix/Session.js\";\nimport type {SASVerification} from \"../../../matrix/verification/SAS/SASVerification\";\nimport type {SASRequest} from \"../../../matrix/verification/SAS/SASRequest\";\nimport type {CrossSigning} from \"../../../matrix/verification/CrossSigning\";\nimport type {ILogItem} from \"../../../logging/types\";\nimport type {Room} from \"../../../matrix/room/Room.js\";\n\ntype Options = BaseOptions & {\n session: Session;\n request?: SASRequest;\n room?: Room;\n userId?: string;\n};\n\nconst neededSecrets = [\n \"m.cross_signing.master\",\n \"m.cross_signing.self_signing\",\n \"m.cross_signing.user_signing\",\n];\n\nexport class DeviceVerificationViewModel extends ErrorReportViewModel {\n private sas: SASVerification;\n private _currentStageViewModel: any;\n private _needsToRequestSecret: boolean;\n\n constructor(options: Readonly) {\n super(options);\n this.start(options);\n }\n\n private async start(options: Options): Promise {\n const room = options.room;\n let requestOrUserId: SASRequest | string;\n requestOrUserId =\n options.request ??\n options.userId ??\n this.getOption(\"session\").userId;\n await this.startVerification(requestOrUserId, room);\n }\n\n private async startVerification(requestOrUserId: SASRequest | string, room?: Room) {\n await this.logAndCatch(\"DeviceVerificationViewModel.startVerification\", async (log) => {\n const crossSigningObservable = this.getOption(\"session\").crossSigning;\n const crossSigning = await crossSigningObservable.waitFor(c => !!c).promise;\n this.sas = crossSigning.startVerification(requestOrUserId, room, log);\n if (!this.sas) {\n throw new Error(\"CrossSigning.startVerification did not return a sas object!\");\n }\n if (!await this.performPreVerificationChecks(crossSigning, requestOrUserId, log)) {\n return;\n }\n this.addEventListeners();\n if (typeof requestOrUserId === \"string\") {\n this.updateCurrentStageViewModel(new WaitingForOtherUserViewModel(this.childOptions({ sas: this.sas })));\n }\n if (this.sas.isCrossSigningAnotherUser) {\n return crossSigning.signUser(this.sas, log);\n }\n else {\n return crossSigning.signDevice(this.sas, log);\n }\n });\n }\n\n private async performPreVerificationChecks(crossSigning: CrossSigning, requestOrUserId: SASRequest | string, log: ILogItem): Promise {\n return await log.wrap(\"DeviceVerificationViewModel.performPreVerificationChecks\", async (_log) => {\n const areWeVerified = await crossSigning.areWeVerified(log);\n // If we're not verified, we'll need to ask the other device for secrets later\n const otherUserId = typeof requestOrUserId === \"string\" ? requestOrUserId : requestOrUserId.sender;\n const isDeviceVerification = otherUserId === this.getOption(\"session\").userId;\n this._needsToRequestSecret = isDeviceVerification && !areWeVerified;\n if (this._needsToRequestSecret) {\n return true;\n }\n /**\n * It's possible that we are verified but don't have access\n * to the private cross-signing keys. In this case we really\n * can't verify the other device because we need these keys\n * to sign their device. \n * \n * If this happens, we'll simply ask the user to enable key-backup\n * (and secret storage) and try again later.\n */\n const session = this.getOption(\"session\");\n const promises = neededSecrets.map(s => session.secretFetcher.getSecret(s));\n const secrets = await Promise.all(promises)\n for (const secret of secrets) {\n if (!secret) {\n // We really can't proceed!\n this.updateCurrentStageViewModel(new MissingKeysViewModel(this.childOptions({})));\n return false;\n }\n }\n return true;\n });\n }\n \n private addEventListeners() {\n this.track(this.sas.disposableOn(\"SelectVerificationStage\", (stage) => {\n this.updateCurrentStageViewModel(\n new SelectMethodViewModel(this.childOptions({ sas: this.sas, stage: stage!, }))\n );\n }));\n this.track(this.sas.disposableOn(\"EmojiGenerated\", (stage) => {\n this.updateCurrentStageViewModel(\n new VerifyEmojisViewModel(this.childOptions({ stage: stage!, }))\n );\n }));\n this.track(this.sas.disposableOn(\"VerificationCancelled\", (cancellation) => {\n this.updateCurrentStageViewModel(\n new VerificationCancelledViewModel(\n this.childOptions({ cancellation: cancellation!, sas: this.sas })\n )\n );\n }));\n this.track(this.sas.disposableOn(\"VerificationCompleted\", (deviceId) => {\n this.updateCurrentStageViewModel(\n new VerificationCompleteViewModel(this.childOptions({ deviceId: deviceId!, sas: this.sas }))\n );\n this.requestSecrets();\n }));\n }\n\n private async requestSecrets() {\n await this.platform.logger.run(\"DeviceVerificationViewModel.requestSecrets\", async (log) => {\n if (this._needsToRequestSecret) {\n const secretSharing = this.getOption(\"session\").secretSharing;\n const requestPromises = neededSecrets.map((secret) => secretSharing.requestSecret(secret, log));\n const secretRequests = await Promise.all(requestPromises);\n const receivedSecretPromises = secretRequests.map(r => r.waitForResponse());\n await Promise.all(receivedSecretPromises);\n const crossSigning = this.getOption(\"session\").crossSigning.get();\n crossSigning.start(log);\n }\n });\n }\n\n private updateCurrentStageViewModel(vm) {\n this._currentStageViewModel = this.disposeTracked(this._currentStageViewModel);\n this._currentStageViewModel = this.track(vm);\n this.emitChange(\"currentStageViewModel\");\n }\n\n dispose(): void {\n if (this.sas && !this.sas.finished) {\n this.sas.abort().catch((e) => { console.error(e); });\n }\n super.dispose();\n }\n\n get currentStageViewModel() {\n return this._currentStageViewModel;\n }\n\n get type(): string { \n return \"verification\";\n }\n\n get isHappeningInRoom(): boolean {\n return !!this.navigation.path.get(\"room\");\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableValue} from \"../../observable/value\";\nimport {RoomStatus} from \"../../matrix/room/common\";\n\n/**\nDepending on the status of a room (invited, joined, archived, or none),\nwe want to show a different view with a different view model\nwhen showing a room. Furthermore, this logic is needed both in the \nsingle room view and in the grid view. So this logic is extracted here,\nand this observable updates with the right view model as the status for\na room changes.\n\nTo not have to track the subscription manually in the SessionViewModel and\nthe RoomGridViewModel, all subscriptions are removed in the dispose method.\nOnly when transferring a RoomViewModelObservable between the SessionViewModel\nand RoomGridViewModel, unsubscribeAll should be called prior to doing\nthe transfer, so either parent view model don't keep getting updates for\nthe now transferred child view model.\n\nThis is also why there is an explicit initialize method, see comment there.\n*/\nexport class RoomViewModelObservable extends ObservableValue {\n constructor(sessionViewModel, roomIdOrLocalId) {\n super(null);\n this._statusSubscription = null;\n this._sessionViewModel = sessionViewModel;\n this.id = roomIdOrLocalId;\n }\n\n /**\n Separate initialize method rather than doing this onSubscribeFirst because \n we don't want to run this again when transferring this value between\n SessionViewModel and RoomGridViewModel, as onUnsubscribeLast and onSubscribeFirst\n are called in that case.\n */\n async initialize() {\n const {session} = this._sessionViewModel._client;\n const statusObservable = await session.observeRoomStatus(this.id);\n this.set(await this._statusToViewModel(statusObservable.get()));\n this._statusSubscription = statusObservable.subscribe(async status => {\n // first dispose existing VM, if any\n this.get()?.dispose();\n this.set(await this._statusToViewModel(status));\n });\n }\n\n async _statusToViewModel(status) {\n if (status & RoomStatus.Replaced) {\n if (status & RoomStatus.BeingCreated) {\n const {session} = this._sessionViewModel._client;\n const roomBeingCreated = session.roomsBeingCreated.get(this.id);\n this._sessionViewModel.notifyRoomReplaced(roomBeingCreated.id, roomBeingCreated.roomId);\n } else {\n throw new Error(\"Don't know how to replace a room with this status: \" + (status ^ RoomStatus.Replaced));\n }\n } else if (status & RoomStatus.BeingCreated) {\n return this._sessionViewModel._createRoomBeingCreatedViewModel(this.id);\n } else if (status & RoomStatus.Invited) {\n return this._sessionViewModel._createInviteViewModel(this.id);\n } else if (status & RoomStatus.Joined) {\n return this._sessionViewModel._createRoomViewModelInstance(this.id);\n } else if (status & RoomStatus.Archived) {\n return await this._sessionViewModel._createArchivedRoomViewModel(this.id);\n } else {\n return this._sessionViewModel._createUnknownRoomViewModel(this.id);\n }\n }\n\n dispose() {\n if (this._statusSubscription) {\n this._statusSubscription = this._statusSubscription();\n }\n this.unsubscribeAll();\n this.get()?.dispose();\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\n\nexport class RoomDetailsViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._room = options.room;\n this._onRoomChange = this._onRoomChange.bind(this);\n this._room.on(\"change\", this._onRoomChange);\n }\n\n get type() {\n return \"room-details\";\n }\n\n get shouldShowBackButton() {\n return false;\n }\n\n get previousSegmentName() {\n return false;\n }\n\n get roomId() {\n return this._room.id;\n }\n\n get canonicalAlias() {\n return this._room.canonicalAlias;\n }\n\n get name() {\n return this._room.name;\n }\n\n get isEncrypted() {\n return !!this._room.isEncrypted;\n }\n\n get memberCount() {\n return this._room.joinedMemberCount;\n }\n\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._room.avatarColorId)\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._room.avatarUrl, size, this.platform, this._room.mediaRepository);\n }\n\n get avatarTitle() {\n return this.name;\n }\n\n _onRoomChange() {\n this.emitChange();\n }\n\n dispose() {\n super.dispose();\n this._room.off(\"change\", this._onRoomChange);\n }\n\n openPanel(segment) {\n let path = this.navigation.path.until(\"room\");\n path = path.with(this.navigation.segment(\"right-panel\", true));\n path = path.with(this.navigation.segment(segment, true));\n this.navigation.applyPath(path);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\n\nexport class MemberTileViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._member = this._options.member;\n this._mediaRepository = options.mediaRepository\n this._previousName = null;\n this._nameChanged = true;\n }\n\n get name() {\n return `${this._member.name}${this._disambiguationPart}`;\n }\n\n get _disambiguationPart() {\n return this._disambiguate ? ` (${this.userId})` : \"\";\n }\n\n get userId() {\n return this._member.userId;\n }\n\n get previousName() {\n return this._previousName;\n }\n\n get nameChanged() {\n return this._nameChanged;\n }\n\n get detailsUrl() {\n const roomId = this.navigation.path.get(\"room\").value;\n return `${this.urlRouter.openRoomActionUrl(roomId)}/member/${encodeURIComponent(this._member.userId)}`;\n }\n\n _updatePreviousName(newName) {\n const currentName = this._member.name;\n if (currentName !== newName) {\n this._previousName = currentName;\n this._nameChanged = true;\n } else {\n this._nameChanged = false;\n }\n }\n\n setDisambiguation(status) {\n this._disambiguate = status;\n this.emitChange();\n }\n\n updateFrom(newMember) {\n this._updatePreviousName(newMember.name);\n this._member = newMember;\n }\n\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this.userId)\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._member.avatarUrl, size, this.platform, this._mediaRepository);\n }\n\n get avatarTitle() {\n return this.name;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {PowerLevels} from \"../../../../matrix/room/PowerLevels.js\";\n\nexport function createMemberComparator(powerLevels) {\n const collator = new Intl.Collator();\n const removeCharacter = string => string.charAt(0) === \"@\"? string.slice(1) : string;\n\n return function comparator(member, otherMember) {\n const p1 = powerLevels.getUserLevel(member.userId);\n const p2 = powerLevels.getUserLevel(otherMember.userId);\n if (p1 !== p2) { return p2 - p1; }\n const name = removeCharacter(member.name);\n const otherName = removeCharacter(otherMember.name);\n return collator.compare(name, otherName);\n };\n}\n\nexport function tests() {\n\n function createComparatorWithPowerLevel(map) {\n let users = {};\n for (const prop in map) {\n Object.assign(users, {[prop]: map[prop]});\n }\n const powerLevelEvent = {\n content: {users, users_default: 0}\n };\n return createMemberComparator(new PowerLevels({powerLevelEvent}));\n }\n\n return {\n \"power_level(member1) > power_level(member2) returns value <= 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@alice:hs.tld\": 50});\n const member1 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n const member2 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n assert.strictEqual(fn(member1, member2) <= 0, true);\n },\n\n \"power_level(member1) < power_level(member2) returns value > 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@alice:hs.tld\": 50});\n const member1 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n const member2 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n assert.strictEqual(fn(member1, member2) > 0, true);\n },\n\n \"alphabetic compare on name\": assert => {\n const fn = createComparatorWithPowerLevel();\n const member1 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n const member2 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n assert.strictEqual(fn(member1, member2) > 0, true);\n assert.strictEqual(fn(member2, member1) <= 0, true);\n },\n\n \"alphabetic compare with case (alice comes before Bob)\": assert => {\n const fn = createComparatorWithPowerLevel();\n const member1 = {userId: \"@bob:hs.tld\", name: \"Bob\"};\n const member2 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n assert.strictEqual(fn(member1, member2) > 0, true);\n assert.strictEqual(fn(member2, member1) <= 0, true);\n },\n\n \"equal powerlevel and same names returns 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@bobby:hs.tld\": 50, \"@bob:hs.tld\": 50});\n const member1 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n const member2 = {userId: \"@bobby:hs.tld\", name: \"bob\"};\n assert.strictEqual(fn(member1, member2), 0);\n assert.strictEqual(fn(member2, member1), 0);\n },\n\n \"(both_negative_powerlevel) power_level(member1) < power_level(member2) returns value > 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@alice:hs.tld\": -100, \"@bob:hs.tld\": -50});\n const member1 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n const member2 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n assert.strictEqual(fn(member1, member2) > 0, true);\n },\n\n \"(both_negative_powerlevel) power_level(member1) > power_level(member2) returns value <= 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@alice:hs.tld\": -50, \"@bob:hs.tld\": -100});\n const member1 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n const member2 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n assert.strictEqual(fn(member1, member2) <= 0, true);\n },\n\n \"(one_negative_powerlevel) power_level(member1) > power_level(member2) returns value <= 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@alice:hs.tld\": 50, \"@bob:hs.tld\": -100});\n const member1 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n const member2 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n assert.strictEqual(fn(member1, member2) <= 0, true);\n },\n\n \"(one_negative_powerlevel) power_level(member1) < power_level(member2) returns value > 0\": assert => {\n const fn = createComparatorWithPowerLevel({\"@alice:hs.tld\": -100, \"@bob:hs.tld\": 50});\n const member1 = {userId: \"@alice:hs.tld\", name: \"alice\"};\n const member2 = {userId: \"@bob:hs.tld\", name: \"bob\"};\n assert.strictEqual(fn(member1, member2) > 0, true);\n },\n };\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class Disambiguator {\n constructor() {\n this._map = new Map();\n }\n\n _unDisambiguate(vm, array) {\n const idx = array.indexOf(vm);\n if (idx !== -1) {\n const [removed] = array.splice(idx, 1);\n removed.setDisambiguation(false);\n }\n }\n\n _handlePreviousName(vm) {\n const previousName = vm.previousName;\n if (typeof previousName !== \"string\") { return; }\n const value = this._map.get(previousName);\n if (Array.isArray(value)) {\n this._unDisambiguate(vm, value);\n if (value.length === 1) {\n const vm = value[0];\n vm.setDisambiguation(false);\n this._map.set(previousName, vm);\n }\n } else {\n this._map.delete(previousName);\n }\n }\n\n _updateMap(vm) {\n const name = vm.name;\n const value = this._map.get(name);\n if (value) {\n if (Array.isArray(value)) {\n if (value.findIndex(member => member.userId === vm.userId) !== -1) { return; }\n value.push(vm);\n return value;\n } else if(vm.userId !== value.userId) {\n const array = [value, vm]\n this._map.set(name, array);\n return array;\n }\n } else {\n this._map.set(name, vm);\n }\n }\n\n disambiguate(vm) {\n if (!vm.nameChanged) { return; }\n this._handlePreviousName(vm);\n const value = this._updateMap(vm);\n value?.forEach((vm) => vm.setDisambiguation(true));\n }\n}\n\nexport function tests(){\n\n class MockViewModel {\n constructor(name, userId) {\n this.name = name;\n this.disambiguate = false;\n this.userId = userId;\n this.nameChanged = true;\n }\n \n updateName(newName) {\n if (this.name !== newName) {\n this.previousName = this.name;\n this.nameChanged = true;\n }\n else {\n this.nameChanged = false;\n }\n this.name = newName;\n }\n\n setDisambiguation(status) {\n this.disambiguate = status;\n }\n }\n\n function createVmAndDisambiguator(nameList) {\n const d = new Disambiguator();\n const array = nameList.map(([name, id]) => new MockViewModel(name, id));\n return [...array, d];\n }\n\n return {\n \"Unique names\": assert => {\n const [vm1, vm2, d] = createVmAndDisambiguator([[\"foo\", \"a\"], [\"bar\", \"b\"]]);\n d.disambiguate(vm1);\n d.disambiguate(vm2);\n assert.strictEqual(vm1.disambiguate, false);\n assert.strictEqual(vm2.disambiguate, false);\n },\n\n \"Same names are disambiguated\": assert => {\n const [vm1, vm2, vm3, d] = createVmAndDisambiguator([[\"foo\", \"a\"], [\"foo\", \"b\"], [\"foo\", \"c\"]]);\n d.disambiguate(vm1);\n d.disambiguate(vm2);\n d.disambiguate(vm3);\n assert.strictEqual(vm1.disambiguate, true);\n assert.strictEqual(vm2.disambiguate, true);\n assert.strictEqual(vm3.disambiguate, true);\n },\n\n \"Name updates disambiguate\": assert => {\n const [vm1, vm2, vm3, d] = createVmAndDisambiguator([[\"foo\", \"a\"], [\"bar\", \"b\"], [\"jar\", \"c\"]]);\n d.disambiguate(vm1);\n d.disambiguate(vm2);\n d.disambiguate(vm3);\n \n vm2.updateName(\"foo\");\n d.disambiguate(vm2);\n assert.strictEqual(vm1.disambiguate, true);\n assert.strictEqual(vm2.disambiguate, true);\n\n vm1.updateName(\"bar\");\n d.disambiguate(vm1);\n assert.strictEqual(vm1.disambiguate, false);\n assert.strictEqual(vm2.disambiguate, false);\n\n vm3.updateName(\"foo\");\n d.disambiguate(vm3);\n vm1.updateName(\"foo\");\n d.disambiguate(vm1);\n assert.strictEqual(vm1.disambiguate, true);\n assert.strictEqual(vm2.disambiguate, true);\n assert.strictEqual(vm3.disambiguate, true);\n\n vm2.updateName(\"bar\");\n d.disambiguate(vm2);\n assert.strictEqual(vm1.disambiguate, true);\n assert.strictEqual(vm2.disambiguate, false);\n assert.strictEqual(vm3.disambiguate, true);\n },\n\n \"Multiple disambiguate events\": assert => {\n const [vm1, d] = createVmAndDisambiguator([[\"foo\", \"a\"]]);\n d.disambiguate(vm1);\n vm1.updateName(vm1.name);\n d.disambiguate(vm1);\n assert.strictEqual(vm1.disambiguate, false);\n },\n\n \"Empty names must un-disambiguate\": assert => {\n const [vm1, vm2, d] = createVmAndDisambiguator([[\"\", \"a\"], [\"\", \"b\"]]);\n d.disambiguate(vm1);\n d.disambiguate(vm2);\n vm1.updateName(\"foo\");\n d.disambiguate(vm1);\n assert.strictEqual(vm1.disambiguate, false);\n assert.strictEqual(vm2.disambiguate, false);\n }\n };\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {MemberTileViewModel} from \"./MemberTileViewModel.js\";\nimport {createMemberComparator} from \"./members/comparator.js\";\nimport {Disambiguator} from \"./members/disambiguator.js\";\n\nexport class MemberListViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const list = options.members;\n\n const powerLevelsObservable = options.powerLevelsObservable;\n this.track(powerLevelsObservable.subscribe(() => { /*resort based on new power levels here*/ }));\n\n const powerLevels = powerLevelsObservable.get();\n this.memberTileViewModels = this._mapTileViewModels(list.members.filterValues(member => member.membership === \"join\"))\n .sortValues(createMemberComparator(powerLevels));\n this.nameDisambiguator = new Disambiguator();\n this.mediaRepository = options.mediaRepository;\n }\n\n get type() { return \"member-list\"; }\n\n get shouldShowBackButton() { return true; }\n\n get previousSegmentName() { return \"details\"; }\n\n _mapTileViewModels(members) {\n const mapper = (member, emitChange) => {\n const mediaRepository = this.mediaRepository;\n const vm = new MemberTileViewModel(this.childOptions({member, emitChange, mediaRepository}));\n this.nameDisambiguator.disambiguate(vm);\n return vm;\n };\n const updater = (params, vm, newMember) => {\n vm.updateFrom(newMember);\n this.nameDisambiguator.disambiguate(vm);\n };\n return members.mapValues(mapper, updater);\n }\n\n openInvitePanel() {\n let path = this.navigation.path.until(\"room\");\n path = path.with(this.navigation.segment(\"right-panel\", true));\n path = path.with(this.navigation.segment(\"invite\", true));\n this.navigation.applyPath(path);\n }\n\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {RoomType} from \"../../../matrix/room/common\";\nimport {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../avatar\";\nimport {UserTrust} from \"../../../matrix/verification/CrossSigning\";\nimport {RoomStatus} from \"../../../matrix/room/common\";\n\nexport class MemberDetailsViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._observableMember = options.observableMember;\n this._mediaRepository = options.mediaRepository;\n this._member = this._observableMember.get();\n this._isEncrypted = options.isEncrypted;\n this._powerLevelsObservable = options.powerLevelsObservable;\n this._session = options.session;\n this.track(this._powerLevelsObservable.subscribe(() => this._onPowerLevelsChange()));\n this.track(this._observableMember.subscribe( () => this._onMemberChange()));\n this._userTrust = undefined;\n this._userTrustSubscription = undefined;\n if (this.features.crossSigning) {\n this.track(this._session.crossSigning.subscribe(() => {\n this._onCrossSigningChange();\n }));\n }\n this._onCrossSigningChange();\n }\n\n get name() { return this._member.name; }\n \n get userId() { return this._member.userId; }\n\n get canVerifyUser() { return this._member.userId !== this._session.userId; }\n \n get trustDescription() {\n switch (this._userTrust?.get()) {\n case UserTrust.Trusted: return this.i18n`You have verified this user. This user has verified all of their sessions.`;\n case UserTrust.UserNotSigned: return this.i18n`You have not verified this user.`;\n case UserTrust.UserSignatureMismatch: return this.i18n`You appear to have signed this user, but the signature is invalid.`;\n case UserTrust.UserDeviceNotSigned: return this.i18n`You have verified this user, but they have one or more unverified sessions.`;\n case UserTrust.UserDeviceSignatureMismatch: return this.i18n`This user has a session signature that is invalid.`;\n case UserTrust.UserSetupError: return this.i18n`This user hasn't set up cross-signing correctly`;\n case UserTrust.OwnSetupError: return this.i18n`Cross-signing wasn't set up correctly on your side.`;\n case undefined:\n default: // adding default as well because jslint can't check for switch exhaustiveness\n return this.i18n`Please wait…`;\n }\n }\n\n get trustShieldColor() {\n if (!this._isEncrypted) {\n return \"\";\n }\n switch (this._userTrust?.get()) {\n case undefined:\n case UserTrust.OwnSetupError:\n return \"\";\n case UserTrust.Trusted:\n return \"green\";\n case UserTrust.UserNotSigned:\n return \"black\";\n default:\n return \"red\";\n }\n }\n\n get type() { return \"member-details\"; }\n \n get shouldShowBackButton() { return true; }\n \n get previousSegmentName() { return \"members\"; }\n \n get role() {\n if (this.powerLevel >= 100) { return this.i18n`Admin`; }\n else if (this.powerLevel >= 50) { return this.i18n`Moderator`; }\n else if (this.powerLevel === 0) { return this.i18n`Default`; }\n else { return this.i18n`Custom (${this.powerLevel})`; }\n }\n\n _onMemberChange() {\n this._member = this._observableMember.get();\n this.emitChange(\"member\");\n }\n\n _onPowerLevelsChange() {\n this.emitChange(\"role\");\n }\n\n async signUser() {\n const crossSigning = this._session.crossSigning.get();\n if (crossSigning) {\n await this.logger.run(\"MemberDetailsViewModel.signUser\", async log => {\n await crossSigning.signUser(this.userId, log);\n });\n }\n }\n\n async verifyUser() {\n await this.logger.run(\"MemberDetailsViewModel.verifyUser\", async () => {\n const room = this._session.findDirectMessageForUserId(this.userId);\n let roomId = room?.id;\n if (!roomId) {\n const roomBeingCreated = await this._session.createRoom({\n type: RoomType.DirectMessage,\n invites: [this.userId]\n });\n roomId = roomBeingCreated.roomId;\n }\n const observable = await this._session.observeRoomStatus(roomId);\n await observable.waitFor(s => s === RoomStatus.Joined).promise;\n let path = this.navigation.path.until(\"session\");\n path = path.with(this.navigation.segment(\"room\", roomId));\n path = path.with(this.navigation.segment(\"right-panel\", true));\n path = path.with(this.navigation.segment(\"verification\", this.userId));\n this.navigation.applyPath(path);\n });\n }\n\n get avatarLetter() {\n return avatarInitials(this.name);\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this.userId)\n }\n\n avatarUrl(size) {\n return getAvatarHttpUrl(this._member.avatarUrl, size, this.platform, this._mediaRepository);\n }\n\n get avatarTitle() {\n return this.name;\n }\n\n get isEncrypted() {\n return this._isEncrypted;\n }\n\n get powerLevel() {\n return this._powerLevelsObservable.get()?.getUserLevel(this._member.userId);\n }\n\n get linkToUser() {\n return `https://matrix.to/#/${encodeURIComponent(this._member.userId)}`;\n }\n\n async openDirectMessage() {\n const room = this._session.findDirectMessageForUserId(this.userId);\n let roomId = room?.id;\n if (!roomId) {\n const roomBeingCreated = await this._session.createRoom({\n type: RoomType.DirectMessage,\n invites: [this.userId]\n });\n roomId = roomBeingCreated.id;\n }\n this.navigation.push(\"room\", roomId);\n }\n\n _onCrossSigningChange() {\n const crossSigning = this._session.crossSigning.get();\n this._userTrustSubscription = this.disposeTracked(this._userTrustSubscription);\n this._userTrust = undefined;\n if (crossSigning) {\n this.logger.run(\"MemberDetailsViewModel.observeUserTrust\", log => {\n this._userTrust = crossSigning.observeUserTrust(this.userId, log);\n this._userTrustSubscription = this.track(this._userTrust.subscribe(() => {\n this.emitChange(\"trustShieldColor\");\n }));\n });\n }\n this.emitChange(\"trustShieldColor\");\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ErrorReportViewModel} from \"../../ErrorReportViewModel\";\nimport type {Options as BaseOptions} from \"../../ViewModel\";\nimport type {SegmentType} from \"../../navigation\";\nimport type {Room} from \"../../../matrix/room/Room.js\";\nimport type {Session} from \"../../../matrix/Session.js\";\n\ntype Options = { room: Room, session: Session } & BaseOptions;\n\nexport class InvitePanelViewModel extends ErrorReportViewModel {\n constructor(options: Options) {\n super(options);\n }\n\n get type() {\n return \"invite\";\n }\n\n get shouldShowBackButton() {\n return true;\n }\n\n get previousSegmentName() {\n return \"members\";\n }\n\n get roomName() {\n return this.getOption(\"room\").name;\n }\n\n async invite(userId: string) {\n await this.logAndCatch(\"InvitePanelViewModel.invite\", async () => {\n const room = this.getOption(\"room\");\n await room.inviteUser(userId);\n const path = this.navigation.path.until(\"room\");\n this.navigation.applyPath(path);\n });\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"../../ViewModel\";\nimport {RoomDetailsViewModel} from \"./RoomDetailsViewModel.js\";\nimport {MemberListViewModel} from \"./MemberListViewModel.js\";\nimport {MemberDetailsViewModel} from \"./MemberDetailsViewModel.js\";\nimport {InvitePanelViewModel} from \"./InvitePanelViewModel\";\nimport {DeviceVerificationViewModel} from \"../verification/DeviceVerificationViewModel\";\n\nexport class RightPanelViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._room = options.room;\n this._session = options.session;\n this._members = null;\n this._setupNavigation();\n }\n\n get activeViewModel() { return this._activeViewModel; }\n\n async _getMemberListArguments() {\n if (!this._members) {\n this._members = await this._room.loadMemberList();\n this.track(() => this._members.release());\n }\n const room = this._room;\n const powerLevelsObservable = await this._room.observePowerLevels();\n return {members: this._members, powerLevelsObservable, mediaRepository: room.mediaRepository};\n }\n\n async _getMemberDetailsArguments() {\n const segment = this.navigation.path.get(\"member\"); \n const userId = segment.value;\n const observableMember = await this._room.observeMember(userId);\n if (!observableMember) {\n return false;\n }\n const isEncrypted = this._room.isEncrypted;\n const powerLevelsObservable = await this._room.observePowerLevels();\n return {\n observableMember,\n isEncrypted,\n powerLevelsObservable,\n mediaRepository: this._room.mediaRepository,\n session: this._session\n };\n }\n\n _setupNavigation() {\n this._hookUpdaterToSegment(\"details\", RoomDetailsViewModel, () => { return {room: this._room}; });\n this._hookUpdaterToSegment(\"invite\", InvitePanelViewModel, () => { return {room: this._room}; });\n this._hookUpdaterToSegment(\"members\", MemberListViewModel, () => this._getMemberListArguments());\n this._hookUpdaterToSegment(\"member\", MemberDetailsViewModel, () => this._getMemberDetailsArguments(),\n () => {\n // If we fail to create the member details panel, fallback to memberlist\n const url = `${this.urlRouter.urlUntilSegment(\"room\")}/members`;\n this.urlRouter.pushUrl(url);\n }\n );\n this._hookUpdaterToSegment(\"verification\", DeviceVerificationViewModel, () => {\n const options = {\n session: this._session,\n room: this._room,\n };\n const id = this.navigation.path.get(\"verification\").value; \n if (typeof id === \"string\") {\n /**\n * Here id is:\n * 1. id of the request when we receive a sas verification request\n * 2. id of the user we are trying to verify when we initiate the verification process\n */\n const request = this._session?.crossSigning.get()?.receivedSASVerifications.get(id);\n const extraOptions = request ? { request } : { userId: id };\n Object.assign(options, extraOptions);\n }\n return options;\n });\n }\n\n async _hookUpdaterToSegment(segment, ViewModel, argCreator, failCallback) {\n const observable = this.navigation.observe(segment);\n const updater = await this._setupUpdater(segment, ViewModel, argCreator, failCallback);\n this.track(observable.subscribe(updater));\n }\n\n async _setupUpdater(segment, ViewModel, argCreator, failCallback) {\n const updater = async (skipDispose = false) => {\n if (this._activeViewModel instanceof ViewModel) {\n return;\n }\n if (!skipDispose) {\n this._activeViewModel = this.disposeTracked(this._activeViewModel);\n }\n const enable = !!this.navigation.path.get(segment)?.value;\n if (enable) {\n const args = await argCreator();\n if (!args && failCallback) {\n failCallback();\n return;\n }\n this._activeViewModel = this.track(new ViewModel(this.childOptions(args)));\n }\n this.emitChange(\"activeViewModel\");\n };\n await updater(true);\n return updater;\n }\n\n closePanel() {\n const path = this.navigation.path.until(\"room\");\n this.navigation.applyPath(path);\n }\n\n showPreviousPanel() {\n const segmentName = this.activeViewModel.previousSegmentName;\n if (segmentName) {\n let path = this.navigation.path.until(\"room\");\n path = path.with(this.navigation.segment(\"right-panel\", true));\n path = path.with(this.navigation.segment(segmentName, true));\n this.navigation.applyPath(path);\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ErrorReportViewModel} from \"../../ErrorReportViewModel\";\nimport {Options as BaseOptions} from \"../../ViewModel\";\nimport type {Session} from \"../../../matrix/Session.js\";\nimport {SegmentType} from \"../../navigation\";\n\nexport type BaseClassOptions = {\n dismiss: () => void;\n session: Session;\n} & BaseOptions;\n\nexport abstract class BaseToastNotificationViewModel = BaseClassOptions> extends ErrorReportViewModel {\n constructor(options: O) {\n super(options);\n }\n\n dismiss(): void {\n this.getOption(\"dismiss\")();\n }\n\n abstract get kind(): string;\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {GroupCall} from \"../../../../matrix/calls/group/GroupCall\";\nimport type {Room} from \"../../../../matrix/room/Room.js\";\nimport {IAvatarContract, avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from \"../../../avatar\"; \nimport {LocalMedia} from \"../../../../matrix/calls/LocalMedia\";\nimport {BaseClassOptions, BaseToastNotificationViewModel} from \".././BaseToastNotificationViewModel\";\nimport {SegmentType} from \"../../../navigation\";\n\ntype Options = {\n call: GroupCall;\n room: Room;\n} & BaseClassOptions;\n\n// Since we access the room segment below, the segment type\n// needs to at least contain the room segment!\ntype MinimumNeededSegmentType = {\n \"room\": string;\n};\n\nexport class CallToastNotificationViewModel = Options> extends BaseToastNotificationViewModel implements IAvatarContract {\n constructor(options: O) {\n super(options);\n this.track(this.call.members.observeSize().subscribe(() => {\n this.emitChange(\"memberCount\");\n }));\n // Dismiss the toast if the room is opened manually\n this.track(\n this.navigation.observe(\"room\").subscribe((roomId) => {\n if ((roomId as unknown as string) === this.call.roomId) {\n this.dismiss();\n }\n }));\n }\n\n get kind(): \"calls\" {\n return \"calls\";\n }\n\n async join(): Promise {\n await this.logAndCatch(\"CallToastNotificationViewModel.join\", async (log) => {\n const stream = await this.platform.mediaDevices.getMediaTracks(false, true);\n const localMedia = new LocalMedia().withUserMedia(stream);\n await this.call.join(localMedia, log);\n const url = this.urlRouter.openRoomActionUrl(this.call.roomId);\n this.urlRouter.pushUrl(url);\n });\n }\n\n get call(): GroupCall {\n return this.getOption(\"call\");\n }\n\n private get room(): Room {\n return this.getOption(\"room\");\n } \n\n get roomName(): string {\n return this.room.name;\n }\n\n get memberCount(): number {\n return this.call.members.size;\n }\n\n get avatarLetter(): string {\n return avatarInitials(this.roomName);\n }\n\n get avatarColorNumber(): number {\n return getIdentifierColorNumber(this.room.avatarColorId);\n }\n\n avatarUrl(size: number): string | undefined {\n return getAvatarHttpUrl(this.room.avatarUrl, size, this.platform, this.room.mediaRepository);\n }\n\n get avatarTitle(): string {\n return this.roomName;\n }\n}\n\n\n","\n/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {CallToastNotificationViewModel} from \"./CallToastNotificationViewModel\";\nimport {ObservableArray} from \"../../../../observable\";\nimport {ViewModel, Options as BaseOptions} from \"../../../ViewModel\";\nimport {RoomStatus} from \"../../../../matrix/room/common\";\nimport type {GroupCall} from \"../../../../matrix/calls/group/GroupCall\";\nimport type {Room} from \"../../../../matrix/room/Room.js\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {SegmentType} from \"../../../navigation\";\nimport type {IToastCollection} from \"../IToastCollection\";\n\ntype Options = {\n session: Session;\n} & BaseOptions;\n\n\nexport class CallToastCollectionViewModel extends ViewModel implements IToastCollection {\n public readonly toastViewModels: ObservableArray = new ObservableArray();\n\n constructor(options: Options) {\n super(options);\n const session = this.getOption(\"session\");\n if (this.features.calls) {\n const callsObservableMap = session.callHandler.calls;\n this.track(callsObservableMap.subscribe(this));\n }\n }\n\n async onAdd(_, call: GroupCall) {\n if (this._shouldShowNotification(call)) {\n const room = await this._findRoomForCall(call);\n const dismiss = () => {\n const idx = this.toastViewModels.array.findIndex(vm => vm.call === call);\n if (idx !== -1) {\n this.toastViewModels.remove(idx);\n }\n };\n this.toastViewModels.append(\n new CallToastNotificationViewModel(this.childOptions({ call, room, dismiss }))\n );\n }\n }\n\n onRemove(_, call: GroupCall) {\n const idx = this.toastViewModels.array.findIndex(vm => vm.call === call);\n if (idx !== -1) {\n this.toastViewModels.remove(idx);\n }\n }\n\n onUpdate(_, call: GroupCall) {\n const idx = this.toastViewModels.array.findIndex(vm => vm.call === call);\n if (idx !== -1) {\n this.toastViewModels.update(idx, this.toastViewModels.at(idx)!);\n }\n }\n\n onReset() {\n for (let i = 0; i < this.toastViewModels.length; ++i) {\n this.toastViewModels.remove(i);\n }\n }\n\n private async _findRoomForCall(call: GroupCall): Promise {\n const id = call.roomId;\n const session = this.getOption(\"session\");\n const rooms = session.rooms;\n // Make sure that we know of this room, \n // otherwise wait for it to come through sync\n const observable = await session.observeRoomStatus(id);\n await observable.waitFor(s => s === RoomStatus.Joined).promise;\n const room = rooms.get(id);\n return room;\n }\n \n private _shouldShowNotification(call: GroupCall): boolean {\n const currentlyOpenedRoomId = this.navigation.path.get(\"room\")?.value;\n if (!call.isLoadedFromStorage && call.roomId !== currentlyOpenedRoomId && !call.usesFoci) {\n return true;\n }\n return false;\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseClassOptions, BaseToastNotificationViewModel} from \".././BaseToastNotificationViewModel\";\nimport {SegmentType} from \"../../../navigation\";\nimport {SASRequest} from \"../../../../matrix/verification/SAS/SASRequest\";\n\ntype Options = {\n request: SASRequest;\n} & BaseClassOptions;\n\ntype MinimumNeededSegmentType = {\n \"device-verification\": string | boolean;\n};\n\nexport class VerificationToastNotificationViewModel = Options> extends BaseToastNotificationViewModel {\n constructor(options: O) {\n super(options);\n }\n\n get kind(): \"verification\" {\n return \"verification\";\n }\n\n get request(): SASRequest {\n return this.getOption(\"request\");\n }\n\n get otherDeviceId(): string {\n return this.request.deviceId;\n }\n\n accept() {\n // @ts-ignore\n this.navigation.push(\"device-verification\", this.request.id);\n this.dismiss();\n }\n\n}\n\n\n","\n/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {VerificationToastNotificationViewModel} from \"./VerificationToastNotificationViewModel\";\nimport {ObservableArray} from \"../../../../observable\";\nimport {ViewModel, Options as BaseOptions} from \"../../../ViewModel\";\nimport type {Session} from \"../../../../matrix/Session.js\";\nimport type {SegmentType} from \"../../../navigation\";\nimport type {IToastCollection} from \"../IToastCollection\";\nimport type {SASRequest} from \"../../../../matrix/verification/SAS/SASRequest\";\n\ntype Options = {\n session: Session;\n} & BaseOptions;\n\nexport class VerificationToastCollectionViewModel extends ViewModel implements IToastCollection {\n public readonly toastViewModels: ObservableArray = new ObservableArray();\n\n constructor(options: Options) {\n super(options);\n this.subscribeToSASRequests();\n }\n\n private async subscribeToSASRequests() {\n await this.getOption(\"session\").crossSigning.waitFor(v => !!v).promise; \n const crossSigning = this.getOption(\"session\").crossSigning.get();\n this.track(crossSigning.receivedSASVerifications.subscribe(this));\n }\n\n\n async onAdd(_, request: SASRequest) {\n if (request.sender !== this.getOption(\"session\").userId) {\n // Don't show toast for cross-signing other users\n return;\n }\n const dismiss = () => {\n const idx = this.toastViewModels.array.findIndex(vm => vm.request.id === request.id);\n if (idx !== -1) {\n this.toastViewModels.remove(idx);\n }\n };\n this.toastViewModels.append(\n this.track(new VerificationToastNotificationViewModel(this.childOptions({ request, dismiss })))\n );\n }\n\n onRemove(_, request: SASRequest) {\n const idx = this.toastViewModels.array.findIndex(vm => vm.request.id === request.id);\n if (idx !== -1) {\n this.toastViewModels.remove(idx);\n }\n }\n\n onUpdate(_, request: SASRequest) {\n const idx = this.toastViewModels.array.findIndex(vm => vm.request.id === request.id);\n if (idx !== -1) {\n this.toastViewModels.update(idx, this.toastViewModels.at(idx)!);\n }\n }\n\n onReset() {\n for (let i = 0; i < this.toastViewModels.length; ++i) {\n this.toastViewModels.remove(i);\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ConcatList} from \"../../../observable\";\nimport {ViewModel, Options as BaseOptions} from \"../../ViewModel\";\nimport {CallToastCollectionViewModel} from \"./calls/CallsToastCollectionViewModel\";\nimport {VerificationToastCollectionViewModel} from \"./verification/VerificationToastCollectionViewModel\";\nimport type {Session} from \"../../../matrix/Session.js\";\nimport type {SegmentType} from \"../../navigation\";\nimport type {BaseToastNotificationViewModel} from \"./BaseToastNotificationViewModel\";\nimport type {IToastCollection} from \"./IToastCollection\";\n\ntype Options = {\n session: Session;\n} & BaseOptions;\n\nexport class ToastCollectionViewModel extends ViewModel {\n public readonly toastViewModels: ConcatList;\n\n constructor(options: Options) {\n super(options);\n const session = this.getOption(\"session\");\n const collectionVms: IToastCollection[] = [];\n if (this.features.calls) {\n collectionVms.push(this.track(new CallToastCollectionViewModel(this.childOptions({ session }))));\n }\n if (this.features.crossSigning) {\n collectionVms.push(this.track(new VerificationToastCollectionViewModel(this.childOptions({ session }))));\n }\n const vms: IToastCollection[\"toastViewModels\"][] = collectionVms.map(vm => vm.toastViewModels);\n if (vms.length !== 0) {\n this.toastViewModels = new ConcatList(...vms);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {LeftPanelViewModel} from \"./leftpanel/LeftPanelViewModel.js\";\nimport {RoomViewModel} from \"./room/RoomViewModel.js\";\nimport {UnknownRoomViewModel} from \"./room/UnknownRoomViewModel.js\";\nimport {InviteViewModel} from \"./room/InviteViewModel.js\";\nimport {RoomBeingCreatedViewModel} from \"./room/RoomBeingCreatedViewModel.js\";\nimport {LightboxViewModel} from \"./room/LightboxViewModel.js\";\nimport {SessionStatusViewModel} from \"./SessionStatusViewModel.js\";\nimport {RoomGridViewModel} from \"./RoomGridViewModel.js\";\nimport {SettingsViewModel} from \"./settings/SettingsViewModel.js\";\nimport {CreateRoomViewModel} from \"./CreateRoomViewModel.js\";\nimport {JoinRoomViewModel} from \"./JoinRoomViewModel\";\nimport {DeviceVerificationViewModel} from \"./verification/DeviceVerificationViewModel\";\nimport {ViewModel} from \"../ViewModel\";\nimport {RoomViewModelObservable} from \"./RoomViewModelObservable.js\";\nimport {RightPanelViewModel} from \"./rightpanel/RightPanelViewModel.js\";\nimport {SyncStatus} from \"../../matrix/Sync.js\";\nimport {ToastCollectionViewModel} from \"./toast/ToastCollectionViewModel\";\n\nexport class SessionViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {client} = options;\n this._client = this.track(client);\n this._sessionStatusViewModel = this.track(new SessionStatusViewModel(this.childOptions({\n sync: client.sync,\n reconnector: client.reconnector,\n session: client.session,\n })));\n this._leftPanelViewModel = this.track(new LeftPanelViewModel(this.childOptions({session: this._client.session})));\n this._settingsViewModel = null;\n this._roomViewModelObservable = null;\n this._gridViewModel = null;\n this._createRoomViewModel = null;\n this._joinRoomViewModel = null;\n this._verificationViewModel = null;\n this._toastCollectionViewModel = this.track(new ToastCollectionViewModel(this.childOptions({\n session: this._client.session,\n })));\n this._setupNavigation();\n this._setupForcedLogoutOnAccessTokenInvalidation();\n }\n\n _setupNavigation() {\n const gridRooms = this.navigation.observe(\"rooms\");\n // this gives us a set of room ids in the grid\n this.track(gridRooms.subscribe(roomIds => {\n this._updateGrid(roomIds);\n }));\n if (gridRooms.get()) {\n this._updateGrid(gridRooms.get());\n }\n\n const currentRoomId = this.navigation.observe(\"room\");\n // this gives us the active room\n this.track(currentRoomId.subscribe(roomId => {\n if (!this._gridViewModel) {\n this._updateRoom(roomId);\n }\n this._updateRightPanel();\n }));\n if (!this._gridViewModel) {\n this._updateRoom(currentRoomId.get());\n }\n\n const settings = this.navigation.observe(\"settings\");\n this.track(settings.subscribe(settingsOpen => {\n this._updateSettings(settingsOpen);\n }));\n this._updateSettings(settings.get());\n\n const createRoom = this.navigation.observe(\"create-room\");\n this.track(createRoom.subscribe(createRoomOpen => {\n this._updateCreateRoom(createRoomOpen);\n }));\n this._updateCreateRoom(createRoom.get());\n\n const joinRoom = this.navigation.observe(\"join-room\");\n this.track(joinRoom.subscribe((joinRoomOpen) => {\n this._updateJoinRoom(joinRoomOpen);\n }));\n this._updateJoinRoom(joinRoom.get());\n\n if (this.features.crossSigning) {\n const verification = this.navigation.observe(\"device-verification\");\n this.track(verification.subscribe((txnId) => {\n this._updateVerification(txnId);\n }));\n this._updateVerification(verification.get());\n }\n\n const lightbox = this.navigation.observe(\"lightbox\");\n this.track(lightbox.subscribe(eventId => {\n this._updateLightbox(eventId);\n }));\n this._updateLightbox(lightbox.get());\n\n\n const rightpanel = this.navigation.observe(\"right-panel\");\n this.track(rightpanel.subscribe(() => this._updateRightPanel()));\n this._updateRightPanel();\n }\n\n _setupForcedLogoutOnAccessTokenInvalidation() {\n this.track(this._client.sync.status.subscribe(status => {\n if (status === SyncStatus.Stopped) {\n const error = this._client.sync.error;\n if (error?.errcode === \"M_UNKNOWN_TOKEN\") {\n // Access token is no longer valid, so force the user to log out\n const segments = [\n this.navigation.segment(\"logout\", this.id),\n this.navigation.segment(\"forced\", true),\n ];\n const path = this.navigation.pathFrom(segments);\n this.navigation.applyPath(path);\n }\n }\n }));\n }\n\n get id() {\n return this._client.sessionId;\n }\n\n start() {\n this._sessionStatusViewModel.start();\n if (this.features.calls) {\n this._client.session.callHandler.loadCalls(\"m.ring\");\n // TODO: only do this when opening the room\n this._client.session.callHandler.loadCalls(\"m.prompt\");\n }\n }\n\n get activeMiddleViewModel() {\n return (\n this._roomViewModelObservable?.get() ||\n this._gridViewModel ||\n this._settingsViewModel ||\n this._createRoomViewModel ||\n this._joinRoomViewModel ||\n this._verificationViewModel\n );\n }\n\n get roomGridViewModel() {\n return this._gridViewModel;\n }\n\n get leftPanelViewModel() {\n return this._leftPanelViewModel;\n }\n\n get sessionStatusViewModel() {\n return this._sessionStatusViewModel;\n }\n\n get settingsViewModel() {\n return this._settingsViewModel;\n }\n\n get currentRoomViewModel() {\n return this._roomViewModelObservable?.get();\n }\n\n get rightPanelViewModel() {\n return this._rightPanelViewModel;\n }\n\n get createRoomViewModel() {\n return this._createRoomViewModel;\n }\n\n get joinRoomViewModel() {\n return this._joinRoomViewModel;\n }\n\n get verificationViewModel() {\n return this._verificationViewModel;\n }\n\n get toastCollectionViewModel() {\n return this._toastCollectionViewModel;\n }\n\n _updateGrid(roomIds) {\n const changed = !(this._gridViewModel && roomIds);\n const currentRoomId = this.navigation.path.get(\"room\");\n if (roomIds) {\n if (!this._gridViewModel) {\n this._gridViewModel = this.track(new RoomGridViewModel(this.childOptions({\n width: 3,\n height: 2,\n createRoomViewModelObservable: roomId => new RoomViewModelObservable(this, roomId),\n })));\n // try to transfer the current room view model, so we don't have to reload the timeline\n this._roomViewModelObservable?.unsubscribeAll();\n if (this._gridViewModel.initializeRoomIdsAndTransferVM(roomIds, this._roomViewModelObservable)) {\n this._roomViewModelObservable = this.untrack(this._roomViewModelObservable);\n } else if (this._roomViewModelObservable) {\n this._roomViewModelObservable = this.disposeTracked(this._roomViewModelObservable);\n }\n } else {\n this._gridViewModel.setRoomIds(roomIds);\n }\n } else if (this._gridViewModel && !roomIds) {\n // closing grid, try to show focused room in grid\n if (currentRoomId) {\n const vmo = this._gridViewModel.releaseRoomViewModel(currentRoomId.value);\n if (vmo) {\n this._roomViewModelObservable = this.track(vmo);\n this._roomViewModelObservable.subscribe(() => {\n this.emitChange(\"activeMiddleViewModel\");\n });\n }\n }\n this._gridViewModel = this.disposeTracked(this._gridViewModel);\n }\n if (changed) {\n this.emitChange(\"activeMiddleViewModel\");\n }\n }\n\n _createRoomViewModelInstance(roomId) {\n const room = this._client.session.rooms.get(roomId);\n if (room) {\n const roomVM = new RoomViewModel(this.childOptions({room, session: this._client.session}));\n roomVM.load();\n return roomVM;\n }\n return null;\n }\n\n _createUnknownRoomViewModel(roomIdOrAlias) {\n return new UnknownRoomViewModel(this.childOptions({\n roomIdOrAlias,\n session: this._client.session,\n }));\n }\n\n async _createArchivedRoomViewModel(roomId) {\n const room = await this._client.session.loadArchivedRoom(roomId);\n if (room) {\n const roomVM = new RoomViewModel(this.childOptions({room, session: this._client.session}));\n roomVM.load();\n return roomVM;\n }\n return null;\n }\n\n _createInviteViewModel(roomId) {\n const invite = this._client.session.invites.get(roomId);\n if (invite) {\n return new InviteViewModel(this.childOptions({\n invite,\n mediaRepository: this._client.session.mediaRepository,\n }));\n }\n return null;\n }\n\n _createRoomBeingCreatedViewModel(localId) {\n const roomBeingCreated = this._client.session.roomsBeingCreated.get(localId);\n if (roomBeingCreated) {\n return new RoomBeingCreatedViewModel(this.childOptions({\n roomBeingCreated,\n mediaRepository: this._client.session.mediaRepository,\n }));\n }\n return null;\n }\n\n _updateRoom(roomId) {\n // opening a room and already open?\n if (this._roomViewModelObservable?.id === roomId) {\n return;\n }\n // close if needed\n if (this._roomViewModelObservable) {\n this._roomViewModelObservable = this.disposeTracked(this._roomViewModelObservable);\n }\n if (!roomId) {\n // if clearing the activeMiddleViewModel rather than changing to a different one,\n // emit so the view picks it up and show the placeholder\n this.emitChange(\"activeMiddleViewModel\");\n return;\n }\n const vmo = new RoomViewModelObservable(this, roomId);\n this._roomViewModelObservable = this.track(vmo);\n // subscription is unsubscribed in RoomViewModelObservable.dispose, and thus handled by track\n this._roomViewModelObservable.subscribe(() => {\n this.emitChange(\"activeMiddleViewModel\");\n });\n vmo.initialize();\n }\n\n _updateSettings(settingsOpen) {\n if (this._settingsViewModel) {\n this._settingsViewModel = this.disposeTracked(this._settingsViewModel);\n }\n if (settingsOpen) {\n this._settingsViewModel = this.track(new SettingsViewModel(this.childOptions({\n client: this._client,\n })));\n this._settingsViewModel.load();\n }\n this.emitChange(\"activeMiddleViewModel\");\n }\n\n _updateCreateRoom(createRoomOpen) {\n if (this._createRoomViewModel) {\n this._createRoomViewModel = this.disposeTracked(this._createRoomViewModel);\n }\n if (createRoomOpen) {\n this._createRoomViewModel = this.track(new CreateRoomViewModel(this.childOptions({session: this._client.session})));\n }\n this.emitChange(\"activeMiddleViewModel\");\n }\n\n _updateJoinRoom(joinRoomOpen) {\n if (this._joinRoomViewModel) {\n this._joinRoomViewModel = this.disposeTracked(this._joinRoomViewModel);\n }\n if (joinRoomOpen) {\n this._joinRoomViewModel = this.track(new JoinRoomViewModel(this.childOptions({session: this._client.session})));\n }\n this.emitChange(\"activeMiddleViewModel\");\n }\n\n _updateVerification(txnId) {\n if (this._verificationViewModel) {\n this._verificationViewModel = this.disposeTracked(this._verificationViewModel);\n }\n if (txnId) {\n const request = this._client.session.crossSigning.get()?.receivedSASVerifications.get(txnId);\n this._verificationViewModel = this.track(new DeviceVerificationViewModel(this.childOptions({ session: this._client.session, request })));\n }\n this.emitChange(\"activeMiddleViewModel\");\n }\n\n _updateLightbox(eventId) {\n if (this._lightboxViewModel) {\n this._lightboxViewModel = this.disposeTracked(this._lightboxViewModel);\n }\n if (eventId) {\n const room = this._roomFromNavigation();\n this._lightboxViewModel = this.track(new LightboxViewModel(this.childOptions({eventId, room})));\n }\n this.emitChange(\"lightboxViewModel\");\n }\n\n get lightboxViewModel() {\n return this._lightboxViewModel;\n }\n\n _roomFromNavigation() {\n const roomId = this.navigation.path.get(\"room\")?.value;\n const room = this._client.session.rooms.get(roomId);\n return room;\n }\n\n _updateRightPanel() {\n this._rightPanelViewModel = this.disposeTracked(this._rightPanelViewModel);\n const enable = !!this.navigation.path.get(\"right-panel\")?.value;\n if (enable) {\n const room = this._roomFromNavigation();\n this._rightPanelViewModel = this.track(new RightPanelViewModel(this.childOptions({room, session: this._client.session})));\n }\n this.emitChange(\"rightPanelViewModel\");\n }\n\n notifyRoomReplaced(oldId, newId) {\n this.navigation.push(\"room\", newId);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ViewModel} from \"./ViewModel\";\nimport {KeyType} from \"../matrix/ssss/index\";\nimport {Status} from \"./session/settings/KeyBackupViewModel\";\n\nexport class AccountSetupViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._accountSetup = options.accountSetup;\n this._dehydratedDevice = undefined;\n this._decryptDehydratedDeviceViewModel = undefined;\n if (this._accountSetup.encryptedDehydratedDevice) {\n this._decryptDehydratedDeviceViewModel = new DecryptDehydratedDeviceViewModel(this, dehydratedDevice => {\n this._dehydratedDevice = dehydratedDevice;\n this._decryptDehydratedDeviceViewModel = undefined;\n this.emitChange(\"deviceDecrypted\");\n });\n }\n }\n\n get decryptDehydratedDeviceViewModel() {\n return this._decryptDehydratedDeviceViewModel;\n }\n\n get deviceDecrypted() {\n return !!this._dehydratedDevice;\n }\n\n get dehydratedDeviceId() {\n return this._accountSetup.encryptedDehydratedDevice.deviceId;\n }\n\n finish() {\n this._accountSetup.finish(this._dehydratedDevice);\n }\n}\n\n// this vm adopts the same shape as KeyBackupViewModel so the same view can be reused.\nclass DecryptDehydratedDeviceViewModel extends ViewModel {\n constructor(accountSetupViewModel, decryptedCallback) {\n super(accountSetupViewModel.options);\n this._accountSetupViewModel = accountSetupViewModel;\n this._isBusy = false;\n this._status = Status.SetupWithRecoveryKey;\n this._error = undefined;\n this._decryptedCallback = decryptedCallback;\n }\n\n get decryptAction() {\n return this.i18n`Restore`;\n }\n\n get purpose() {\n return this.i18n`claim your dehydrated device`;\n }\n\n get offerDehydratedDeviceSetup() {\n return false;\n }\n\n get dehydratedDeviceId() {\n return this._accountSetupViewModel._dehydratedDevice?.deviceId;\n }\n \n get isBusy() {\n return this._isBusy;\n }\n\n get backupVersion() { return 0; }\n\n get status() {\n return this._status;\n }\n\n get error() {\n return this._error?.message;\n }\n\n showPhraseSetup() {\n if (this._status === Status.SetupWithRecoveryKey) {\n this._status = Status.SetupWithPassphrase;\n this.emitChange(\"status\");\n }\n }\n\n showKeySetup() {\n if (this._status === Status.SetupWithPassphrase) {\n this._status = Status.SetupWithRecoveryKey;\n this.emitChange(\"status\");\n }\n }\n\n async _enterCredentials(keyType, credential) {\n if (credential) {\n try {\n this._isBusy = true;\n this.emitChange(\"isBusy\");\n const {encryptedDehydratedDevice} = this._accountSetupViewModel._accountSetup;\n const dehydratedDevice = await encryptedDehydratedDevice.decrypt(keyType, credential);\n this._decryptedCallback(dehydratedDevice);\n } catch (err) {\n console.error(err);\n this._error = err;\n this.emitChange(\"error\");\n } finally {\n this._isBusy = false;\n this.emitChange(\"\");\n }\n }\n }\n\n enterSecurityPhrase(passphrase) {\n this._enterCredentials(KeyType.Passphrase, passphrase);\n }\n\n enterSecurityKey(securityKey) {\n this._enterCredentials(KeyType.RecoveryKey, securityKey);\n }\n\n disable() {}\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AccountSetupViewModel} from \"./AccountSetupViewModel.js\";\nimport {LoadStatus} from \"../matrix/Client.js\";\nimport {SyncStatus} from \"../matrix/Sync.js\";\nimport {ViewModel} from \"./ViewModel\";\n\nexport class SessionLoadViewModel extends ViewModel {\n constructor(options) {\n super(options);\n const {client, ready, homeserver, deleteSessionOnCancel} = options;\n this._client = client;\n this._ready = ready;\n this._homeserver = homeserver;\n this._deleteSessionOnCancel = deleteSessionOnCancel;\n this._loading = false;\n this._error = null;\n this.backUrl = this.urlRouter.urlForSegment(\"session\", true);\n this._accountSetupViewModel = undefined;\n\n }\n\n async start() {\n if (this._loading) {\n return;\n }\n try {\n this._loading = true;\n this.emitChange(\"loading\");\n this._waitHandle = this._client.loadStatus.waitFor(s => {\n if (s === LoadStatus.AccountSetup) {\n this._accountSetupViewModel = new AccountSetupViewModel(this.childOptions({accountSetup: this._client.accountSetup}));\n } else {\n this._accountSetupViewModel = undefined;\n }\n this.emitChange(\"loadLabel\");\n // wait for initial sync, but not catchup sync\n const isCatchupSync = s === LoadStatus.FirstSync &&\n this._client.sync.status.get() === SyncStatus.CatchupSync;\n return isCatchupSync ||\n s === LoadStatus.LoginFailed ||\n s === LoadStatus.Error ||\n s === LoadStatus.Ready;\n });\n try {\n await this._waitHandle.promise;\n } catch (err) {\n return; // aborted by goBack\n }\n // TODO: should we deal with no connection during initial sync \n // and we're retrying as well here?\n // e.g. show in the label what is going on wrt connectionstatus\n // much like we will once you are in the app. Probably a good idea\n\n // did it finish or get stuck at LoginFailed or Error?\n const loadStatus = this._client.loadStatus.get();\n const loadError = this._client.loadError;\n if (loadStatus === LoadStatus.FirstSync || loadStatus === LoadStatus.Ready) {\n const client = this._client;\n // session container is ready,\n // don't dispose it anymore when \n // we get disposed\n this._client = null;\n this._ready(client);\n }\n if (loadError) {\n console.error(\"session load error\", loadError.stack);\n }\n } catch (err) {\n this._error = err;\n console.error(\"error thrown during session load\", err.stack);\n } finally {\n this._loading = false;\n // loadLabel in case of client.loadError also gets updated through this\n this.emitChange(\"loading\");\n }\n }\n\n\n dispose() {\n if (this._client) {\n this._client.dispose();\n this._client = null;\n }\n if (this._waitHandle) {\n // rejects with AbortError\n this._waitHandle.dispose();\n this._waitHandle = null;\n }\n }\n\n // to show a spinner or not\n get loading() {\n const client = this._client;\n if (client && client.loadStatus.get() === LoadStatus.AccountSetup) {\n return false;\n }\n return this._loading;\n }\n\n get loadLabel() {\n const client = this._client;\n const error = this._getError();\n if (error || (client && client.loadStatus.get() === LoadStatus.Error)) {\n return `Something went wrong: ${error && error.message}.`;\n }\n\n // Statuses related to login are handled by respective login view models\n if (client) {\n switch (client.loadStatus.get()) {\n case LoadStatus.QueryAccount:\n return `Querying account encryption setup…`;\n case LoadStatus.AccountSetup:\n return \"\"; // we'll show a header ing AccountSetupView\n case LoadStatus.SessionSetup:\n return `Setting up your encryption keys…`;\n case LoadStatus.Loading:\n return `Loading your conversations…`;\n case LoadStatus.FirstSync:\n return `Getting your conversations from the server…`;\n default:\n return this._client.loadStatus.get();\n }\n }\n\n return `Preparing…`;\n }\n\n _getError() {\n return this._error || this._client?.loadError; \n }\n\n get hasError() {\n return !!this._getError();\n }\n\n async exportLogs() {\n const logExport = await this.logger.export();\n this.platform.saveFileAs(logExport.asBlob(), `hydrogen-logs-${this.platform.clock.now()}.json`);\n }\n\n async logout() {\n await this._client.startLogout(this.navigation.path.get(\"session\").value);\n this.navigation.push(\"session\", true);\n }\n\n get accountSetupViewModel() {\n return this._accountSetupViewModel;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {LoginFailure} from \"../../matrix/Client.js\";\nimport type {PasswordLoginMethod} from \"../../matrix/login\";\nimport {Options as BaseOptions, ViewModel} from \"../ViewModel\";\nimport type {LoginOptions} from \"./LoginViewModel\";\n\ntype Options = {\n loginOptions: LoginOptions | undefined;\n attemptLogin: (loginMethod: PasswordLoginMethod) => Promise;\n} & BaseOptions\n\nexport class PasswordLoginViewModel extends ViewModel {\n private _loginOptions?: LoginOptions;\n private _attemptLogin: (loginMethod: PasswordLoginMethod) => Promise;\n private _isBusy = false;\n private _errorMessage = \"\";\n\n constructor(options: Options) {\n super(options);\n const {loginOptions, attemptLogin} = options;\n this._loginOptions = loginOptions;\n this._attemptLogin = attemptLogin;\n }\n\n get isBusy(): boolean { return this._isBusy; }\n get errorMessage(): string { return this._errorMessage; }\n\n setBusy(status: boolean): void {\n this._isBusy = status;\n this.emitChange(\"isBusy\");\n }\n\n _showError(message: string): void {\n this._errorMessage = message;\n this.emitChange(\"errorMessage\");\n }\n\n async login(username: string, password: string): Promise{\n this._errorMessage = \"\";\n this.emitChange(\"errorMessage\");\n const status = await this._attemptLogin(this._loginOptions!.password!(username, password));\n let error = \"\";\n switch (status) {\n case LoginFailure.Credentials:\n error = this.i18n`Your username and/or password don't seem to be correct.`;\n break;\n case LoginFailure.Connection:\n error = this.i18n`Can't connect to ${this._loginOptions!.homeserver}.`;\n break;\n case LoginFailure.Unknown:\n error = this.i18n`Something went wrong while checking your login and password.`;\n break;\n }\n if (error) {\n this._showError(error);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {SSOLoginHelper} from \"../../matrix/login\";\nimport {Options as BaseOptions, ViewModel} from \"../ViewModel\";\nimport type {LoginOptions} from \"./LoginViewModel\";\n\n\ntype Options = {\n loginOptions: LoginOptions | undefined;\n} & BaseOptions;\n\nexport class StartSSOLoginViewModel extends ViewModel{\n private _sso?: SSOLoginHelper;\n private _isBusy = false;\n\n constructor(options: Options) {\n super(options);\n this._sso = options.loginOptions!.sso;\n this._isBusy = false;\n }\n\n get isBusy(): boolean { return this._isBusy; }\n\n setBusy(status: boolean): void {\n this._isBusy = status;\n this.emitChange(\"isBusy\");\n }\n\n async startSSOLogin(): Promise {\n await this.platform.settingsStorage.setString(\"sso_ongoing_login_homeserver\", this._sso!.homeserver);\n const link = this._sso!.createSSORedirectURL(this.urlRouter.createSSOCallbackURL());\n this.platform.openUrl(link);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Options as BaseOptions, ViewModel} from \"../ViewModel\";\nimport {LoginFailure} from \"../../matrix/Client.js\";\nimport type {TokenLoginMethod} from \"../../matrix/login\";\nimport { Client } from \"../../matrix/Client.js\";\n\ntype Options = {\n client: Client;\n attemptLogin: (loginMethod: TokenLoginMethod) => Promise;\n loginToken: string;\n} & BaseOptions\n\nexport class CompleteSSOLoginViewModel extends ViewModel {\n private _loginToken: string;\n private _client: Client;\n private _attemptLogin: (loginMethod: TokenLoginMethod) => Promise;\n private _errorMessage = \"\";\n\n constructor(options: Options) {\n super(options);\n const {\n loginToken,\n client,\n attemptLogin,\n } = options;\n this._loginToken = loginToken;\n this._client = client;\n this._attemptLogin = attemptLogin;\n this._errorMessage = \"\";\n void this.performSSOLoginCompletion();\n }\n\n get errorMessage(): string { return this._errorMessage; }\n\n _showError(message: string): void {\n this._errorMessage = message;\n this.emitChange(\"errorMessage\");\n }\n\n async performSSOLoginCompletion(): Promise {\n if (!this._loginToken) {\n return;\n }\n const homeserver = await this.platform.settingsStorage.getString(\"sso_ongoing_login_homeserver\");\n let loginOptions: { token?: (loginToken: string) => TokenLoginMethod; };\n try {\n loginOptions = await this._client.queryLogin(homeserver).result;\n }\n catch (err) {\n this._showError(err.message);\n return;\n }\n if (!loginOptions.token) {\n this.navigation.push(\"session\");\n return;\n }\n const status = await this._attemptLogin(loginOptions.token(this._loginToken));\n let error = \"\";\n switch (status) {\n case LoginFailure.Credentials:\n error = this.i18n`Your login token is invalid.`;\n break;\n case LoginFailure.Connection:\n error = this.i18n`Can't connect to ${homeserver}.`;\n break;\n case LoginFailure.Unknown:\n error = this.i18n`Something went wrong while checking your login token.`;\n break;\n }\n if (error) {\n this._showError(error);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Client} from \"../../matrix/Client.js\";\nimport {Options as BaseOptions, ViewModel} from \"../ViewModel\";\nimport {PasswordLoginViewModel} from \"./PasswordLoginViewModel\";\nimport {StartSSOLoginViewModel} from \"./StartSSOLoginViewModel\";\nimport {CompleteSSOLoginViewModel} from \"./CompleteSSOLoginViewModel\";\nimport {LoadStatus} from \"../../matrix/Client.js\";\nimport {SessionLoadViewModel} from \"../SessionLoadViewModel.js\";\nimport {SegmentType} from \"../navigation/index\";\n\nimport type {PasswordLoginMethod, SSOLoginHelper, TokenLoginMethod, ILoginMethod} from \"../../matrix/login\";\n\ntype Options = {\n defaultHomeserver: string;\n ready: ReadyFn;\n loginToken?: string;\n} & BaseOptions;\n\nexport class LoginViewModel extends ViewModel {\n private _ready: ReadyFn;\n private _loginToken?: string;\n private _client: Client;\n private _loginOptions?: LoginOptions;\n private _passwordLoginViewModel?: PasswordLoginViewModel;\n private _startSSOLoginViewModel?: StartSSOLoginViewModel;\n private _completeSSOLoginViewModel?: CompleteSSOLoginViewModel;\n private _loadViewModel?: SessionLoadViewModel;\n private _loadViewModelSubscription?: () => void;\n private _homeserver: string;\n private _queriedHomeserver?: string;\n private _abortHomeserverQueryTimeout?: () => void;\n private _abortQueryOperation?: () => void;\n\n private _hideHomeserver: boolean = false;\n private _isBusy: boolean = false;\n private _errorMessage: string = \"\";\n\n constructor(options: Readonly) {\n super(options);\n const {ready, defaultHomeserver, loginToken} = options;\n this._ready = ready;\n this._loginToken = loginToken;\n this._client = new Client(this.platform, this.features);\n this._homeserver = defaultHomeserver;\n this._initViewModels();\n }\n\n get passwordLoginViewModel(): PasswordLoginViewModel | undefined {\n return this._passwordLoginViewModel;\n }\n\n get startSSOLoginViewModel(): StartSSOLoginViewModel | undefined {\n return this._startSSOLoginViewModel;\n }\n\n get completeSSOLoginViewModel(): CompleteSSOLoginViewModel | undefined {\n return this._completeSSOLoginViewModel;\n }\n\n get homeserver(): string {\n return this._homeserver;\n }\n\n get resolvedHomeserver(): string | undefined {\n return this._loginOptions?.homeserver;\n }\n\n get errorMessage(): string {\n return this._errorMessage;\n }\n\n get showHomeserver(): boolean {\n return !this._hideHomeserver;\n }\n\n get loadViewModel(): SessionLoadViewModel {\n return this._loadViewModel;\n }\n\n get isBusy(): boolean {\n return this._isBusy;\n }\n\n get isFetchingLoginOptions(): boolean {\n return !!this._abortQueryOperation;\n }\n\n goBack(): void {\n this.navigation.push(\"session\");\n }\n\n private _initViewModels(): void {\n if (this._loginToken) {\n this._hideHomeserver = true;\n this._completeSSOLoginViewModel = this.track(new CompleteSSOLoginViewModel(\n this.childOptions(\n {\n client: this._client,\n attemptLogin: (loginMethod: TokenLoginMethod) => this.attemptLogin(loginMethod),\n loginToken: this._loginToken\n })));\n this.emitChange(\"completeSSOLoginViewModel\");\n }\n else {\n void this.queryHomeserver();\n }\n }\n\n private _showPasswordLogin(): void {\n this._passwordLoginViewModel = this.track(new PasswordLoginViewModel(\n this.childOptions({\n loginOptions: this._loginOptions,\n attemptLogin: (loginMethod: PasswordLoginMethod) => this.attemptLogin(loginMethod)\n })));\n this.emitChange(\"passwordLoginViewModel\");\n }\n\n private _showSSOLogin(): void {\n this._startSSOLoginViewModel = this.track(\n new StartSSOLoginViewModel(this.childOptions({loginOptions: this._loginOptions}))\n );\n this.emitChange(\"startSSOLoginViewModel\");\n }\n\n private _showError(message: string): void {\n this._errorMessage = message;\n this.emitChange(\"errorMessage\");\n }\n\n private _setBusy(status: boolean): void {\n this._isBusy = status;\n this._passwordLoginViewModel?.setBusy(status);\n this._startSSOLoginViewModel?.setBusy(status);\n this.emitChange(\"isBusy\");\n }\n\n async attemptLogin(loginMethod: ILoginMethod): Promise {\n this._setBusy(true);\n void this._client.startWithLogin(loginMethod, {inspectAccountSetup: true});\n const loadStatus = this._client.loadStatus;\n const handle = loadStatus.waitFor((status: LoadStatus) => status !== LoadStatus.Login);\n await handle.promise;\n this._setBusy(false);\n const status = loadStatus.get();\n if (status === LoadStatus.LoginFailed) {\n return this._client.loginFailure;\n }\n this._hideHomeserver = true;\n this.emitChange(\"hideHomeserver\");\n this._disposeViewModels();\n void this._createLoadViewModel();\n return null;\n }\n\n private _createLoadViewModel(): void {\n this._loadViewModelSubscription = this.disposeTracked(this._loadViewModelSubscription);\n this._loadViewModel = this.disposeTracked(this._loadViewModel);\n this._loadViewModel = this.track(\n new SessionLoadViewModel(\n this.childOptions({\n ready: (client) => {\n // make sure we don't delete the session in dispose when navigating away\n this._client = null;\n this._ready(client);\n },\n client: this._client,\n homeserver: this._homeserver\n })\n )\n );\n void this._loadViewModel.start();\n this.emitChange(\"loadViewModel\");\n this._loadViewModelSubscription = this.track(\n this._loadViewModel.disposableOn(\"change\", () => {\n if (!this._loadViewModel.loading) {\n this._loadViewModelSubscription = this.disposeTracked(this._loadViewModelSubscription);\n }\n this._setBusy(false);\n })\n );\n }\n\n private _disposeViewModels(): void {\n this._startSSOLoginViewModel = this.disposeTracked(this._startSSOLoginViewModel);\n this._passwordLoginViewModel = this.disposeTracked(this._passwordLoginViewModel);\n this._completeSSOLoginViewModel = this.disposeTracked(this._completeSSOLoginViewModel);\n this.emitChange(\"disposeViewModels\");\n }\n\n async setHomeserver(newHomeserver: string): Promise {\n this._homeserver = newHomeserver;\n // clear everything set by queryHomeserver\n this._loginOptions = undefined;\n this._queriedHomeserver = undefined;\n this._showError(\"\");\n this._disposeViewModels();\n this._abortQueryOperation = this.disposeTracked(this._abortQueryOperation);\n this.emitChange(\"loginViewModels\"); // multiple fields changing\n // also clear the timeout if it is still running\n this.disposeTracked(this._abortHomeserverQueryTimeout);\n const timeout = this.clock.createTimeout(1000);\n this._abortHomeserverQueryTimeout = this.track(() => timeout.abort());\n try {\n await timeout.elapsed();\n } catch (err) {\n if (err.name === \"AbortError\") {\n return; // still typing, don't query\n } else {\n throw err;\n }\n }\n this._abortHomeserverQueryTimeout = this.disposeTracked(this._abortHomeserverQueryTimeout);\n void this.queryHomeserver();\n }\n\n async queryHomeserver(): Promise {\n // don't repeat a query we've just done\n if (this._homeserver === this._queriedHomeserver || this._homeserver === \"\") {\n return;\n }\n this._queriedHomeserver = this._homeserver;\n // given that setHomeserver already clears everything set here,\n // and that is the only way to change the homeserver,\n // we don't need to reset things again here.\n // However, clear things set by setHomeserver:\n // if query is called before the typing timeout hits (e.g. field lost focus),\n // cancel the timeout so we don't query again.\n this._abortHomeserverQueryTimeout = this.disposeTracked(this._abortHomeserverQueryTimeout);\n // cancel ongoing query operation, if any\n this._abortQueryOperation = this.disposeTracked(this._abortQueryOperation);\n try {\n const queryOperation = this._client.queryLogin(this._homeserver);\n this._abortQueryOperation = this.track(() => queryOperation.abort());\n this.emitChange(\"isFetchingLoginOptions\");\n this._loginOptions = await queryOperation.result;\n this.emitChange(\"resolvedHomeserver\");\n }\n catch (e) {\n if (e.name === \"AbortError\") {\n return; //aborted, bail out\n } else {\n this._loginOptions = undefined;\n }\n } finally {\n this._abortQueryOperation = this.disposeTracked(this._abortQueryOperation);\n this.emitChange(\"isFetchingLoginOptions\");\n }\n if (this._loginOptions) {\n if (this._loginOptions.sso) { this._showSSOLogin(); }\n if (this._loginOptions.password) { this._showPasswordLogin(); }\n if (!this._loginOptions.sso && !this._loginOptions.password) {\n this._showError(\"This homeserver supports neither SSO nor password based login flows\");\n }\n }\n else {\n this._showError(`Could not query login methods supported by ${this.homeserver}`);\n }\n }\n\n dispose(): void {\n super.dispose();\n if (this._client) {\n // if we move away before we're done with initial sync\n // delete the session\n void this._client.deleteSession();\n }\n }\n}\n\ntype ReadyFn = (client: Client) => void;\n\n// TODO: move to Client.js when its converted to typescript.\nexport type LoginOptions = {\n homeserver: string;\n password?: (username: string, password: string) => PasswordLoginMethod;\n sso?: SSOLoginHelper;\n token?: (loginToken: string) => TokenLoginMethod;\n};\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Options as BaseOptions, ViewModel} from \"./ViewModel\";\nimport {Client} from \"../matrix/Client.js\";\nimport {SegmentType} from \"./navigation/index\";\n\ntype Options = { sessionId: string; } & BaseOptions;\n\nexport class LogoutViewModel extends ViewModel {\n private _sessionId: string;\n private _busy: boolean;\n private _showConfirm: boolean;\n private _error?: Error;\n\n constructor(options: Options) {\n super(options);\n this._sessionId = options.sessionId;\n this._busy = false;\n this._showConfirm = true;\n this._error = undefined;\n }\n\n get showConfirm(): boolean {\n return this._showConfirm;\n }\n\n get busy(): boolean {\n return this._busy;\n }\n\n get cancelUrl(): string | undefined {\n return this.urlRouter.urlForSegment(\"session\", true);\n }\n\n async logout(): Promise {\n this._busy = true;\n this._showConfirm = false;\n this.emitChange(\"busy\");\n try {\n const client = new Client(this.platform);\n await client.startLogout(this._sessionId);\n this.navigation.push(\"session\", true);\n } catch (err) {\n this._error = err;\n this._busy = false;\n this.emitChange(\"busy\");\n }\n }\n\n get status(): string {\n if (this._error) {\n return this.i18n`Could not log out of device: ${this._error.message}`;\n } else {\n return this.i18n`Logging out… Please don't close the app.`;\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Options as BaseOptions, ViewModel} from \"./ViewModel\";\nimport {Client} from \"../matrix/Client.js\";\nimport {SegmentType} from \"./navigation/index\";\n\ntype Options = { sessionId: string; } & BaseOptions;\n\nexport class ForcedLogoutViewModel extends ViewModel {\n private _sessionId: string;\n private _error?: Error;\n private _logoutPromise: Promise;\n private _showStatus: boolean = false;\n private _showSpinner: boolean = false;\n\n constructor(options: Options) {\n super(options);\n this._sessionId = options.sessionId;\n // Start the logout process immediately without any user interaction\n this._logoutPromise = this.forceLogout();\n }\n\n async forceLogout(): Promise {\n try {\n const client = new Client(this.platform);\n await client.startForcedLogout(this._sessionId);\n }\n catch (err) {\n this._error = err;\n // Show the error in the UI \n this._showSpinner = false;\n this._showStatus = true;\n this.emitChange(\"error\");\n }\n }\n\n async proceed(): Promise {\n /**\n * The logout should already be completed because we started it from the ctor.\n * In case the logout is still proceeding, we will show a message with a spinner. \n */\n this._showSpinner = true;\n this._showStatus = true;\n this.emitChange(\"showStatus\");\n await this._logoutPromise;\n // At this point, the logout is completed for sure.\n if (!this._error) {\n this.navigation.push(\"login\", true);\n }\n }\n\n get status(): string {\n if (this._error) {\n return this.i18n`Could not log out of device: ${this._error.message}`;\n } else {\n return this.i18n`Logging out… Please don't close the app.`;\n }\n }\n\n get showStatus(): boolean {\n return this._showStatus;\n }\n\n get showSpinner(): boolean {\n return this._showSpinner;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SortedArray} from \"../observable\";\nimport {ViewModel} from \"./ViewModel\";\nimport {avatarInitials, getIdentifierColorNumber} from \"./avatar\";\n\nclass SessionItemViewModel extends ViewModel {\n constructor(options, pickerVM) {\n super(options);\n this._pickerVM = pickerVM;\n this._sessionInfo = options.sessionInfo;\n this._isDeleting = false;\n this._isClearing = false;\n this._error = null;\n this._exportDataUrl = null;\n }\n\n get error() {\n return this._error && this._error.message;\n }\n\n get id() {\n return this._sessionInfo.id;\n }\n\n get openUrl() {\n return this.urlRouter.urlForSegment(\"session\", this.id);\n }\n\n get label() {\n const {userId, comment} = this._sessionInfo;\n if (comment) {\n return `${userId} (${comment})`;\n } else {\n return userId;\n }\n }\n\n get sessionInfo() {\n return this._sessionInfo;\n }\n\n get exportDataUrl() {\n return this._exportDataUrl;\n }\n\n get avatarColorNumber() {\n return getIdentifierColorNumber(this._sessionInfo.userId);\n }\n\n get avatarInitials() {\n return avatarInitials(this._sessionInfo.userId);\n }\n}\n\n\nexport class SessionPickerViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._sessions = new SortedArray((s1, s2) => s1.id.localeCompare(s2.id));\n this._loadViewModel = null;\n this._error = null;\n }\n\n // this loads all the sessions\n async load() {\n const sessions = await this.platform.sessionInfoStorage.getAll();\n this._sessions.setManyUnsorted(sessions.map(s => {\n return new SessionItemViewModel(this.childOptions({sessionInfo: s}), this);\n }));\n }\n\n // for the loading of 1 picked session\n get loadViewModel() {\n return this._loadViewModel;\n }\n\n get sessions() {\n return this._sessions;\n }\n\n get cancelUrl() {\n return this.urlRouter.urlForSegment(\"login\");\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Client} from \"../matrix/Client.js\";\nimport {SessionViewModel} from \"./session/SessionViewModel.js\";\nimport {SessionLoadViewModel} from \"./SessionLoadViewModel.js\";\nimport {LoginViewModel} from \"./login/LoginViewModel\";\nimport {LogoutViewModel} from \"./LogoutViewModel\";\nimport {ForcedLogoutViewModel} from \"./ForcedLogoutViewModel\";\nimport {SessionPickerViewModel} from \"./SessionPickerViewModel.js\";\nimport {ViewModel} from \"./ViewModel\";\n\nexport class RootViewModel extends ViewModel {\n constructor(options) {\n super(options);\n this._error = null;\n this._sessionPickerViewModel = null;\n this._sessionLoadViewModel = null;\n this._loginViewModel = null;\n this._logoutViewModel = null;\n this._forcedLogoutViewModel = null;\n this._sessionViewModel = null;\n this._pendingClient = null;\n }\n\n async load() {\n this.track(this.navigation.observe(\"login\").subscribe(() => this._applyNavigation()));\n this.track(this.navigation.observe(\"session\").subscribe(() => this._applyNavigation()));\n this.track(this.navigation.observe(\"sso\").subscribe(() => this._applyNavigation()));\n this.track(this.navigation.observe(\"logout\").subscribe(() => this._applyNavigation()));\n this._applyNavigation(true);\n }\n\n async _applyNavigation(shouldRestoreLastUrl) {\n const isLogin = this.navigation.path.get(\"login\");\n const logoutSessionId = this.navigation.path.get(\"logout\")?.value;\n const isForcedLogout = this.navigation.path.get(\"forced\")?.value;\n const sessionId = this.navigation.path.get(\"session\")?.value;\n const loginToken = this.navigation.path.get(\"sso\")?.value;\n if (isLogin) {\n if (this.activeSection !== \"login\") {\n this._showLogin();\n }\n } else if (logoutSessionId && isForcedLogout) {\n if (this.activeSection !== \"forced-logout\") {\n this._showForcedLogout(logoutSessionId);\n }\n } else if (logoutSessionId) {\n if (this.activeSection !== \"logout\") {\n this._showLogout(logoutSessionId);\n }\n } else if (sessionId === true) {\n if (this.activeSection !== \"picker\") {\n this._showPicker();\n }\n } else if (sessionId) {\n if (!this._sessionViewModel || this._sessionViewModel.id !== sessionId) {\n // see _showLogin for where _pendingClient comes from\n if (this._pendingClient && this._pendingClient.sessionId === sessionId) {\n const client = this._pendingClient;\n this._pendingClient = null;\n this._showSession(client);\n } else {\n // this should never happen, but we want to be sure not to leak it\n if (this._pendingClient) {\n this._pendingClient.dispose();\n this._pendingClient = null;\n }\n this._showSessionLoader(sessionId);\n }\n }\n } else if (loginToken) {\n this.urlRouter.normalizeUrl();\n if (this.activeSection !== \"login\") {\n this._showLogin(loginToken);\n }\n }\n else {\n try {\n if (!(shouldRestoreLastUrl && this.urlRouter.tryRestoreLastUrl())) {\n const sessionInfos = await this.platform.sessionInfoStorage.getAll();\n if (sessionInfos.length === 0) {\n this.navigation.push(\"login\");\n } else if (sessionInfos.length === 1) {\n this.navigation.push(\"session\", sessionInfos[0].id);\n } else {\n this.navigation.push(\"session\");\n }\n }\n } catch (err) {\n this._setSection(() => this._error = err);\n }\n }\n }\n\n async _showPicker() {\n this._setSection(() => {\n this._sessionPickerViewModel = new SessionPickerViewModel(this.childOptions());\n });\n try {\n await this._sessionPickerViewModel.load();\n } catch (err) {\n this._setSection(() => this._error = err);\n }\n }\n\n _showLogin(loginToken) {\n this._setSection(() => {\n this._loginViewModel = new LoginViewModel(this.childOptions({\n defaultHomeserver: this.platform.config[\"defaultHomeServer\"],\n ready: client => {\n // we don't want to load the session container again,\n // but we also want the change of screen to go through the navigation\n // so we store the session container in a temporary variable that will be\n // consumed by _applyNavigation, triggered by the navigation change\n //\n // Also, we should not call _setSection before the navigation is in the correct state,\n // as url creation (e.g. in RoomTileViewModel)\n // won't be using the correct navigation base path.\n this._pendingClient = client;\n this.navigation.push(\"session\", client.sessionId);\n },\n loginToken\n }));\n });\n }\n\n _showLogout(sessionId) {\n this._setSection(() => {\n this._logoutViewModel = new LogoutViewModel(this.childOptions({sessionId}));\n });\n }\n\n _showForcedLogout(sessionId) {\n this._setSection(() => {\n this._forcedLogoutViewModel = new ForcedLogoutViewModel(this.childOptions({sessionId}));\n });\n }\n\n _showSession(client) {\n this._setSection(() => {\n this._sessionViewModel = new SessionViewModel(this.childOptions({client}));\n this._sessionViewModel.start();\n });\n }\n\n _showSessionLoader(sessionId) {\n const client = new Client(this.platform, this.features);\n client.startWithExistingSession(sessionId);\n this._setSection(() => {\n this._sessionLoadViewModel = new SessionLoadViewModel(this.childOptions({\n client,\n ready: client => this._showSession(client)\n }));\n this._sessionLoadViewModel.start();\n });\n }\n\n get activeSection() {\n if (this._error) {\n return \"error\";\n } else if (this._sessionViewModel) {\n return \"session\";\n } else if (this._loginViewModel) {\n return \"login\";\n } else if (this._logoutViewModel) {\n return \"logout\";\n } else if (this._forcedLogoutViewModel) {\n return \"forced-logout\";\n } else if (this._sessionPickerViewModel) {\n return \"picker\";\n } else if (this._sessionLoadViewModel) {\n return \"loading\";\n } else {\n return \"redirecting\";\n }\n }\n\n _setSection(setter) {\n // clear all members the activeSection depends on\n this._error = null;\n this._sessionPickerViewModel = this.disposeTracked(this._sessionPickerViewModel);\n this._sessionLoadViewModel = this.disposeTracked(this._sessionLoadViewModel);\n this._loginViewModel = this.disposeTracked(this._loginViewModel);\n this._logoutViewModel = this.disposeTracked(this._logoutViewModel);\n this._forcedLogoutViewModel = this.disposeTracked(this._forcedLogoutViewModel);\n this._sessionViewModel = this.disposeTracked(this._sessionViewModel);\n // now set it again\n setter();\n this._sessionPickerViewModel && this.track(this._sessionPickerViewModel);\n this._sessionLoadViewModel && this.track(this._sessionLoadViewModel);\n this._loginViewModel && this.track(this._loginViewModel);\n this._logoutViewModel && this.track(this._logoutViewModel);\n this._forcedLogoutViewModel && this.track(this._forcedLogoutViewModel);\n this._sessionViewModel && this.track(this._sessionViewModel);\n this.emitChange(\"activeSection\");\n }\n\n get error() { return this._error; }\n get sessionViewModel() { return this._sessionViewModel; }\n get loginViewModel() { return this._loginViewModel; }\n get logoutViewModel() { return this._logoutViewModel; }\n get forcedLogoutViewModel() { return this._forcedLogoutViewModel; }\n get sessionPickerViewModel() { return this._sessionPickerViewModel; }\n get sessionLoadViewModel() { return this._sessionLoadViewModel; }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// import {RecordRequester, ReplayRequester} from \"./matrix/net/request/replay\";\nimport {RootViewModel} from \"../../domain/RootViewModel.js\";\nimport {createNavigation, createRouter} from \"../../domain/navigation/index\";\nimport {FeatureSet} from \"../../features\";\n\n// Don't use a default export here, as we use multiple entries during legacy build,\n// which does not support default exports,\n// see https://github.com/rollup/plugins/tree/master/packages/multi-entry\nexport async function main(platform) {\n try {\n // to replay:\n // const fetchLog = await (await fetch(\"/fetchlogs/constrainterror.json\")).json();\n // const replay = new ReplayRequester(fetchLog, {delay: false});\n // const request = replay.request;\n\n // to record:\n // const recorder = new RecordRequester(createFetchRequest(clock.createTimeout));\n // const request = recorder.request;\n // window.getBrawlFetchLog = () => recorder.log();\n await platform.init();\n const features = await FeatureSet.load(platform.settingsStorage);\n const navigation = createNavigation();\n platform.setNavigation(navigation);\n const urlRouter = createRouter({navigation, history: platform.history});\n urlRouter.attach();\n const vm = new RootViewModel({\n platform,\n // the only public interface of the router is to create urls,\n // so we call it that in the view models\n urlRouter: urlRouter,\n navigation,\n features\n });\n await vm.load();\n platform.createAndMountRootView(vm);\n } catch(err) {\n console.error(`${err.message}:\\n${err.stack}`);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ConnectionError} from \"../matrix/error.js\";\nimport type {Timeout} from \"../platform/web/dom/Clock.js\"\nimport type {IAbortable} from \"./AbortableOperation\";\n\ntype TimeoutCreator = (ms: number) => Timeout;\n\nexport function abortOnTimeout(createTimeout: TimeoutCreator, timeoutAmount: number, requestResult: IAbortable, responsePromise: Promise) {\n const timeout = createTimeout(timeoutAmount);\n // abort request if timeout finishes first\n let timedOut = false;\n timeout.elapsed().then(\n () => {\n timedOut = true;\n requestResult.abort();\n },\n () => {} // ignore AbortError when timeout is aborted\n );\n // abort timeout if request finishes first\n return responsePromise.then(\n response => {\n timeout.abort();\n return response;\n },\n err => {\n timeout.abort();\n // map error to TimeoutError\n if (err.name === \"AbortError\" && timedOut) {\n throw new ConnectionError(`Request timed out after ${timeoutAmount}ms`, true);\n } else {\n throw err;\n }\n }\n );\n}\n\n// because impunity only takes one entrypoint currently,\n// these tests aren't run by yarn test as that does not\n// include platform specific code,\n// and this file is only included by platform specific code,\n// see how to run in package.json and replace src/main.js with this file.\nimport {Clock as MockClock} from \"../mocks/Clock.js\";\nimport {Request as MockRequest} from \"../mocks/Request.js\";\nimport {AbortError} from \"../matrix/error.js\";\nexport function tests() {\n return {\n \"ConnectionError on timeout\": async assert => {\n const clock = new MockClock();\n const request = new MockRequest();\n const promise = abortOnTimeout(clock.createTimeout, 10000, request, request.response());\n clock.elapse(10000);\n await assert.rejects(promise, ConnectionError);\n assert(request.aborted);\n },\n \"Abort is canceled once response resolves\": async assert => {\n const clock = new MockClock();\n const request = new MockRequest();\n const promise = abortOnTimeout(clock.createTimeout, 10000, request, request.response());\n request.resolve(5);\n clock.elapse(10000);\n assert(!request.aborted);\n assert.equal(await promise, 5);\n },\n \"AbortError from request is not mapped to ConnectionError\": async assert => {\n const clock = new MockClock();\n const request = new MockRequest();\n const promise = abortOnTimeout(clock.createTimeout, 10000, request, request.response());\n request.reject(new AbortError());\n assert(!request.aborted);\n assert.rejects(promise, AbortError);\n }\n }\n\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function addCacheBuster(urlStr, random = Math.random) {\n // XHR doesn't have a good way to disable cache,\n // so add a random query param\n // see https://davidtranscend.com/blog/prevent-ie11-cache-ajax-requests/\n if (urlStr.includes(\"?\")) {\n urlStr = urlStr + \"&\";\n } else {\n urlStr = urlStr + \"?\";\n }\n return urlStr + `_cacheBuster=${Math.ceil(random() * Number.MAX_SAFE_INTEGER)}`;\n}\n\nexport function mapAsFormData(map) {\n const formData = new FormData();\n for (const [name, value] of map) {\n // Special case {name: string, blob: BlobHandle} to set a filename.\n // This is the format returned by platform.openFile\n if (value.blob?.nativeBlob && value.name) {\n formData.set(name, value.blob.nativeBlob, value.name);\n } else {\n formData.set(name, value);\n }\n }\n return formData;\n}\n\nexport function tests() {\n return {\n \"add cache buster\": assert => {\n const random = () => 0.5;\n assert.equal(addCacheBuster(\"http://foo\", random), \"http://foo?_cacheBuster=4503599627370496\");\n assert.equal(addCacheBuster(\"http://foo?bar=baz\", random), \"http://foo?bar=baz&_cacheBuster=4503599627370496\");\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {\n AbortError,\n ConnectionError\n} from \"../../../../matrix/error.js\";\nimport {addCacheBuster, mapAsFormData} from \"./common.js\";\n\nclass RequestResult {\n constructor(promise, xhr) {\n this._promise = promise;\n this._xhr = xhr;\n }\n\n abort() {\n this._xhr.abort();\n }\n\n response() {\n return this._promise;\n }\n}\n\nfunction createXhr(url, {method, headers, timeout, format, uploadProgress}) {\n const xhr = new XMLHttpRequest();\n\n if (uploadProgress) {\n xhr.upload.addEventListener(\"progress\", evt => uploadProgress(evt.loaded));\n }\n\n xhr.open(method, url);\n \n if (format === \"buffer\") {\n // important to call this after calling open\n xhr.responseType = \"arraybuffer\";\n }\n if (headers) {\n for(const [name, value] of headers.entries()) {\n try {\n xhr.setRequestHeader(name, value);\n } catch (err) {\n console.info(`Could not set ${name} header: ${err.message}`);\n }\n }\n }\n if (timeout) {\n xhr.timeout = timeout;\n }\n\n return xhr;\n}\n\nfunction xhrAsPromise(xhr, method, url) {\n return new Promise((resolve, reject) => {\n xhr.addEventListener(\"load\", () => resolve(xhr));\n xhr.addEventListener(\"abort\", () => reject(new AbortError()));\n xhr.addEventListener(\"error\", () => reject(new ConnectionError(`Error ${method} ${url}`)));\n xhr.addEventListener(\"timeout\", () => reject(new ConnectionError(`Timeout ${method} ${url}`, true)));\n });\n}\n\nexport function xhrRequest(url, options) {\n let {cache, format, body, method} = options;\n if (!cache) {\n url = addCacheBuster(url);\n }\n const xhr = createXhr(url, options);\n const promise = xhrAsPromise(xhr, method, url).then(xhr => {\n const {status} = xhr;\n let body = null;\n if (format === \"buffer\") {\n body = xhr.response;\n } else if (xhr.getResponseHeader(\"Content-Type\") === \"application/json\") {\n body = JSON.parse(xhr.responseText);\n }\n return {status, body};\n });\n\n // if a BlobHandle, take native blob\n if (body?.nativeBlob) {\n body = body.nativeBlob;\n }\n if (body instanceof Map) {\n body = mapAsFormData(body);\n }\n xhr.send(body || null);\n\n return new RequestResult(promise, xhr);\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {\n AbortError,\n ConnectionError\n} from \"../../../../matrix/error.js\";\nimport {abortOnTimeout} from \"../../../../utils/timeout\";\nimport {addCacheBuster, mapAsFormData} from \"./common.js\";\nimport {xhrRequest} from \"./xhr.js\";\n\nclass RequestResult {\n constructor(promise, controller) {\n if (!controller) {\n const abortPromise = new Promise((_, reject) => {\n this._controller = {\n abort() {\n const err = new Error(\"fetch request aborted\");\n err.name = \"AbortError\";\n reject(err);\n }\n };\n });\n this.promise = Promise.race([promise, abortPromise]);\n } else {\n this.promise = promise;\n this._controller = controller;\n }\n }\n\n abort() {\n this._controller.abort();\n }\n\n response() {\n return this.promise;\n }\n}\n\nexport function createFetchRequest(createTimeout, serviceWorkerHandler) {\n return function fetchRequest(url, requestOptions) {\n if (serviceWorkerHandler?.haltRequests) {\n // prevent any requests while waiting\n // for the new service worker to get activated.\n // Once this happens, the page will be reloaded\n // by the serviceWorkerHandler so this is fine.\n return new RequestResult(new Promise(() => {}), {});\n }\n // fetch doesn't do upload progress yet, delegate to xhr\n if (requestOptions?.uploadProgress) {\n return xhrRequest(url, requestOptions);\n }\n let {method, headers, body, timeout, format, cache = false} = requestOptions;\n const controller = typeof AbortController === \"function\" ? new AbortController() : null;\n // if a BlobHandle, take native blob\n if (body?.nativeBlob) {\n body = body.nativeBlob;\n }\n if (body instanceof Map) {\n body = mapAsFormData(body);\n }\n let options = {method, body};\n if (controller) {\n options = Object.assign(options, {\n signal: controller.signal\n });\n }\n if (!cache) {\n url = addCacheBuster(url);\n }\n options = Object.assign(options, {\n mode: \"cors\",\n credentials: \"omit\",\n referrer: \"no-referrer\",\n // ideally we'd turn off cache here, but Safari interprets\n // `Access-Control-Allow-Headers` strictly (only when fetch is\n // intercepted by a service worker strangely enough), in that\n // it gives a CORS error if Cache-Control is not present\n // in the list of allowed headers (which it isn't commonly, at least not on matrix.org).\n // With no-store or no-cache here, it does set `Cache-Control`\n // so we don't do that, and prevent caching with `addCacheBuster`.\n // We also hope the server responds with `Cache-Control: no-store` so\n // we don't fill the http cache with api responses.\n // \n // cache: \"no-store\",\n cache: \"default\",\n });\n if (headers) {\n const fetchHeaders = new Headers();\n for(const [name, value] of headers.entries()) {\n fetchHeaders.append(name, value);\n }\n options.headers = fetchHeaders;\n }\n const promise = fetch(url, options).then(async response => {\n const {status} = response;\n let body;\n try {\n if (format === \"json\") {\n body = await response.json();\n } else if (format === \"buffer\") {\n body = await response.arrayBuffer();\n }\n else if (format === \"text\") {\n body = await response.text();\n }\n } catch (err) {\n // some error pages return html instead of json, ignore error\n // detect these ignored errors from the response status \n if (!(err.name === \"SyntaxError\" && status >= 400)) {\n throw err;\n }\n }\n return {status, body};\n }, err => {\n if (err.name === \"AbortError\") {\n // map DOMException with name AbortError to our own AbortError type\n // as we don't want DOMExceptions in the protocol layer.\n throw new AbortError();\n } else if (err instanceof TypeError) {\n // Network errors are reported as TypeErrors, see\n // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful\n // this can either mean user is offline, server is offline, or a CORS error (server misconfiguration).\n // \n // One could check navigator.onLine to rule out the first\n // but the 2 latter ones are indistinguishable from javascript.\n throw new ConnectionError(`${method} ${url}: ${err.message}`);\n }\n throw err;\n });\n const result = new RequestResult(promise, controller);\n\n if (timeout) {\n result.promise = abortOnTimeout(createTimeout, timeout, result, result.promise);\n }\n\n return result;\n } \n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\ninterface ISessionInfo {\n id: string;\n deviceId: string;\n userId: string;\n homeserver: string;\n homeServer: string; // deprecate this over time\n accessToken: string;\n lastUsed: number;\n /**\n * If true, then this session will not be used for sending\n * encrypted messages.\n * OTK uploads will be disabled when this is true.\n * \n * Encrypted messages can still be decrypted and key backups\n * can also be restored.\n */\n isReadOnly: boolean;\n}\n\n// todo: this should probably be in platform/types?\ninterface ISessionInfoStorage {\n getAll(): Promise;\n updateLastUsed(id: string, timestamp: number): Promise;\n updateAccessToken(id: string, token: string): Promise;\n get(id: string): Promise;\n add(sessionInfo: ISessionInfo): Promise;\n delete(sessionId: string): Promise;\n}\n\nexport class SessionInfoStorage implements ISessionInfoStorage {\n private readonly _name: string;\n\n constructor(name: string) {\n this._name = name;\n }\n\n getAll(): Promise {\n const sessionsJson = localStorage.getItem(this._name);\n if (sessionsJson) {\n const sessions = JSON.parse(sessionsJson);\n if (Array.isArray(sessions)) {\n return Promise.resolve(sessions);\n }\n }\n return Promise.resolve([]);\n }\n\n async updateAccessToken(id: string, accessToken: string): Promise {\n const sessions = await this.getAll();\n const session = sessions.find(session => session.id === id);\n if (!session) {\n throw Error('No session found');\n }\n session.accessToken = accessToken;\n localStorage.setItem(this._name, JSON.stringify(sessions));\n }\n\n async updateLastUsed(id: string, timestamp: number): Promise {\n const sessions = await this.getAll();\n const session = sessions.find(session => session.id === id);\n if (session) {\n session.lastUsed = timestamp;\n localStorage.setItem(this._name, JSON.stringify(sessions));\n }\n }\n\n async get(id: string): Promise {\n const sessions = await this.getAll();\n if (sessions) {\n return sessions.find(session => session.id === id);\n }\n }\n\n async add(sessionInfo: ISessionInfo): Promise {\n const sessions = await this.getAll();\n sessions.push(sessionInfo);\n localStorage.setItem(this._name, JSON.stringify(sessions));\n }\n\n async delete(sessionId: string): Promise {\n let sessions = await this.getAll();\n sessions = sessions.filter(s => s.id !== sessionId);\n localStorage.setItem(this._name, JSON.stringify(sessions));\n }\n \n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class SettingsStorage {\n constructor(prefix) {\n this._prefix = prefix;\n }\n\n async setInt(key, value) {\n this._set(key, value);\n }\n\n async getInt(key, defaultValue = 0) {\n const value = window.localStorage.getItem(`${this._prefix}${key}`);\n if (typeof value === \"string\") {\n return parseInt(value, 10);\n }\n return defaultValue;\n }\n\n async setBool(key, value) {\n this._set(key, value);\n }\n\n async getBool(key, defaultValue = false) {\n const value = window.localStorage.getItem(`${this._prefix}${key}`);\n if (typeof value === \"string\") {\n return value === \"true\";\n }\n return defaultValue;\n }\n\n async setString(key, value) {\n this._set(key, value);\n }\n\n async getString(key) {\n return window.localStorage.getItem(`${this._prefix}${key}`);\n }\n\n async remove(key) {\n window.localStorage.removeItem(`${this._prefix}${key}`);\n }\n\n async _set(key, value) {\n window.localStorage.setItem(`${this._prefix}${key}`, value);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nexport class UTF8 {\n constructor() {\n this._encoder = null;\n this._decoder = null;\n }\n\n encode(str) {\n if (!this._encoder) {\n this._encoder = new TextEncoder();\n }\n return this._encoder.encode(str);\n }\n\n decode(buffer) {\n if (!this._decoder) {\n this._decoder = new TextDecoder();\n }\n return this._decoder.decode(buffer);\n }\n}\n","/*\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n(function(){\n \"use strict\";\n\n var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n // Use a lookup table to find the index.\n var lookup = new Uint8Array(256);\n for (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n }\n\n exports.encode = function(arraybuffer) {\n var bytes = new Uint8Array(arraybuffer),\n i, len = bytes.length, base64 = \"\";\n\n for (i = 0; i < len; i+=3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n base64 += chars[bytes[i + 2] & 63];\n }\n\n if ((len % 3) === 2) {\n base64 = base64.substring(0, base64.length - 1) + \"=\";\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + \"==\";\n }\n\n return base64;\n };\n\n exports.decode = function(base64) {\n var bufferLength = base64.length * 0.75,\n len = base64.length, i, p = 0,\n encoded1, encoded2, encoded3, encoded4;\n\n if (base64[base64.length - 1] === \"=\") {\n bufferLength--;\n if (base64[base64.length - 2] === \"=\") {\n bufferLength--;\n }\n }\n\n var arraybuffer = new ArrayBuffer(bufferLength),\n bytes = new Uint8Array(arraybuffer);\n\n for (i = 0; i < len; i+=4) {\n encoded1 = lookup[base64.charCodeAt(i)];\n encoded2 = lookup[base64.charCodeAt(i+1)];\n encoded3 = lookup[base64.charCodeAt(i+2)];\n encoded4 = lookup[base64.charCodeAt(i+3)];\n\n bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n\n return arraybuffer;\n };\n})();\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport base64 from \"base64-arraybuffer\";\n\nexport class Base64 {\n encodeUnpadded(buffer) {\n const str = base64.encode(buffer);\n const paddingIdx = str.indexOf(\"=\");\n if (paddingIdx !== -1) {\n return str.substr(0, paddingIdx);\n } else {\n return str;\n }\n }\n\n encode(buffer) {\n return base64.encode(buffer);\n }\n\n decode(str) {\n return base64.decode(str);\n }\n}\n","var Buffer = {\n isBuffer: function(array) {return array instanceof Uint8Array;},\n from: function(arrayBuffer) {return arrayBuffer;},\n allocUnsafe: function(size) {return Buffer.alloc(size);},\n alloc: function(size) {return new Uint8Array(size);}\n};\nexport default Buffer;\n","'use strict'\n// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\n// @ts-ignore\nvar _Buffer = require('safe-buffer').Buffer\nfunction base (ALPHABET) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n var BASE_MAP = new Uint8Array(256)\n for (var j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n for (var i = 0; i < ALPHABET.length; i++) {\n var x = ALPHABET.charAt(i)\n var xc = x.charCodeAt(0)\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i\n }\n var BASE = ALPHABET.length\n var LEADER = ALPHABET.charAt(0)\n var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n function encode (source) {\n if (Array.isArray(source) || source instanceof Uint8Array) { source = _Buffer.from(source) }\n if (!_Buffer.isBuffer(source)) { throw new TypeError('Expected Buffer') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n var zeroes = 0\n var length = 0\n var pbegin = 0\n var pend = source.length\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++\n zeroes++\n }\n // Allocate enough space in big-endian base58 representation.\n var size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n var b58 = new Uint8Array(size)\n // Process the bytes.\n while (pbegin !== pend) {\n var carry = source[pbegin]\n // Apply \"b58 = b58 * 256 + ch\".\n var i = 0\n for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0\n b58[it1] = (carry % BASE) >>> 0\n carry = (carry / BASE) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n pbegin++\n }\n // Skip leading zeroes in base58 result.\n var it2 = size - length\n while (it2 !== size && b58[it2] === 0) {\n it2++\n }\n // Translate the result into a string.\n var str = LEADER.repeat(zeroes)\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }\n return str\n }\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return _Buffer.alloc(0) }\n var psz = 0\n // Skip leading spaces.\n if (source[psz] === ' ') { return }\n // Skip and count leading '1's.\n var zeroes = 0\n var length = 0\n while (source[psz] === LEADER) {\n zeroes++\n psz++\n }\n // Allocate enough space in big-endian base256 representation.\n var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.\n var b256 = new Uint8Array(size)\n // Process the characters.\n while (source[psz]) {\n // Decode character\n var carry = BASE_MAP[source.charCodeAt(psz)]\n // Invalid character\n if (carry === 255) { return }\n var i = 0\n for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0\n b256[it3] = (carry % 256) >>> 0\n carry = (carry / 256) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n psz++\n }\n // Skip trailing spaces.\n if (source[psz] === ' ') { return }\n // Skip leading zeroes in b256.\n var it4 = size - length\n while (it4 !== size && b256[it4] === 0) {\n it4++\n }\n var vch = _Buffer.allocUnsafe(zeroes + (size - it4))\n vch.fill(0x00, 0, zeroes)\n var j = zeroes\n while (it4 !== size) {\n vch[j++] = b256[it4++]\n }\n return vch\n }\n function decode (string) {\n var buffer = decodeUnsafe(string)\n if (buffer) { return buffer }\n throw new Error('Non-base' + BASE + ' character')\n }\n return {\n encode: encode,\n decodeUnsafe: decodeUnsafe,\n decode: decode\n }\n}\nmodule.exports = base\n","var basex = require('base-x')\nvar ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\n\nmodule.exports = basex(ALPHABET)\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport bs58 from \"bs58\";\n\nexport class Base58 {\n encode(buffer) {\n return bs58.encode(buffer);\n }\n\n decode(str) {\n return bs58.decode(str);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {UTF8} from \"../dom/UTF8.js\";\nimport {Base64} from \"./Base64.js\";\nimport {Base58} from \"./Base58.js\";\n\nexport class Encoding {\n constructor() {\n this.utf8 = new UTF8();\n this.base64 = new Base64();\n this.base58 = new Base58();\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class OlmWorker {\n constructor(workerPool) {\n this._workerPool = workerPool;\n }\n\n megolmDecrypt(session, ciphertext) {\n const sessionKey = session.export_session(session.first_known_index());\n return this._workerPool.send({type: \"megolm_decrypt\", ciphertext, sessionKey});\n }\n\n async createAccountAndOTKs(account, otkAmount) {\n // IE11 does not support getRandomValues in a worker, so we have to generate the values upfront.\n let randomValues;\n if (window.msCrypto) {\n randomValues = [\n window.msCrypto.getRandomValues(new Uint8Array(64)),\n window.msCrypto.getRandomValues(new Uint8Array(otkAmount * 32)),\n ];\n }\n const pickle = await this._workerPool.send({type: \"olm_create_account_otks\", randomValues, otkAmount}).response();\n account.unpickle(\"\", pickle);\n }\n\n async createOutboundOlmSession(account, newSession, theirIdentityKey, theirOneTimeKey) {\n const accountPickle = account.pickle(\"\");\n let randomValues;\n if (window.msCrypto) {\n randomValues = [\n window.msCrypto.getRandomValues(new Uint8Array(64)),\n ];\n }\n const sessionPickle = await this._workerPool.send({type: \"olm_create_outbound\", accountPickle, theirIdentityKey, theirOneTimeKey, randomValues}).response();\n newSession.unpickle(\"\", sessionPickle);\n }\n\n dispose() {\n this._workerPool.dispose();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {\n openDatabase,\n txnAsPromise,\n reqAsPromise,\n iterateCursor,\n fetchResults,\n} from \"../matrix/storage/idb/utils\";\nimport type {Interval} from \"../platform/web/dom/Clock\";\nimport type {Platform} from \"../platform/web/Platform.js\";\nimport type {BlobHandle} from \"../platform/web/dom/BlobHandle.js\";\nimport type {ILogItem, ILogger, ILogReporter, ISerializedItem} from \"./types\";\nimport {LogFilter} from \"./LogFilter\";\n\ntype QueuedItem = {\n json: string;\n id?: number;\n}\n\ntype Options = {\n name: string,\n flushInterval?: number,\n limit?: number,\n platform: Platform,\n serializedTransformer?: (item: ISerializedItem) => ISerializedItem\n}\n\nexport class IDBLogPersister implements ILogReporter {\n private readonly _flushInterval: Interval;\n private _queuedItems: QueuedItem[];\n private readonly options: Options;\n private logger?: ILogger;\n\n constructor(options: Options) {\n this.options = options;\n this._queuedItems = this._loadQueuedItems();\n // TODO: also listen for unload just in case sync keeps on running after pagehide is fired?\n window.addEventListener(\"pagehide\", this, false);\n this._flushInterval = this.options.platform.clock.createInterval(\n () => this._tryFlush(),\n this.options.flushInterval ?? 60 * 1000\n );\n }\n\n setLogger(logger: ILogger): void {\n this.logger = logger;\n }\n\n reportItem(logItem: ILogItem, filter: LogFilter, forced: boolean): void {\n const queuedItem = this.prepareItemForQueue(logItem, filter, forced);\n if (queuedItem) {\n this._queuedItems.push(queuedItem);\n }\n }\n\n async export(): Promise {\n const db = await this._openDB();\n try {\n const txn = db.transaction([\"logs\"], \"readonly\");\n const logs = txn.objectStore(\"logs\");\n const storedItems: QueuedItem[] = await fetchResults(logs.openCursor(), () => false);\n const openItems = this.getSerializedOpenItems();\n const allItems = storedItems.concat(this._queuedItems).concat(openItems);\n return new IDBLogExport(allItems, this, this.options.platform);\n } finally {\n try {\n db.close();\n } catch (e) {}\n }\n }\n \n dispose(): void {\n window.removeEventListener(\"pagehide\", this, false);\n this._flushInterval.dispose();\n }\n\n handleEvent(evt: Event): void {\n if (evt.type === \"pagehide\") {\n this._finishAllAndFlush();\n }\n }\n\n private async _tryFlush(): Promise {\n const db = await this._openDB();\n try {\n const txn = db.transaction([\"logs\"], \"readwrite\");\n const logs = txn.objectStore(\"logs\");\n const amount = this._queuedItems.length;\n for(const i of this._queuedItems) {\n logs.add(i);\n }\n const itemCount = await reqAsPromise(logs.count());\n const limit = this.options.limit ?? 3000;\n if (itemCount > limit) {\n // delete an extra 10% so we don't need to delete every time we flush\n let deleteAmount = (itemCount - limit) + Math.round(0.1 * limit);\n await iterateCursor(logs.openCursor(), (_, __, cursor) => {\n cursor.delete();\n deleteAmount -= 1;\n return {done: deleteAmount === 0};\n });\n }\n await txnAsPromise(txn);\n this._queuedItems.splice(0, amount);\n } catch (err) {\n console.error(\"Could not flush logs\", err);\n } finally {\n try {\n db.close();\n } catch (e) {}\n }\n }\n\n private _finishAllAndFlush(): void {\n if (this.logger) {\n this.logger.log({l: \"pagehide, closing logs\", t: \"navigation\"});\n this.logger.forceFinish();\n }\n this._persistQueuedItems(this._queuedItems);\n }\n\n private _loadQueuedItems(): QueuedItem[] {\n const key = `${this.options.name}_queuedItems`;\n try {\n const json = window.localStorage.getItem(key);\n if (json) {\n window.localStorage.removeItem(key);\n return JSON.parse(json);\n }\n } catch (err) {\n console.error(\"Could not load queued log items\", err);\n }\n return [];\n }\n\n private _openDB(): Promise {\n return openDatabase(this.options.name, db => db.createObjectStore(\"logs\", {keyPath: \"id\", autoIncrement: true}), 1);\n }\n\n private prepareItemForQueue(logItem: ILogItem, filter: LogFilter, forced: boolean): QueuedItem | undefined {\n let serializedItem = logItem.serialize(filter, undefined, forced);\n if (serializedItem) {\n if (this.options.serializedTransformer) {\n serializedItem = this.options.serializedTransformer(serializedItem);\n }\n return {\n json: JSON.stringify(serializedItem)\n };\n }\n }\n\n private _persistQueuedItems(items: QueuedItem[]): void {\n try {\n window.localStorage.setItem(`${this.options.name}_queuedItems`, JSON.stringify(items));\n } catch (e) {\n console.error(\"Could not persist queued log items in localStorage, they will likely be lost\", e);\n }\n }\n\n /** @internal called by ILogExport.removeFromStore */\n async removeItems(items: QueuedItem[]): Promise {\n const db = await this._openDB();\n try {\n const txn = db.transaction([\"logs\"], \"readwrite\");\n const logs = txn.objectStore(\"logs\");\n for (const item of items) {\n if (typeof item.id === \"number\") {\n logs.delete(item.id);\n } else {\n // assume the (non-persisted) object in each array will be the same\n const queuedIdx = this._queuedItems.indexOf(item);\n if (queuedIdx === -1) {\n this._queuedItems.splice(queuedIdx, 1);\n }\n }\n }\n await txnAsPromise(txn);\n } finally {\n try {\n db.close();\n } catch (e) {}\n }\n }\n\n private getSerializedOpenItems(): QueuedItem[] {\n const openItems: QueuedItem[] = [];\n if (!this.logger) {\n return openItems;\n }\n const filter = new LogFilter();\n for(const item of this.logger!.getOpenRootItems()) {\n const openItem = this.prepareItemForQueue(item, filter, false);\n if (openItem) {\n openItems.push(openItem);\n }\n }\n return openItems;\n }\n}\n\nexport class IDBLogExport {\n private readonly _items: QueuedItem[];\n private readonly _logger: IDBLogPersister;\n private readonly _platform: Platform;\n\n constructor(items: QueuedItem[], logger: IDBLogPersister, platform: Platform) {\n this._items = items;\n this._logger = logger;\n this._platform = platform;\n }\n \n get count(): number {\n return this._items.length;\n }\n\n /**\n * @return {Promise}\n */\n removeFromStore(): Promise {\n return this._logger.removeItems(this._items);\n }\n\n asBlob(): BlobHandle {\n const json = this.toJSON();\n const buffer: Uint8Array = this._platform.encoding.utf8.encode(json);\n const blob: BlobHandle = this._platform.createBlob(buffer, \"application/json\");\n return blob;\n }\n\n toJSON(): string {\n const log = {\n formatVersion: 1,\n appVersion: this._platform.updateService?.version,\n platform: this._platform.description,\n items: this._items.map(i => JSON.parse(i.json))\n };\n const json = JSON.stringify(log);\n return json;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {ILogger, ILogItem, LogItemValues, ILogReporter} from \"./types\";\nimport type {LogItem} from \"./LogItem\";\n\nexport class ConsoleReporter implements ILogReporter {\n private logger?: ILogger;\n\n reportItem(item: ILogItem): void {\n printToConsole(item as LogItem);\n }\n\n setLogger(logger: ILogger) {\n this.logger = logger;\n }\n\n printOpenItems(): void {\n if (!this.logger) {\n return;\n }\n for (const item of this.logger.getOpenRootItems()) {\n this.reportItem(item);\n }\n }\n}\n\nconst excludedKeysFromTable = [\"l\", \"id\"];\nfunction filterValues(values: LogItemValues): LogItemValues | null {\n return Object.entries(values)\n .filter(([key]) => !excludedKeysFromTable.includes(key))\n .reduce((obj: LogItemValues, [key, value]) => {\n obj = obj || {};\n obj[key] = value;\n return obj;\n }, null);\n}\n\nfunction hasChildWithError(item: LogItem): boolean {\n if (item.error) {\n return true;\n }\n if (item.children) {\n for(const c of item.children) {\n if (hasChildWithError(c)) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction printToConsole(item: LogItem): void {\n const label = `${itemCaption(item)} (@${item.start}ms, duration: ${item.duration}ms)`;\n const filteredValues = filterValues(item.values);\n const shouldGroup = item.children || filteredValues;\n if (shouldGroup) {\n if (hasChildWithError(item)) {\n console.group(label);\n } else {\n console.groupCollapsed(label);\n }\n if (item.error) {\n console.error(item.error);\n }\n } else {\n if (item.error) {\n console.error(item.error);\n } else {\n console.log(label);\n }\n }\n if (filteredValues) {\n console.table(filteredValues);\n }\n if (item.children) {\n for(const c of item.children) {\n printToConsole(c);\n }\n }\n if (shouldGroup) {\n console.groupEnd();\n }\n}\n\nfunction itemCaption(item: ILogItem): string {\n if (item.values.t === \"network\") {\n return `${item.values.method} ${item.values.url}`;\n } else if (item.values.l && typeof item.values.id !== \"undefined\") {\n return `${item.values.l} ${item.values.id}`;\n } else if (item.values.l && typeof item.values.status !== \"undefined\") {\n return `${item.values.l} (${item.values.status})`;\n } else if (item.values.l && typeof item.values.type !== \"undefined\") {\n return `${item.values.l} (${item.values.type})`;\n } else if (item.values.l && item.error) {\n return `${item.values.l} failed`;\n } else if (typeof item.values.ref !== \"undefined\") {\n return `ref ${item.values.ref}`;\n } else {\n return item.values.l || item.values.type;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {LogLevel, LogFilter} from \"./LogFilter\";\nimport type {Logger} from \"./Logger\";\nimport type {ISerializedItem, ILogItem, LogItemValues, LabelOrValues, FilterCreator, LogCallback} from \"./types\";\n\nexport class LogItem implements ILogItem {\n public readonly start: number;\n public logLevel: LogLevel;\n public error?: Error;\n public end?: number;\n private _values: LogItemValues;\n protected _logger: Logger;\n private _filterCreator?: FilterCreator;\n private _children?: Array;\n private _discard: boolean = false;\n\n constructor(labelOrValues: LabelOrValues, logLevel: LogLevel, logger: Logger, filterCreator?: FilterCreator) {\n this._logger = logger;\n this.start = logger._now();\n // (l)abel\n this._values = typeof labelOrValues === \"string\" ? {l: labelOrValues} : labelOrValues;\n this.logLevel = logLevel;\n this._filterCreator = filterCreator;\n }\n\n /**\n * Prevents this log item from being present in the exported output.\n */\n discard(): void {\n this._discard = true;\n }\n\n /** start a new root log item and run it detached mode, see Logger.runDetached */\n runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem {\n return this._logger.runDetached(labelOrValues, callback, logLevel, filterCreator);\n }\n\n /** start a new detached root log item and log a reference to it from this item */\n wrapDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): void {\n this.refDetached(this.runDetached(labelOrValues, callback, logLevel, filterCreator));\n }\n\n /** logs a reference to a different log item, usually obtained from runDetached.\n This is useful if the referenced operation can't be awaited. */\n refDetached(logItem: ILogItem, logLevel?: LogLevel): void {\n logItem.ensureRefId();\n this.log({ref: logItem.values.refId}, logLevel);\n }\n\n ensureRefId(): void {\n if (!this._values.refId) {\n this.set(\"refId\", this._logger._createRefId());\n }\n }\n\n /**\n * Creates a new child item and runs it in `callback`.\n */\n wrap(labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): T {\n const item = this.child(labelOrValues, logLevel, filterCreator);\n return item.run(callback);\n }\n\n get duration(): number | undefined {\n if (this.end) {\n return this.end - this.start;\n } else {\n return undefined;\n }\n }\n\n durationWithoutType(type: string): number | undefined {\n const durationOfType = this.durationOfType(type);\n if (this.duration && durationOfType) {\n return this.duration - durationOfType;\n }\n }\n\n durationOfType(type: string): number | undefined {\n if (this._values.t === type) {\n return this.duration;\n } else if (this._children) {\n return this._children.reduce((sum, c) => {\n const duration = c.durationOfType(type);\n return sum + (duration ?? 0);\n }, 0);\n } else {\n return 0;\n }\n }\n \n /**\n * Creates a new child item that finishes immediately\n * Finished items should not be modified anymore as they can be serialized\n * at any stage, but using `set` on the return value in a synchronous way should still be safe.\n */\n log(labelOrValues: LabelOrValues, logLevel?: LogLevel): ILogItem {\n const item = this.child(labelOrValues, logLevel);\n item.end = item.start;\n return item;\n }\n\n set(key: string | object, value?: unknown): ILogItem {\n if(typeof key === \"object\") {\n const values = key;\n Object.assign(this._values, values);\n } else {\n this._values[key] = value;\n }\n return this;\n }\n\n serialize(filter: LogFilter, parentStartTime: number | undefined, forced: boolean): ISerializedItem | undefined {\n if (this._discard) {\n return;\n }\n if (this._filterCreator) {\n try {\n filter = this._filterCreator(new LogFilter(filter), this);\n } catch (err) {\n console.error(\"Error creating log filter\", err);\n }\n }\n let children: Array | null = null;\n if (this._children) {\n children = this._children.reduce((array: Array, c) => {\n const s = c.serialize(filter, this.start, false);\n if (s) {\n if (array === null) {\n array = [];\n }\n array.push(s);\n }\n return array;\n }, null);\n }\n if (filter && !filter.filter(this, children)) {\n return;\n }\n // in (v)alues, (l)abel and (t)ype are also reserved.\n const item: ISerializedItem = {\n // (s)tart\n s: typeof parentStartTime === \"number\" ? this.start - parentStartTime : this.start,\n // (d)uration\n d: this.duration,\n // (v)alues\n v: this._values,\n // (l)evel\n l: this.logLevel\n };\n if (this.error) {\n // (e)rror\n item.e = {\n stack: this.error.stack,\n name: this.error.name,\n message: this.error.message.split(\"\\n\")[0]\n };\n }\n if (forced) {\n item.f = true; //(f)orced\n }\n if (children) {\n // (c)hildren\n item.c = children;\n }\n return item;\n }\n\n /**\n * You probably want to use `wrap` instead of this.\n * \n * Runs a callback passing this log item,\n * recording the timing and any error.\n *\n * callback can return a Promise.\n *\n * Should only be called once.\n * \n * @param {Function} callback [description]\n * @return {[type]} [description]\n */\n run(callback: LogCallback): T {\n if (this.end !== undefined) {\n console.trace(\"log item is finished, additional logs will likely not be recorded\");\n }\n try {\n const result = callback(this);\n if (result instanceof Promise) {\n return result.then(promiseResult => {\n this.finish();\n return promiseResult;\n }, err => {\n throw this.catch(err);\n }) as unknown as T;\n } else {\n this.finish();\n return result;\n }\n } catch (err) {\n throw this.catch(err);\n }\n }\n\n /**\n * finished the item, recording the end time. After finishing, an item can't be modified anymore as it will be persisted.\n * @internal shouldn't typically be called by hand. allows to force finish if a promise is still running when closing the app\n */\n finish(): void {\n if (this.end === undefined) {\n if (this._children) {\n for(const c of this._children) {\n c.finish();\n }\n }\n this.end = this._logger._now();\n }\n }\n\n /** @internal */\n forceFinish(): void {\n this.finish();\n }\n\n // expose log level without needing import everywhere\n get level(): typeof LogLevel {\n return LogLevel;\n }\n\n catch(err: Error): Error {\n this.error = err;\n this.logLevel = LogLevel.Error;\n this.finish();\n return err;\n }\n\n child(labelOrValues: LabelOrValues, logLevel?: LogLevel, filterCreator?: FilterCreator): LogItem {\n if (this.end) {\n console.trace(`log item ${this.values.l} finished, additional log ${JSON.stringify(labelOrValues)} will likely not be recorded`);\n }\n if (!logLevel) {\n logLevel = this.logLevel || LogLevel.Info;\n }\n const item = new LogItem(labelOrValues, logLevel, this._logger, filterCreator);\n if (!this._children) {\n this._children = [];\n }\n this._children.push(item);\n return item;\n }\n\n get logger(): Logger {\n return this._logger;\n }\n\n get values(): LogItemValues {\n return this._values;\n }\n\n get children(): Array | undefined {\n return this._children;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {LogItem} from \"./LogItem\";\nimport {LogLevel, LogFilter} from \"./LogFilter\";\nimport type {ILogger, ILogReporter, FilterCreator, LabelOrValues, LogCallback, ILogItem, ISerializedItem} from \"./types\";\nimport type {Platform} from \"../platform/web/Platform.js\";\n\nexport class Logger implements ILogger {\n protected _openItems: Set = new Set();\n protected _platform: Platform;\n protected _serializedTransformer: (item: ISerializedItem) => ISerializedItem;\n public readonly reporters: ILogReporter[] = [];\n\n constructor({platform}) {\n this._platform = platform;\n }\n\n log(labelOrValues: LabelOrValues, logLevel: LogLevel = LogLevel.Info): ILogItem {\n const item = new LogItem(labelOrValues, logLevel, this);\n item.end = item.start;\n this._persistItem(item, undefined, false);\n return item;\n }\n\n /** Prefer `run()` or `log()` above this method; only use it if you have a long-running operation\n * *without* a single call stack that should be logged into one sub-tree.\n * You need to call `finish()` on the returned item or it will stay open until the app unloads. */\n child(labelOrValues: LabelOrValues, logLevel: LogLevel = LogLevel.Info, filterCreator?: FilterCreator): ILogItem {\n const item = new DeferredPersistRootLogItem(labelOrValues, logLevel, this, filterCreator);\n this._openItems.add(item);\n return item;\n }\n\n /** if item is a log item, wrap the callback in a child of it, otherwise start a new root log item. */\n wrapOrRun(item: ILogItem | undefined, labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): T {\n if (item) {\n return item.wrap(labelOrValues, callback, logLevel, filterCreator);\n } else {\n return this.run(labelOrValues, callback, logLevel, filterCreator);\n }\n }\n\n /** run a callback in detached mode,\n where the (async) result or errors are not propagated but still logged.\n Useful to pair with LogItem.refDetached.\n\n @return {ILogItem} the log item added, useful to pass to LogItem.refDetached */\n runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem {\n if (!logLevel) {\n logLevel = LogLevel.Info;\n }\n const item = new LogItem(labelOrValues, logLevel, this);\n this._run(item, callback, logLevel, false /* don't throw, nobody is awaiting */, filterCreator);\n return item;\n }\n\n /** run a callback wrapped in a log operation.\n Errors and duration are transparently logged, also for async operations.\n Whatever the callback returns is returned here. */\n run(labelOrValues: LabelOrValues, callback: LogCallback, logLevel?: LogLevel, filterCreator?: FilterCreator): T {\n if (logLevel === undefined) {\n logLevel = LogLevel.Info;\n }\n const item = new LogItem(labelOrValues, logLevel, this);\n return this._run(item, callback, logLevel, true, filterCreator);\n }\n\n private _run(item: LogItem, callback: LogCallback, logLevel: LogLevel, wantResult: true, filterCreator?: FilterCreator): T;\n // we don't return if we don't throw, as we don't have anything to return when an error is caught but swallowed for the fire-and-forget case.\n private _run(item: LogItem, callback: LogCallback, logLevel: LogLevel, wantResult: false, filterCreator?: FilterCreator): void;\n private _run(item: LogItem, callback: LogCallback, logLevel: LogLevel, wantResult: boolean, filterCreator?: FilterCreator): T | void {\n this._openItems.add(item);\n\n const finishItem = () => {\n let filter = new LogFilter();\n if (filterCreator) {\n try {\n filter = filterCreator(filter, item);\n } catch (err) {\n console.error(\"Error while creating log filter\", err);\n }\n } else {\n // if not filter is specified, filter out anything lower than the initial log level\n filter = filter.minLevel(logLevel);\n }\n try {\n this._persistItem(item, filter, false);\n } catch (err) {\n console.error(\"Could not persist log item\", err);\n }\n this._openItems.delete(item);\n };\n\n try {\n let result = item.run(callback);\n if (result instanceof Promise) {\n result = result.then(promiseResult => {\n finishItem();\n return promiseResult;\n }, err => {\n finishItem();\n if (wantResult) {\n throw err;\n }\n }) as unknown as T;\n if (wantResult) {\n return result;\n }\n } else {\n finishItem();\n if(wantResult) {\n return result;\n }\n }\n } catch (err) {\n finishItem();\n if (wantResult) {\n throw err;\n }\n }\n }\n\n addReporter(reporter: ILogReporter): void {\n reporter.setLogger(this);\n this.reporters.push(reporter);\n }\n\n getOpenRootItems(): Iterable {\n return this._openItems;\n }\n\n forceFinish() {\n for (const openItem of this._openItems) {\n openItem.forceFinish();\n try {\n // for now, serialize with an all-permitting filter\n // as the createFilter function would get a distorted image anyway\n // about the duration of the item, etc ...\n // true for force finish\n this._persistItem(openItem, new LogFilter(), true);\n } catch (err) {\n console.error(\"Could not serialize log item\", err);\n }\n }\n this._openItems.clear();\n }\n\n /** @internal */\n _removeItemFromOpenList(item: LogItem): void {\n this._openItems.delete(item);\n }\n\n /** @internal */\n _persistItem(item: LogItem, filter?: LogFilter, forced?: boolean): void {\n for (var i = 0; i < this.reporters.length; i += 1) {\n this.reporters[i].reportItem(item, filter, forced);\n }\n }\n\n // expose log level without needing \n get level(): typeof LogLevel {\n return LogLevel;\n }\n\n /** @internal */\n _now(): number {\n return this._platform.clock.now();\n }\n\n /** @internal */\n _createRefId(): number {\n return Math.round(this._platform.random() * Number.MAX_SAFE_INTEGER);\n }\n}\n\nclass DeferredPersistRootLogItem extends LogItem {\n finish() {\n super.finish();\n (this._logger as Logger)._persistItem(this, undefined, false);\n (this._logger as Logger)._removeItemFromOpenList(this);\n }\n\n forceFinish() {\n super.finish();\n /// no need to persist when force-finishing as _finishOpenItems above will do it\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 Daniel Fedorin \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// DOM helper functions\n\nimport {ViewNode} from \"./types\";\n\nexport type ClassNames = { [className: string]: boolean | ((value: T) => boolean) }\nexport type BasicAttributes = { [attribute: string]: ClassNames | boolean | string }\nexport type Child = string | Text | ViewNode;\n\nexport function isChildren(children: object | Child | Child[]): children is Child | Child[] {\n // children should be an not-object (that's the attributes), or a domnode, or an array\n return typeof children !== \"object\" || \"nodeType\" in children || Array.isArray(children);\n}\n\nexport function classNames(obj: ClassNames, value: T): string {\n return Object.entries(obj).reduce((cn, [name, enabled]) => {\n if (typeof enabled === \"function\") {\n enabled = enabled(value);\n }\n if (enabled) {\n return cn + (cn.length ? \" \" : \"\") + name;\n } else {\n return cn;\n }\n }, \"\");\n}\n\nexport function setAttribute(el: Element, name: string, value: string | boolean): void {\n if (name === \"className\") {\n name = \"class\";\n }\n if (value === false) {\n el.removeAttribute(name);\n } else {\n if (value === true) {\n value = name;\n }\n el.setAttribute(name, value);\n }\n}\n\nexport function el(elementName: string, attributes?: BasicAttributes | Child | Child[], children?: Child | Child[]): Element {\n return elNS(HTML_NS, elementName, attributes, children);\n}\n\nexport function elNS(ns: string, elementName: string, attributes?: BasicAttributes | Child | Child[], children?: Child | Child[]): Element {\n if (attributes && isChildren(attributes)) {\n children = attributes;\n attributes = undefined;\n }\n\n const e = document.createElementNS(ns, elementName);\n\n if (attributes) {\n for (let [name, value] of Object.entries(attributes)) {\n if (typeof value === \"object\") {\n // Only className should ever be an object; be careful\n // here anyway and ignore object-valued non-className attributes.\n value = (value !== null && name === \"className\") ? classNames(value, undefined) : false;\n }\n setAttribute(e, name, value);\n }\n }\n\n if (children) {\n if (!Array.isArray(children)) {\n children = [children];\n }\n for (let c of children) {\n if (typeof c === \"string\") {\n c = text(c);\n }\n e.appendChild(c);\n }\n }\n return e;\n}\n\nexport function text(str: string): Text {\n return document.createTextNode(str);\n}\n\nexport const HTML_NS: string = \"http://www.w3.org/1999/xhtml\";\nexport const SVG_NS: string = \"http://www.w3.org/2000/svg\";\n\nexport const TAG_NAMES = {\n [HTML_NS]: [\n \"br\", \"a\", \"ol\", \"ul\", \"li\", \"div\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\n \"p\", \"strong\", \"em\", \"span\", \"img\", \"section\", \"header\", \"main\", \"footer\", \"dialog\",\n \"article\", \"aside\", \"del\", \"blockquote\", \"details\", \"summary\",\n \"table\", \"thead\", \"tbody\", \"tr\", \"th\", \"td\", \"hr\",\n \"pre\", \"code\", \"button\", \"time\", \"input\", \"textarea\", \"select\", \"option\", \"optgroup\", \"label\", \"form\",\n \"progress\", \"output\", \"video\", \"style\"],\n [SVG_NS]: [\"svg\", \"g\", \"path\", \"circle\", \"ellipse\", \"rect\", \"use\"]\n} as const;\n\nexport const tag: { [tagName in typeof TAG_NAMES[string][number]]: (attributes?: BasicAttributes | Child | Child[], children?: Child | Child[]) => Element } = {} as any;\n\nfor (const [ns, tags] of Object.entries(TAG_NAMES)) {\n for (const tagName of tags) {\n tag[tagName] = function(attributes, children) {\n return elNS(ns, tagName, attributes, children);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {IView, IMountArgs, ViewNode} from \"./types\";\nimport {tag} from \"./html\";\n\nexport function mountView(view: IView, mountArgs?: IMountArgs): ViewNode {\n let node;\n try {\n node = view.mount(mountArgs);\n } catch (err) {\n // Log it to the console so it's easy to reference\n console.error(err);\n // Then render our error boundary to the DOM\n node = errorToDOM(err);\n }\n return node;\n}\n\nexport function errorToDOM(error: Error): Element {\n const stack = new Error().stack;\n let callee: string | null = null;\n if (stack) {\n callee = stack.split(\"\\n\")[1];\n }\n return tag.div([\n tag.h2(\"Something went wrong…\"),\n tag.h3(error.message),\n tag.p(`This occurred while running ${callee}.`),\n tag.pre(error.stack),\n ]);\n}\n\nexport function insertAt(parentNode: Element, idx: number, childNode: Node): void {\n const isLast = idx === parentNode.childElementCount;\n if (isLast) {\n parentNode.appendChild(childNode);\n } else {\n const nextDomNode = parentNode.children[idx];\n parentNode.insertBefore(childNode, nextDomNode);\n }\n}\n\nexport function removeChildren(parentNode: Element): void {\n parentNode.innerHTML = '';\n}\n\nexport function disableTargetCallback(callback: (evt: Event) => Promise): (evt: Event) => Promise {\n return async (evt: Event) => {\n (evt.target as HTMLElement)?.setAttribute(\"disabled\", \"disabled\");\n await callback(evt);\n (evt.target as HTMLElement)?.removeAttribute(\"disabled\");\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {el} from \"./html\";\nimport {mountView, insertAt} from \"./utils\";\nimport {SubscriptionHandle} from \"../../../../observable/BaseObservable\";\nimport {BaseObservableList as ObservableList, IListObserver} from \"../../../../observable/list/BaseObservableList\";\nimport {IView, IMountArgs} from \"./types\";\n\nexport interface IOptions {\n list: ObservableList,\n onItemClick?: (childView: V, evt: UIEvent) => void,\n className?: string,\n tagName?: string,\n parentProvidesUpdates?: boolean\n}\n\nexport class ListView implements IView, IListObserver {\n\n private _onItemClick?: (childView: V, evt: UIEvent) => void;\n private _className?: string;\n private _tagName: string;\n private _root?: Element;\n protected _subscription?: SubscriptionHandle;\n protected _childCreator: (value: T) => V;\n protected _mountArgs: IMountArgs;\n protected _list: ObservableList;\n protected _childInstances?: V[];\n\n constructor(\n {list, onItemClick, className, tagName = \"ul\", parentProvidesUpdates = true}: IOptions, \n childCreator: (value: T) => V\n ) {\n this._onItemClick = onItemClick;\n this._list = list;\n this._className = className;\n this._tagName = tagName;\n this._root = undefined;\n this._subscription = undefined;\n this._childCreator = childCreator;\n this._childInstances = undefined;\n this._mountArgs = {parentProvidesUpdates};\n }\n\n root(): Element | undefined {\n // won't be undefined when called between mount and unmount\n return this._root;\n }\n\n update(attributes: IOptions) {\n if (attributes.list) {\n if (this._subscription) {\n this._unloadList();\n while (this._root!.lastChild) {\n this._root!.lastChild.remove();\n }\n }\n this._list = attributes.list;\n this.loadList();\n }\n }\n\n mount(): Element {\n const attr: {[name: string]: any} = {};\n if (this._className) {\n attr.className = this._className;\n }\n const root = this._root = el(this._tagName, attr);\n this.loadList();\n if (this._onItemClick) {\n root.addEventListener(\"click\", this);\n }\n return root;\n }\n\n handleEvent(evt: Event) {\n if (evt.type === \"click\") {\n this._handleClick(evt as UIEvent);\n }\n }\n\n unmount(): void {\n if (this._list) {\n this._unloadList();\n }\n }\n\n private _handleClick(event: UIEvent) {\n if (event.target === this._root || !this._onItemClick) {\n return;\n }\n let childNode = event.target as Element;\n while (childNode.parentNode !== this._root) {\n childNode = childNode.parentNode as Element;\n }\n const index = Array.prototype.indexOf.call(this._root!.childNodes, childNode);\n const childView = this._childInstances![index];\n if (childView) {\n this._onItemClick(childView, event);\n }\n }\n\n private _unloadList() {\n this._subscription = this._subscription!();\n for (let child of this._childInstances!) {\n child.unmount();\n }\n this._childInstances = undefined;\n }\n\n protected loadList() {\n if (!this._list) {\n return;\n }\n this._subscription = this._list.subscribe(this);\n this._childInstances = [];\n const fragment = document.createDocumentFragment();\n for (let item of this._list) {\n const child = this._childCreator(item);\n this._childInstances!.push(child);\n fragment.appendChild(mountView(child, this._mountArgs));\n }\n this._root!.appendChild(fragment);\n }\n\n onReset() {\n for (const child of this._childInstances!) {\n child.root()!.remove();\n child.unmount();\n }\n this._childInstances!.length = 0;\n }\n\n onAdd(idx: number, value: T) {\n this.addChild(idx, value);\n }\n\n onRemove(idx: number, value: T) {\n this.removeChild(idx);\n }\n\n onMove(fromIdx: number, toIdx: number, value: T) {\n this.moveChild(fromIdx, toIdx);\n }\n\n onUpdate(i: number, value: T, params: any) {\n this.updateChild(i, value, params);\n }\n\n protected addChild(childIdx: number, value: T) {\n const child = this._childCreator(value);\n this._childInstances!.splice(childIdx, 0, child);\n insertAt(this._root!, childIdx, mountView(child, this._mountArgs));\n }\n\n protected removeChild(childIdx: number) {\n const [child] = this._childInstances!.splice(childIdx, 1);\n child.root()!.remove();\n child.unmount();\n }\n\n protected moveChild(fromChildIdx: number, toChildIdx: number) {\n const [child] = this._childInstances!.splice(fromChildIdx, 1);\n this._childInstances!.splice(toChildIdx, 0, child);\n child.root()!.remove();\n insertAt(this._root!, toChildIdx, child.root()! as Element);\n }\n\n protected updateChild(childIdx: number, value: T, params: any) {\n if (this._childInstances) {\n const instance = this._childInstances![childIdx];\n instance && instance.update(value, params);\n }\n }\n\n // TODO: is this the list or view index? \n protected recreateItem(index: number, value: T) {\n if (this._childInstances) {\n const child = this._childCreator(value);\n if (!child) {\n this.onRemove(index, value);\n } else {\n const [oldChild] = this._childInstances!.splice(index, 1, child);\n this._root!.replaceChild(child.mount(this._mountArgs), oldChild.root()!);\n oldChild.unmount();\n }\n }\n }\n\n public getChildInstanceByIndex(idx: number): V | undefined {\n return this._childInstances?.[idx];\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\nCopyright 2021 Daniel Fedorin \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {IMountArgs, ViewNode, IView} from \"./types\";\n\nexport interface IObservableValue {\n on?(event: \"change\", handler: (props?: string[]) => void): void;\n off?(event: \"change\", handler: (props?: string[]) => void): void;\n}\n\nexport abstract class BaseUpdateView implements IView {\n protected _value: T\n protected _boundUpdateFromValue: ((props?: string[]) => void) | null\n\n abstract mount(args?: IMountArgs): ViewNode;\n abstract root(): ViewNode | undefined;\n abstract update(...any);\n\n constructor(value :T) {\n this._value = value;\n // TODO: can avoid this if we adopt the handleEvent pattern in our EventListener\n this._boundUpdateFromValue = null;\n }\n\n subscribeOnMount(options?: IMountArgs): void {\n const parentProvidesUpdates = options && options.parentProvidesUpdates;\n if (!parentProvidesUpdates) {\n this._subscribe();\n }\n }\n\n unmount(): void {\n this._unsubscribe();\n }\n\n get value(): T {\n return this._value;\n }\n\n _updateFromValue(changedProps?: string[]) {\n this.update(this._value, changedProps);\n }\n\n _subscribe(): void {\n if (typeof this._value?.on === \"function\") {\n this._boundUpdateFromValue = this._updateFromValue.bind(this) as (props?: string[]) => void;\n this._value.on(\"change\", this._boundUpdateFromValue);\n }\n }\n\n _unsubscribe(): void {\n if (this._boundUpdateFromValue) {\n if (typeof this._value.off === \"function\") {\n this._value.off(\"change\", this._boundUpdateFromValue);\n }\n this._boundUpdateFromValue = null;\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 Daniel Fedorin \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { setAttribute, text, isChildren, classNames, TAG_NAMES, HTML_NS, ClassNames, Child as NonBoundChild} from \"./html\";\nimport {mountView} from \"./utils\";\nimport {BaseUpdateView, IObservableValue} from \"./BaseUpdateView\";\nimport {IMountArgs, ViewNode, IView} from \"./types\";\n\nfunction objHasFns(obj: ClassNames): obj is { [className: string]: boolean } {\n for(const value of Object.values(obj)) {\n if (typeof value === \"function\") {\n return true;\n }\n }\n return false;\n}\n\nexport type RenderFn = (t: Builder, vm: T) => ViewNode;\ntype TextBinding = (T) => string | number | boolean | undefined | null;\ntype Child = NonBoundChild | TextBinding;\ntype Children = Child | Child[];\ntype EventHandler = ((event: Event) => void);\ntype AttributeStaticValue = string | boolean;\ntype AttributeBinding = (value: T) => AttributeStaticValue;\nexport type AttrValue = AttributeStaticValue | AttributeBinding | EventHandler | ClassNames;\nexport type Attributes = { [attribute: string]: AttrValue };\ntype ElementFn = (attributes?: Attributes | Children, children?: Children) => Element;\nexport type Builder = TemplateBuilder & { [tagName in typeof TAG_NAMES[string][number]]: ElementFn };\n\n/**\n Bindable template. Renders once, and allows bindings for given nodes. If you need\n to change the structure on a condition, use a subtemplate (if)\n\n supports\n - event handlers (attribute fn value with name that starts with on)\n - one way binding of attributes (other attribute fn value)\n - one way binding of text values (child fn value)\n - refs to get dom nodes\n - className binding returning object with className => enabled map\n - add subviews inside the template\n*/\n// TODO: should we rename this to BoundView or something? As opposed to StaticView ...\nexport abstract class TemplateView extends BaseUpdateView {\n private _eventListeners?: { node: Element, name: string, fn: EventHandler, useCapture: boolean }[] = undefined;\n private _bindings?: (() => void)[] = undefined;\n private _root?: ViewNode = undefined;\n // public because used by TemplateBuilder\n _subViews?: IView[] = undefined;\n\n _attach(): void {\n if (this._eventListeners) {\n for (let {node, name, fn, useCapture} of this._eventListeners) {\n node.addEventListener(name, fn, useCapture);\n }\n }\n }\n\n _detach(): void {\n if (this._eventListeners) {\n for (let {node, name, fn, useCapture} of this._eventListeners) {\n node.removeEventListener(name, fn, useCapture);\n }\n }\n }\n\n abstract render(t: Builder, value: T): ViewNode;\n\n mount(options?: IMountArgs): ViewNode {\n const builder = new TemplateBuilder(this) as Builder;\n try {\n this._root = this.render(builder, this._value);\n } finally {\n builder.close();\n }\n // takes care of update being called when needed\n this.subscribeOnMount(options);\n this._attach();\n return this._root!;\n }\n\n unmount(): void {\n this._detach();\n super.unmount();\n if (this._subViews) {\n for (const v of this._subViews) {\n v.unmount();\n }\n }\n }\n\n root(): ViewNode | undefined {\n return this._root;\n }\n\n update(value: T, props?: string[]): void {\n this._value = value;\n if (this._bindings) {\n for (const binding of this._bindings) {\n binding();\n }\n }\n }\n\n _addEventListener(node: Element, name: string, fn: (event: Event) => void, useCapture: boolean = false): void {\n if (!this._eventListeners) {\n this._eventListeners = [];\n }\n this._eventListeners.push({node, name, fn, useCapture});\n }\n\n _addBinding(bindingFn: () => void): void {\n if (!this._bindings) {\n this._bindings = [];\n }\n this._bindings.push(bindingFn);\n }\n\n addSubView(view: IView): void {\n if (!this._subViews) {\n this._subViews = [];\n }\n this._subViews.push(view);\n }\n\n removeSubView(view: IView): void {\n if (!this._subViews) { return; }\n const idx = this._subViews.indexOf(view);\n if (idx !== -1) {\n this._subViews.splice(idx, 1);\n }\n }\n\n updateSubViews(value: IObservableValue, props: string[]) {\n if (this._subViews) {\n for (const v of this._subViews) {\n v.update(value, props);\n }\n }\n }\n}\n\n// what is passed to render\nexport class TemplateBuilder {\n private _templateView: TemplateView;\n private _closed: boolean = false;\n\n constructor(templateView: TemplateView) {\n this._templateView = templateView;\n }\n\n close(): void {\n this._closed = true;\n }\n\n _addBinding(fn: () => void): void {\n if (this._closed) {\n console.trace(\"Adding a binding after render will likely cause memory leaks\");\n }\n this._templateView._addBinding(fn);\n }\n\n get _value(): T {\n return this._templateView.value;\n }\n\n addEventListener(node: Element, name: string, fn: (event: Event) => void, useCapture: boolean = false): void {\n this._templateView._addEventListener(node, name, fn, useCapture);\n }\n\n _addAttributeBinding(node: Element, name: string, fn: AttributeBinding): void {\n let prevValue: string | boolean | undefined = undefined;\n const binding = () => {\n const newValue = fn(this._value);\n if (prevValue !== newValue) {\n prevValue = newValue;\n setAttribute(node, name, newValue);\n }\n };\n this._addBinding(binding);\n binding();\n }\n\n _addClassNamesBinding(node: Element, obj: ClassNames): void {\n this._addAttributeBinding(node, \"className\", value => classNames(obj, value));\n }\n\n _addTextBinding(fn: (value: T) => ReturnType>): Text {\n const initialValue = fn(this._value)+\"\";\n const node = text(initialValue);\n let prevValue = initialValue;\n const binding = () => {\n const newValue = fn(this._value)+\"\";\n if (prevValue !== newValue) {\n prevValue = newValue;\n node.textContent = newValue;\n }\n };\n\n this._addBinding(binding);\n return node;\n }\n\n _isEventHandler(key: string, value: AttrValue): value is (event: Event) => void {\n // This isn't actually safe, but it's incorrect to feed event handlers to\n // non-on* attributes.\n return key.startsWith(\"on\") && key.length > 2 && typeof value === \"function\";\n }\n\n _setNodeAttributes(node: Element, attributes: Attributes): void {\n for(let [key, value] of Object.entries(attributes)) {\n // binding for className as object of className => enabled\n if (typeof value === \"object\") {\n if (key !== \"className\" || value === null) {\n // Ignore non-className objects.\n continue;\n }\n if (objHasFns(value)) {\n this._addClassNamesBinding(node, value);\n } else {\n setAttribute(node, key, classNames(value, this._value));\n }\n } else if (this._isEventHandler(key, value)) {\n const eventName = key.substr(2, 1).toLowerCase() + key.substr(3);\n const handler = value;\n this._templateView._addEventListener(node, eventName, handler);\n } else if (typeof value === \"function\") {\n this._addAttributeBinding(node, key, value);\n } else {\n setAttribute(node, key, value);\n }\n }\n }\n\n _setNodeChildren(node: Element, children: Children): void{\n if (!Array.isArray(children)) {\n children = [children];\n }\n for (let child of children) {\n if (typeof child === \"function\") {\n child = this._addTextBinding(child);\n } else if (typeof child === \"string\") {\n // not a DOM node, turn into text\n child = text(child);\n }\n node.appendChild(child);\n }\n }\n \n _addReplaceNodeBinding(fn: (value: T) => R, renderNode: (old: ViewNode | null) => ViewNode): ViewNode {\n let prevValue = fn(this._value);\n let node = renderNode(null);\n\n const binding = () => {\n const newValue = fn(this._value);\n if (prevValue !== newValue) {\n prevValue = newValue;\n const newNode = renderNode(node);\n if (node.parentNode) {\n node.parentNode.replaceChild(newNode, node);\n }\n node = newNode;\n }\n };\n this._addBinding(binding);\n return node;\n }\n\n el(name: string, attributes?: Attributes | Children, children?: Children): ViewNode {\n return this.elNS(HTML_NS, name, attributes, children);\n }\n\n elNS(ns: string, name: string, attributesOrChildren?: Attributes | Children, children?: Children): ViewNode {\n let attributes: Attributes | undefined;\n if (attributesOrChildren) {\n if (isChildren(attributesOrChildren)) {\n children = attributesOrChildren as Children;\n } else {\n attributes = attributesOrChildren as Attributes;\n }\n }\n\n const node = document.createElementNS(ns, name);\n \n if (attributes) {\n this._setNodeAttributes(node, attributes);\n }\n if (children) {\n this._setNodeChildren(node, children);\n }\n\n return node;\n }\n\n // this inserts a view, and is not a view factory for `if`, so returns the root element to insert in the template\n // you should not call t.view() and not use the result (e.g. attach the result to the template DOM tree).\n view(view: IView, mountOptions?: IMountArgs): ViewNode {\n this._templateView.addSubView(view);\n return mountView(view, mountOptions);\n }\n\n // map a value to a view, every time the value changes\n mapView(mapFn: (value: T) => R, viewCreator: (mapped: R) => IView | null): ViewNode {\n return this._addReplaceNodeBinding(mapFn, (prevNode) => {\n if (prevNode && prevNode.nodeType !== Node.COMMENT_NODE) {\n const subViews = this._templateView._subViews;\n if (subViews) {\n const viewIdx = subViews.findIndex(v => v.root() === prevNode);\n if (viewIdx !== -1) {\n const [view] = subViews.splice(viewIdx, 1);\n view.unmount();\n }\n }\n }\n const view = viewCreator(mapFn(this._value));\n if (view) {\n return this.view(view);\n } else {\n return document.createComment(\"node binding placeholder\");\n }\n });\n }\n\n // Special case of mapView for a TemplateView.\n // Always creates a TemplateView, if this is optional depending\n // on mappedValue, use `if` or `mapView`\n map(mapFn: (value: T) => R, renderFn: (mapped: R, t: Builder, vm: T) => ViewNode | undefined): ViewNode {\n return this.mapView(mapFn, mappedValue => {\n return new InlineTemplateView(this._value, (t, vm) => {\n const rootNode = renderFn(mappedValue, t, vm);\n if (!rootNode) {\n // TODO: this will confuse mapView which assumes that\n // a comment node means there is no view to clean up\n return document.createComment(\"map placeholder\");\n }\n return rootNode;\n });\n });\n }\n\n ifView(predicate: (value: T) => boolean, viewCreator: (value: T) => IView): ViewNode {\n return this.mapView(\n value => !!predicate(value),\n enabled => enabled ? viewCreator(this._value) : null\n );\n }\n\n // creates a conditional subtemplate\n // use mapView if you need to map to a different view class\n if(predicate: (value: T) => boolean, renderFn: (t: Builder, vm: T) => ViewNode) {\n return this.ifView(predicate, vm => new InlineTemplateView(vm, renderFn));\n }\n\n /** You probably are looking for something else, like map or mapView.\n This is an escape hatch that allows you to do manual DOM manipulations\n as a reaction to a binding change.\n This should only be used if the side-effect won't add any bindings,\n event handlers, ...\n You should not call the TemplateBuilder (e.g. `t.xxx()`) at all from the side effect,\n instead use tags from html.ts to help you construct any DOM you need. */\n mapSideEffect(mapFn: (value: T) => R, sideEffect: (newV: R, oldV: R | undefined, value: T) => void) {\n let prevValue = mapFn(this._value);\n const binding = () => {\n const newValue = mapFn(this._value);\n if (prevValue !== newValue) {\n sideEffect(newValue, prevValue, this._value);\n prevValue = newValue;\n }\n };\n this._addBinding(binding);\n sideEffect(prevValue, undefined, this._value);\n }\n}\n\n\nfor (const [ns, tags] of Object.entries(TAG_NAMES)) {\n for (const tag of tags) {\n TemplateBuilder.prototype[tag] = function(attributes, children) {\n return this.elNS(ns, tag, attributes, children);\n };\n }\n}\n\nexport class InlineTemplateView extends TemplateView {\n private _render: RenderFn;\n\n constructor(value: T, render: RenderFn) {\n super(value);\n this._render = render;\n }\n\n override render(t: Builder, value: T): ViewNode {\n return this._render(t, value);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {tag, text, classNames, setAttribute} from \"./general/html\";\n/**\n * @param {Object} vm view model with {avatarUrl, avatarColorNumber, avatarTitle, avatarLetter}\n * @param {Number} size\n * @return {Element}\n */\nexport function renderStaticAvatar(vm, size, extraClasses = undefined) {\n const hasAvatar = !!vm.avatarUrl(size);\n let avatarClasses = classNames({\n avatar: true,\n [`size-${size}`]: true,\n [`usercolor${vm.avatarColorNumber}`]: !hasAvatar\n });\n if (extraClasses) {\n avatarClasses += ` ${extraClasses}`;\n }\n const avatarContent = hasAvatar ? renderImg(vm, size) : text(vm.avatarLetter);\n const avatar = tag.div({\n className: avatarClasses,\n title: vm.avatarTitle,\n \"data-testid\": \"avatar\",\n }, [avatarContent]);\n if (hasAvatar) {\n setAttribute(avatar, \"data-avatar-letter\", vm.avatarLetter);\n setAttribute(avatar, \"data-avatar-color\", vm.avatarColorNumber);\n }\n return avatar;\n}\n\nexport function renderImg(vm, size) {\n const sizeStr = size.toString();\n return tag.img({src: vm.avatarUrl(size), width: sizeStr, height: sizeStr, title: vm.avatarTitle});\n}\n\nfunction isAvatarEvent(e) {\n const element = e.target;\n const parent = element.parentElement;\n return element.tagName === \"IMG\" && parent.classList.contains(\"avatar\");\n}\n\nexport function handleAvatarError(e) {\n if (!isAvatarEvent(e)) { return; }\n const parent = e.target.parentElement;\n const avatarColorNumber = parent.getAttribute(\"data-avatar-color\");\n parent.classList.add(`usercolor${avatarColorNumber}`);\n const avatarLetter = parent.getAttribute(\"data-avatar-letter\");\n parent.textContent = avatarLetter;\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseUpdateView} from \"./general/BaseUpdateView\";\nimport {renderStaticAvatar, renderImg} from \"./avatar\";\n\n/*\noptimization to not use a sub view when changing between img and text\nbecause there can be many many instances of this view\n*/\n\nexport class AvatarView extends BaseUpdateView {\n /**\n * @param {ViewModel} value view model with {avatarUrl, avatarColorNumber, avatarTitle, avatarLetter}\n * @param {Number} size\n */\n constructor(value, size) {\n super(value);\n this._root = null;\n this._avatarUrl = null;\n this._avatarTitle = null;\n this._avatarLetter = null;\n this._size = size;\n }\n\n _avatarUrlChanged() {\n if (this.value.avatarUrl(this._size) !== this._avatarUrl) {\n this._avatarUrl = this.value.avatarUrl(this._size);\n return true;\n }\n return false;\n }\n\n _avatarTitleChanged() {\n if (this.value.avatarTitle !== this._avatarTitle) {\n this._avatarTitle = this.value.avatarTitle;\n return true;\n }\n return false;\n }\n\n _avatarLetterChanged() {\n if (this.value.avatarLetter !== this._avatarLetter) {\n this._avatarLetter = this.value.avatarLetter;\n return true;\n }\n return false;\n }\n\n mount(options) {\n this._avatarUrlChanged();\n this._avatarLetterChanged();\n this._avatarTitleChanged();\n this._root = renderStaticAvatar(this.value, this._size);\n // takes care of update being called when needed\n this.subscribeOnMount(options);\n return this._root;\n }\n\n root() {\n return this._root;\n }\n\n update(vm) {\n // important to always call _...changed for every prop \n if (this._avatarUrlChanged()) {\n // avatarColorNumber won't change, it's based on room/user id\n const bgColorClass = `usercolor${vm.avatarColorNumber}`;\n if (vm.avatarUrl(this._size)) {\n this._root.replaceChild(renderImg(vm, this._size), this._root.firstChild);\n this._root.classList.remove(bgColorClass);\n } else {\n this._root.textContent = vm.avatarLetter;\n this._root.classList.add(bgColorClass);\n }\n }\n const hasAvatar = !!vm.avatarUrl(this._size);\n if (this._avatarTitleChanged() && hasAvatar) {\n const element = this._root.firstChild;\n if (element.tagName === \"IMG\") {\n element.setAttribute(\"title\", vm.avatarTitle);\n }\n }\n if (this._avatarLetterChanged() && !hasAvatar) {\n this._root.textContent = vm.avatarLetter;\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nlet container;\n\nexport function spinner(t, extraClasses = undefined) {\n if (container === undefined) {\n container = document.querySelector(\".hydrogen\");\n }\n const classes = Object.assign({\"spinner\": true}, extraClasses);\n if (container?.classList.contains(\"legacy\")) {\n return t.div({className: classes}, [\n t.div(),\n t.div(),\n t.div(),\n t.div(),\n ]);\n } else {\n return t.svg({className: classes, viewBox:\"0 0 100 100\"}, \n t.circle({cx:\"50%\", cy:\"50%\", r:\"45%\", pathLength:\"100\"})\n );\n }\n}\n\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {AvatarView} from \"../../AvatarView.js\";\nimport {spinner} from \"../../common.js\";\n\nexport class RoomTileView extends TemplateView {\n render(t, vm) {\n const classes = {\n \"active\": vm => vm.isOpen,\n \"hidden\": vm => vm.hidden\n };\n return t.li({\"className\": classes}, [\n t.a({href: vm.url}, [\n t.view(new AvatarView(vm, 32), {parentProvidesUpdates: true}),\n t.div({className: \"description\"}, [\n t.div({className: {\"name\": true, unread: vm => vm.isUnread}}, vm => vm.name),\n t.map(vm => vm.busy, busy => {\n if (busy) {\n return spinner(t);\n } else {\n return t.div({\n className: {\n badge: true,\n highlighted: vm => vm.isHighlighted,\n hidden: vm => !vm.badgeCount\n }\n }, vm => vm.badgeCount);\n }\n })\n ])\n ])\n ]);\n }\n\n update(value, props) {\n super.update(value);\n // update the AvatarView as we told it to not subscribe itself with parentProvidesUpdates\n this.updateSubViews(value, props);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"./TemplateView\";\n\nexport class Menu extends TemplateView {\n static option(label, callback) {\n return new MenuOption(label, callback);\n }\n\n constructor(options) {\n super();\n this._options = options;\n }\n\n render(t) {\n return t.ul({className: \"menu\", role: \"menu\"}, this._options.map(o => o.toDOM(t)));\n }\n}\n\nclass MenuOption {\n constructor(label, callback) {\n this.label = label;\n this.callback = callback;\n this.icon = null;\n this.destructive = false;\n }\n\n setIcon(className) {\n this.icon = className;\n return this;\n }\n\n setDestructive() {\n this.destructive = true;\n return this;\n }\n\n toDOM(t) {\n const className = {\n destructive: this.destructive,\n };\n if (this.icon) {\n className.icon = true;\n className[this.icon] = true;\n }\n return t.li({\n className,\n }, t.button({className:\"menu-item\", onClick: this.callback}, this.label));\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {tag} from \"./html\";\n\nexport class Popup {\n constructor(view, closeCallback = null) {\n this._view = view;\n this._target = null;\n this._arrangement = null;\n this._scroller = null;\n this._fakeRoot = null;\n this._trackingTemplateView = null;\n this._closeCallback = closeCallback;\n }\n\n _getPopupContainer() {\n const appContainer = this._target.closest(\".hydrogen\");\n let popupContainer = appContainer.querySelector(\".popupContainer\");\n if (!popupContainer) {\n popupContainer = tag.div({className: \"popupContainer\"});\n appContainer.appendChild(popupContainer);\n }\n return popupContainer;\n }\n\n trackInTemplateView(templateView) {\n this._trackingTemplateView = templateView;\n this._trackingTemplateView.addSubView(this);\n }\n\n showRelativeTo(target, verticalPadding = 0) {\n this._target = target;\n this._verticalPadding = verticalPadding;\n this._scroller = findScrollParent(this._target);\n this._view.mount();\n this._getPopupContainer().appendChild(this._popup);\n this._position();\n if (this._scroller) {\n document.body.addEventListener(\"scroll\", this, true);\n }\n setTimeout(() => {\n document.body.addEventListener(\"click\", this, false);\n }, 10);\n }\n\n get isOpen() {\n return !!this._view;\n }\n\n close() {\n if (this._view) {\n this._view.unmount();\n this._trackingTemplateView.removeSubView(this);\n if (this._scroller) {\n document.body.removeEventListener(\"scroll\", this, true);\n }\n document.body.removeEventListener(\"click\", this, false);\n this._popup.remove();\n this._view = null;\n if (this._closeCallback) {\n this._closeCallback();\n }\n }\n }\n\n get _popup() {\n return this._view.root();\n }\n\n handleEvent(evt) {\n if (evt.type === \"scroll\") {\n if(!this._position()) {\n this.close();\n }\n } else if (evt.type === \"click\") {\n this._onClick(evt);\n }\n }\n\n _onClick() {\n this.close();\n }\n\n _position() {\n const targetPosition = this._target.getBoundingClientRect();\n const popupWidth = this._popup.clientWidth;\n const popupHeight = this._popup.clientHeight;\n const viewport = (this._scroller ? this._scroller : document.documentElement).getBoundingClientRect();\n\n if (\n targetPosition.top > viewport.bottom ||\n targetPosition.left > viewport.right ||\n targetPosition.bottom < viewport.top ||\n targetPosition.right < viewport.left\n ) {\n return false;\n }\n if (viewport.bottom >= targetPosition.bottom + popupHeight) {\n // show below\n this._popup.style.top = `${targetPosition.bottom + this._verticalPadding}px`;\n } else if (viewport.top <= targetPosition.top - popupHeight) {\n // show top\n this._popup.style.top = `${targetPosition.top - popupHeight - this._verticalPadding}px`;\n } else {\n return false;\n }\n if (viewport.right >= targetPosition.right + popupWidth) {\n // show right\n this._popup.style.left = `${targetPosition.left}px`;\n } else if (viewport.left <= targetPosition.left - popupWidth) {\n // show left\n this._popup.style.left = `${targetPosition.right - popupWidth}px`;\n } else {\n return false;\n }\n return true;\n }\n\n /* fake IView api, so it can be tracked by a template view as a subview */\n root() {\n return this._fakeRoot;\n }\n\n mount() {\n this._fakeRoot = document.createComment(\"popup\");\n return this._fakeRoot;\n }\n\n unmount() {\n this.close();\n }\n\n update() {}\n}\n\nfunction findScrollParent(el) {\n let parent = el;\n do {\n parent = parent.parentElement;\n if (parent.scrollHeight > parent.clientHeight) {\n // double check that overflow would allow a scrollbar\n // because some elements, like a button with negative margin to increate the click target\n // can cause the scrollHeight to be larger than the clientHeight in the parent\n // see button.link class\n const style = window.getComputedStyle(parent);\n const overflowY = style.getPropertyValue(\"overflow-y\");\n if (overflowY === \"auto\" || overflowY === \"scroll\") {\n return parent;\n }\n }\n } while (parent !== document.body);\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ListView} from \"../../general/ListView\";\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {RoomTileView} from \"./RoomTileView.js\";\nimport {Menu} from \"../../general/Menu.js\";\nimport {Popup} from \"../../general/Popup.js\";\n\nclass FilterField extends TemplateView {\n render(t, options) {\n const clear = () => {\n filterInput.value = \"\";\n filterInput.blur();\n clearButton.blur();\n options.clear();\n };\n const filterInput = t.input({\n type: \"text\",\n placeholder: options?.label,\n \"aria-label\": options?.label,\n autocomplete: options?.autocomplete,\n enterkeyhint: 'search',\n name: options?.name,\n onInput: event => options.set(event.target.value),\n onKeydown: event => {\n if (event.key === \"Escape\" || event.key === \"Esc\") {\n clear();\n }\n },\n onFocus: () => filterInput.select()\n });\n const clearButton = t.button({\n onClick: clear,\n title: options.i18n`Clear`,\n \"aria-label\": options.i18n`Clear`\n });\n return t.div({className: \"FilterField\"}, [filterInput, clearButton]);\n }\n}\n\nexport class LeftPanelView extends TemplateView {\n constructor(vm) {\n super(vm);\n this._createMenuPopup = null;\n }\n\n render(t, vm) {\n const gridButtonLabel = vm => {\n return vm.gridEnabled ?\n vm.i18n`Show single room` :\n vm.i18n`Enable grid layout`;\n };\n const roomList = t.view(new ListView(\n {\n className: \"RoomList\",\n list: vm.tileViewModels,\n },\n tileVM => new RoomTileView(tileVM)\n ));\n const utilitiesRow = t.div({className: \"utilities\"}, [\n t.a({className: \"button-utility close-session\", href: vm.closeUrl, \"aria-label\": vm.i18n`Back to account list`, title: vm.i18n`Back to account list`}),\n t.view(new FilterField({\n i18n: vm.i18n,\n label: vm.i18n`Filter rooms…`,\n name: \"room-filter\",\n autocomplete: true,\n set: query => {\n // scroll up if we just started filtering\n if (vm.setFilter(query)) {\n roomList.scrollTop = 0;\n }\n },\n clear: () => vm.clearFilter()\n })),\n t.button({\n onClick: () => vm.toggleGrid(),\n className: {\n \"button-utility\": true,\n grid: true,\n on: vm => vm.gridEnabled\n },\n title: gridButtonLabel,\n \"aria-label\": gridButtonLabel\n }),\n t.a({className: \"button-utility settings\", href: vm.settingsUrl, \"aria-label\": vm.i18n`Settings`, title: vm.i18n`Settings`}),\n t.button({\n className: \"button-utility create\",\n \"aria-label\": vm.i18n`Create room`,\n onClick: evt => this._toggleCreateMenu(evt)\n }),\n ]);\n\n return t.div({className: \"LeftPanel\"}, [\n utilitiesRow,\n roomList\n ]);\n }\n\n _toggleCreateMenu(evt) {\n if (this._createMenuPopup && this._createMenuPopup.isOpen) {\n this._createMenuPopup.close();\n } else {\n const vm = this.value;\n const options = [];\n options.push(Menu.option(vm.i18n`Create Room`, () => vm.showCreateRoomView()));\n options.push(Menu.option(vm.i18n`Join Room`, () => vm.showJoinRoomView()));\n this._createMenuPopup = new Popup(new Menu(options));\n this._createMenuPopup.trackInTemplateView(this);\n this._createMenuPopup.showRelativeTo(evt.target, 10);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ListView} from \"../../general/ListView\";\nimport {TemplateView, Builder} from \"../../general/TemplateView\";\nimport {IObservableValue} from \"../../general/BaseUpdateView\";\nimport {BaseObservableList as ObservableList} from \"../../../../../observable/list/BaseObservableList\";\nimport type {IView} from \"../../general/types\";\nimport type {ITile} from \"../../../../../domain/session/room/timeline/tiles/ITile\";\n\nexport interface TileView extends IView {\n readonly value: ITile;\n onClick(event: UIEvent);\n} \nexport type TileViewConstructor = new (\n tile: ITile,\n viewClassForTile: ViewClassForEntryFn,\n renderFlags?: { reply?: boolean, interactive?: boolean }\n) => TileView;\nexport type ViewClassForEntryFn = (tile: ITile) => TileViewConstructor;\n\n//import {TimelineViewModel} from \"../../../../../domain/session/room/timeline/TimelineViewModel.js\";\nexport interface TimelineViewModel extends IObservableValue {\n showJumpDown: boolean;\n tiles: ObservableList;\n setVisibleTileRange(start?: ITile, end?: ITile);\n}\n\nfunction bottom(node: HTMLElement): number {\n return node.offsetTop + node.clientHeight;\n}\n\nfunction findFirstNodeIndexAtOrBelow(tiles: HTMLElement, top: number, startIndex: number = (tiles.children.length - 1)): number {\n for (var i = startIndex; i >= 0; i--) {\n const node = tiles.children[i] as HTMLElement;\n if (node.offsetTop < top) {\n return i;\n }\n }\n // return first item if nothing matched before\n return 0;\n}\n\nexport class TimelineView extends TemplateView {\n\n private anchoredNode?: HTMLElement;\n private anchoredBottom: number = 0;\n private stickToBottom: boolean = true;\n private tilesView?: TilesListView;\n private resizeObserver?: ResizeObserver;\n\n constructor(vm: TimelineViewModel, private readonly viewClassForTile: ViewClassForEntryFn) {\n super(vm);\n }\n\n render(t: Builder, vm: TimelineViewModel) {\n // assume this view will be mounted in the parent DOM straight away\n requestAnimationFrame(() => {\n // do initial scroll positioning\n this.restoreScrollPosition();\n });\n this.tilesView = new TilesListView(vm.tiles, () => this.restoreScrollPosition(), this.viewClassForTile);\n const root = t.div({className: \"Timeline\"}, [\n t.div({\n className: \"Timeline_scroller bottom-aligned-scroll\",\n onScroll: () => this.onScroll()\n }, t.view(this.tilesView)),\n t.button({\n className: {\n \"Timeline_jumpDown\": true,\n hidden: vm => !vm.showJumpDown\n },\n title: \"Jump down\",\n onClick: () => this.jumpDown()\n })\n ]);\n\n if (typeof ResizeObserver === \"function\") {\n this.resizeObserver = new ResizeObserver(() => {\n this.restoreScrollPosition();\n });\n this.resizeObserver.observe(root);\n }\n\n return root;\n }\n\n private get scrollNode(): HTMLElement {\n return (this.root()! as HTMLElement).firstElementChild! as HTMLElement;\n }\n\n private get tilesNode(): HTMLElement {\n return this.tilesView!.root()! as HTMLElement;\n }\n\n private jumpDown() {\n const {scrollNode} = this;\n this.stickToBottom = true;\n scrollNode.scrollTop = scrollNode.scrollHeight;\n }\n\n public unmount() {\n super.unmount();\n if (this.resizeObserver) {\n this.resizeObserver.unobserve(this.root()! as Element);\n this.resizeObserver = undefined;\n }\n }\n\n private restoreScrollPosition() {\n const {scrollNode, tilesNode} = this;\n\n const missingTilesHeight = scrollNode.clientHeight - tilesNode.clientHeight;\n if (missingTilesHeight > 0) {\n tilesNode.style.setProperty(\"margin-top\", `${missingTilesHeight}px`);\n // we don't have enough tiles to fill the viewport, so set all as visible\n const len = this.value.tiles.length;\n this.updateVisibleRange(0, len - 1);\n } else {\n tilesNode.style.removeProperty(\"margin-top\");\n if (this.stickToBottom) {\n scrollNode.scrollTop = scrollNode.scrollHeight;\n } else if (this.anchoredNode) {\n const newAnchoredBottom = bottom(this.anchoredNode!);\n if (newAnchoredBottom !== this.anchoredBottom) {\n const bottomDiff = newAnchoredBottom - this.anchoredBottom;\n // scrollBy tends to create less scroll jumps than reassigning scrollTop as it does\n // not depend on reading scrollTop, which might be out of date as some platforms\n // run scrolling off the main thread.\n if (typeof scrollNode.scrollBy === \"function\") {\n scrollNode.scrollBy(0, bottomDiff);\n } else {\n scrollNode.scrollTop = scrollNode.scrollTop + bottomDiff;\n }\n this.anchoredBottom = newAnchoredBottom;\n }\n }\n // TODO: should we be updating the visible range here as well as the range might have changed even though\n // we restored the bottom tile\n }\n }\n\n private onScroll(): void {\n const {scrollNode, tilesNode} = this;\n const {scrollHeight, scrollTop, clientHeight} = scrollNode;\n\n let bottomNodeIndex;\n this.stickToBottom = Math.abs(scrollHeight - (scrollTop + clientHeight)) < 1;\n if (this.stickToBottom) {\n const len = this.value.tiles.length;\n bottomNodeIndex = len - 1;\n } else {\n const viewportBottom = scrollTop + clientHeight;\n const anchoredNodeIndex = findFirstNodeIndexAtOrBelow(tilesNode, viewportBottom);\n this.anchoredNode = tilesNode.childNodes[anchoredNodeIndex] as HTMLElement;\n this.anchoredBottom = bottom(this.anchoredNode!);\n bottomNodeIndex = anchoredNodeIndex;\n }\n let topNodeIndex = findFirstNodeIndexAtOrBelow(tilesNode, scrollTop, bottomNodeIndex);\n this.updateVisibleRange(topNodeIndex, bottomNodeIndex);\n }\n\n private updateVisibleRange(startIndex: number, endIndex: number) {\n // can be undefined, meaning the tiles collection is still empty\n const firstVisibleChild = this.tilesView!.getChildInstanceByIndex(startIndex);\n const lastVisibleChild = this.tilesView!.getChildInstanceByIndex(endIndex);\n this.value.setVisibleTileRange(firstVisibleChild?.value, lastVisibleChild?.value);\n }\n}\n\nclass TilesListView extends ListView {\n\n private onChanged: () => void;\n\n constructor(tiles: ObservableList, onChanged: () => void, private readonly viewClassForTile: ViewClassForEntryFn) {\n super({\n list: tiles,\n onItemClick: (tileView, evt) => tileView.onClick(evt),\n }, tile => {\n const TileView = viewClassForTile(tile);\n return new TileView(tile, viewClassForTile);\n });\n this.onChanged = onChanged;\n }\n\n onReset() {\n super.onReset();\n this.onChanged();\n }\n\n onUpdate(index: number, value: ITile, param: any) {\n if (param === \"shape\") {\n const ExpectedClass = this.viewClassForTile(value);\n const child = this.getChildInstanceByIndex(index);\n if (!ExpectedClass || !(child instanceof ExpectedClass)) {\n // shape was updated, so we need to recreate the tile view,\n // the shape parameter is set in EncryptedEventTile.updateEntry\n // (and perhaps elsewhere by the time you read this)\n super.recreateItem(index, value);\n return;\n }\n }\n super.onUpdate(index, value, param);\n this.onChanged();\n }\n\n onAdd(idx: number, value: ITile) {\n super.onAdd(idx, value);\n this.onChanged();\n }\n\n onRemove(idx: number, value: ITile) {\n super.onRemove(idx, value);\n this.onChanged();\n }\n\n onMove(fromIdx: number, toIdx: number, value: ITile) {\n super.onMove(fromIdx, toIdx, value);\n this.onChanged();\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {spinner} from \"../../common.js\";\n\nexport class TimelineLoadingView extends TemplateView {\n render(t, vm) {\n return t.div({className: \"TimelineLoadingView\"}, [\n spinner(t),\n t.div(vm.isEncrypted ? vm.i18n`Loading encrypted messages…` : vm.i18n`Loading messages…`)\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {Popup} from \"../../general/Popup.js\";\nimport {Menu} from \"../../general/Menu.js\";\n\nexport class MessageComposer extends TemplateView {\n constructor(viewModel, viewClassForTile) {\n super(viewModel);\n this._viewClassForTile = viewClassForTile;\n this._input = null;\n this._attachmentPopup = null;\n this._focusInput = null;\n this._rafResizeHandle = undefined;\n }\n\n render(t, vm) {\n this._input = t.textarea({\n onKeydown: e => this._onKeyDown(e),\n onInput: () => {\n vm.setInput(this._input.value);\n if (this._input.value) {\n this._adjustHeight();\n } else {\n this._clearHeight();\n }\n },\n placeholder: vm => vm.isEncrypted ? \"Send an encrypted message…\" : \"Send a message…\",\n rows: \"1\"\n });\n this._focusInput = () => this._input.focus();\n this.value.on(\"focus\", this._focusInput);\n const replyPreview = t.map(vm => vm.replyViewModel, (rvm, t) => {\n const TileView = rvm && this._viewClassForTile(rvm);\n if (!TileView) { return null; }\n return t.div({\n className: \"MessageComposer_replyPreview\"\n }, [\n t.span({ className: \"replying\" }, \"Replying\"),\n t.button({\n className: \"cancel\",\n onClick: () => this._clearReplyingTo()\n }, \"Close\"),\n t.view(new TileView(rvm, this._viewClassForTile, { interactive: false }, \"div\"))\n ]);\n });\n const input = t.div({className: \"MessageComposer_input\"}, [\n this._input,\n t.button({\n className: \"sendFile\",\n title: vm.i18n`Pick attachment`,\n onClick: evt => this._toggleAttachmentMenu(evt),\n }, vm.i18n`Send file`),\n t.button({\n className: \"send\",\n title: vm.i18n`Send`,\n onClick: () => this._trySend(),\n }, vm.i18n`Send`),\n ]);\n return t.div({ className: {\n MessageComposer: true,\n MessageComposer_canSend: vm => vm.canSend\n } }, [replyPreview, input]);\n }\n\n unmount() {\n if (this._focusInput) {\n this.value.off(\"focus\", this._focusInput);\n }\n super.unmount();\n }\n\n _clearReplyingTo() {\n this.value.clearReplyingTo();\n }\n\n async _trySend() {\n this._input.focus();\n // we clear the composer while enqueuing\n // and restore it when that didn't work somehow\n // to prevent the user from sending the message\n // every time they hit enter while it's still enqueuing.\n const {value} = this._input;\n const restoreValue = () => {\n this._input.value = value;\n this._adjustHeight();\n };\n this._input.value = \"\";\n this._clearHeight();\n try {\n if (!await this.value.sendMessage(value)) {\n restoreValue();\n }\n } catch (err) {\n restoreValue();\n console.error(err);\n }\n }\n\n _onKeyDown(event) {\n if (event.key === \"Enter\" && !event.shiftKey) {\n // don't insert newline into composer\n event.preventDefault();\n this._trySend();\n }\n }\n\n _toggleAttachmentMenu(evt) {\n if (this._attachmentPopup && this._attachmentPopup.isOpen) {\n this._attachmentPopup.close();\n } else {\n const vm = this.value;\n this._attachmentPopup = new Popup(new Menu([\n Menu.option(vm.i18n`Send video`, () => vm.sendVideo()).setIcon(\"video\"),\n Menu.option(vm.i18n`Send picture`, () => vm.sendPicture()).setIcon(\"picture\"),\n Menu.option(vm.i18n`Send file`, () => vm.sendFile()).setIcon(\"file\"),\n ]));\n this._attachmentPopup.trackInTemplateView(this);\n this._attachmentPopup.showRelativeTo(evt.target, 12);\n }\n }\n\n _adjustHeight() {\n if (this._rafResizeHandle) {\n return;\n }\n this._rafResizeHandle = window.requestAnimationFrame(() => {\n const scrollHeight = this._input.scrollHeight;\n this._input.style.height = `${scrollHeight}px`;\n this._rafResizeHandle = undefined;\n });\n }\n\n _clearHeight() {\n this._input.style.removeProperty(\"height\");\n }\n\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\n\nexport class DisabledComposerView extends TemplateView {\n render(t) {\n return t.div({className: \"DisabledComposerView\"}, t.h3(vm => vm.description));\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView, Builder} from \"./TemplateView\";\nimport { disableTargetCallback } from \"./utils\";\n\nimport type { ViewNode } from \"./types\";\nimport type {ErrorViewModel} from \"../../../../domain/ErrorViewModel\";\n\n\nexport class ErrorView extends TemplateView {\n constructor(vm: ErrorViewModel, private readonly options: {inline: boolean} = {inline: false}) {\n super(vm);\n }\n override render(t: Builder, vm: ErrorViewModel): ViewNode {\n const submitLogsButton = t.button({\n className: \"ErrorView_submit\",\n onClick: disableTargetCallback(async evt => {\n evt.stopPropagation();\n if (await vm.submitLogs()) {\n alert(\"Logs submitted!\");\n } else {\n alert(\"Could not submit logs\");\n }\n })\n }, \"Submit logs\");\n const closeButton = t.button({\n className: \"ErrorView_close\",\n onClick: evt => {\n evt.stopPropagation();\n vm.close();\n },\n title: \"Dismiss error\"\n });\n return t.div({\n className: {\n \"ErrorView\": true,\n \"ErrorView_inline\": this.options.inline,\n \"ErrorView_block\": !this.options.inline\n }}, [\n t.p({className: \"ErrorView_message\"}, vm.message),\n submitLogsButton,\n closeButton\n ]);\n }\n}\n\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView, Builder} from \"../../general/TemplateView\";\nimport {AvatarView} from \"../../AvatarView\";\nimport {ListView} from \"../../general/ListView\";\nimport {classNames} from \"../../general/html\";\nimport {Stream} from \"../../../../types/MediaDevices\";\nimport type {CallViewModel, CallMemberViewModel, IStreamViewModel} from \"../../../../../domain/session/room/CallViewModel\";\nimport { ErrorView } from \"../../general/ErrorView\";\n\nexport class CallView extends TemplateView {\n private resizeObserver?: ResizeObserver;\n \n render(t: Builder, vm: CallViewModel): Element {\n const members = t.view(new ListView({\n className: \"CallView_members\",\n list: vm.memberViewModels\n }, vm => new StreamView(vm))) as HTMLElement;\n this.bindMembersCssClasses(t, members);\n return t.div({class: \"CallView\"}, [\n members,\n //t.p(vm => `Call ${vm.name}`),\n t.div({class: \"CallView_buttons\"}, [\n t.button({className: {\n \"CallView_mutedMicrophone\": vm => vm.isMicrophoneMuted,\n \"CallView_unmutedMicrophone\": vm => !vm.isMicrophoneMuted,\n }, onClick: disableTargetCallback(() => vm.toggleMicrophone())}),\n t.button({className: {\n \"CallView_mutedCamera\": vm => vm.isCameraMuted,\n \"CallView_unmutedCamera\": vm => !vm.isCameraMuted,\n }, onClick: disableTargetCallback(() => vm.toggleCamera())}),\n t.button({className: \"CallView_hangup\", onClick: disableTargetCallback(() => vm.hangup())}),\n ]),\n t.if(vm => !!vm.errorViewModel, t => {\n return t.div({className: \"CallView_error\"}, t.view(new ErrorView(vm.errorViewModel!)));\n })\n ]);\n }\n\n private bindMembersCssClasses(t, members) {\n t.mapSideEffect(vm => vm.memberCount, count => {\n members.classList.forEach((c, _, list) => {\n if (c.startsWith(\"size\")) {\n list.remove(c);\n }\n });\n members.classList.add(`size${count}`);\n });\n // update classes describing aspect ratio categories\n if (typeof ResizeObserver === \"function\") {\n const set = (c, flag) => {\n if (flag) {\n members.classList.add(c);\n } else {\n members.classList.remove(c);\n }\n };\n this.resizeObserver = new ResizeObserver(() => {\n const ar = members.clientWidth / members.clientHeight;\n const isTall = ar < 0.5;\n const isSquare = !isTall && ar < 1.8\n const isWide = !isTall && !isSquare;\n set(\"tall\", isTall);\n set(\"square\", isSquare);\n set(\"wide\", isWide);\n });\n this.resizeObserver!.observe(members);\n }\n }\n\n public unmount() {\n if (this.resizeObserver) {\n this.resizeObserver.unobserve((this.root()! as Element).querySelector(\".CallView_members\")!);\n this.resizeObserver = undefined;\n }\n super.unmount();\n }\n}\n\nclass StreamView extends TemplateView {\n render(t: Builder, vm: IStreamViewModel): Element {\n const video = t.video({\n autoplay: true,\n disablePictureInPicture: true,\n className: {\n hidden: vm => vm.isCameraMuted\n }\n }) as HTMLVideoElement;\n t.mapSideEffect(vm => vm.stream, stream => {\n video.srcObject = stream as MediaStream;\n });\n return t.div({className: \"StreamView\"}, [\n video,\n t.div({className: {\n StreamView_avatar: true,\n hidden: vm => !vm.isCameraMuted\n }}, t.view(new AvatarView(vm, 96), {parentProvidesUpdates: true})),\n t.div({\n className: {\n StreamView_muteStatus: true,\n hidden: vm => !vm.isCameraMuted && !vm.isMicrophoneMuted,\n microphoneMuted: vm => vm.isMicrophoneMuted && !vm.isCameraMuted,\n cameraMuted: vm => vm.isCameraMuted,\n }\n }),\n t.if(vm => !!vm.errorViewModel, t => {\n return t.div({className: \"StreamView_error\"}, t.view(new ErrorView(vm.errorViewModel!)));\n })\n ]);\n }\n\n update(value, props) {\n super.update(value);\n // update the AvatarView as we told it to not subscribe itself with parentProvidesUpdates\n this.updateSubViews(value, props);\n }\n}\n\nfunction disableTargetCallback(callback: (evt: Event) => Promise): (evt: Event) => Promise {\n return async (evt: Event) => {\n (evt.target as HTMLElement)?.setAttribute(\"disabled\", \"disabled\");\n await callback(evt);\n (evt.target as HTMLElement)?.removeAttribute(\"disabled\");\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\"; \nimport {Popup} from \"../../general/Popup.js\";\nimport {Menu} from \"../../general/Menu.js\";\nimport {TimelineView} from \"./TimelineView\";\nimport {TimelineLoadingView} from \"./TimelineLoadingView.js\";\nimport {MessageComposer} from \"./MessageComposer.js\";\nimport {DisabledComposerView} from \"./DisabledComposerView.js\";\nimport {AvatarView} from \"../../AvatarView.js\";\nimport {CallView} from \"./CallView\";\nimport { ErrorView } from \"../../general/ErrorView\";\n\nexport class RoomView extends TemplateView {\n constructor(vm, viewClassForTile) {\n super(vm);\n this._viewClassForTile = viewClassForTile;\n this._optionsPopup = null;\n }\n\n render(t, vm) {\n return t.main({className: \"RoomView middle\"}, [\n t.div({className: \"RoomHeader middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Close room`}),\n t.view(new AvatarView(vm, 32)),\n t.div({className: \"room-description\"}, [\n t.h2(vm => vm.name),\n ]),\n t.button({\n className: \"button-utility room-options\",\n \"aria-label\":vm.i18n`Room options`,\n onClick: evt => this._toggleOptionsMenu(evt)\n })\n ]),\n t.div({className: \"RoomView_body\"}, [\n t.if(vm => vm.errorViewModel, t => t.div({className: \"RoomView_error\"}, t.view(new ErrorView(vm.errorViewModel)))),\n t.mapView(vm => vm.callViewModel, callViewModel => callViewModel ? new CallView(callViewModel) : null),\n t.mapView(vm => vm.timelineViewModel, timelineViewModel => {\n return timelineViewModel ?\n new TimelineView(timelineViewModel, this._viewClassForTile) :\n new TimelineLoadingView(vm); // vm is just needed for i18n\n }),\n t.mapView(vm => vm.composerViewModel, composerViewModel => {\n switch (composerViewModel?.kind) {\n case \"composer\":\n return new MessageComposer(vm.composerViewModel, this._viewClassForTile);\n case \"disabled\":\n return new DisabledComposerView(vm.composerViewModel);\n }\n }),\n ])\n ]);\n }\n \n _toggleOptionsMenu(evt) {\n if (this._optionsPopup && this._optionsPopup.isOpen) {\n this._optionsPopup.close();\n } else {\n const vm = this.value;\n const options = [];\n options.push(Menu.option(vm.i18n`Room details`, () => vm.openDetailsPanel()));\n if (vm.features.calls) {\n options.push(Menu.option(vm.i18n`Start call`, () => vm.startCall()));\n }\n if (vm.canLeave) {\n options.push(Menu.option(vm.i18n`Leave room`, () => this._confirmToLeaveRoom()).setDestructive());\n }\n if (vm.canForget) {\n options.push(Menu.option(vm.i18n`Forget room`, () => vm.forgetRoom()).setDestructive());\n }\n if (vm.canRejoin) {\n options.push(Menu.option(vm.i18n`Rejoin room`, () => vm.rejoinRoom()));\n }\n if (!options.length) {\n return;\n }\n this._optionsPopup = new Popup(new Menu(options));\n this._optionsPopup.trackInTemplateView(this);\n this._optionsPopup.showRelativeTo(evt.target, 10);\n }\n }\n\n _confirmToLeaveRoom() {\n if (confirm(this.value.i18n`Are you sure you want to leave \"${this.value.name}\"?`)) {\n this.value.leaveRoom();\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\n\nexport class UnknownRoomView extends TemplateView {\n render(t, vm) {\n return t.main({className: \"UnknownRoomView middle\"}, [\n t.div({className: \"UnknownRoomView_header middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Cancel room join`}),\n t.h2(\"Join room\"),\n ]),\n t.div({className: \"UnknownRoomView_body centered-column\"}, [\n t.div({className: \"UnknownRoomView_container\"}, [\n t.h2([\n vm.i18n`You are currently not in ${vm.roomIdOrAlias}.`,\n t.br(),\n vm.i18n`Want to join it?`\n ]),\n t.button({\n className: \"button-action primary\",\n onClick: () => vm.join(),\n disabled: vm => vm.busy,\n }, vm.i18n`Join room`),\n t.if(vm => vm.error, t => t.p({className: \"error\"}, vm.error))\n ])\n ])\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {tag} from \"../general/html\";\n\nexport class StaticView {\n constructor(value, render = undefined) {\n if (typeof value === \"function\" && !render) {\n render = value;\n value = null;\n }\n this._root = render ? render(tag, value) : this.render(tag, value);\n }\n\n mount() {\n return this._root;\n }\n\n root() {\n return this._root;\n }\n\n unmount() {}\n update() {}\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {StaticView} from \"./StaticView\";\nimport {spinner} from \"../common.js\";\n\nexport class LoadingView extends StaticView {\n constructor(label = \"Loading\") {\n super(label, (t, label) => {\n return t.div({ className: \"LoadingView\" }, [spinner(t), label]);\n });\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {LoadingView} from \"../../general/LoadingView\";\nimport {AvatarView} from \"../../AvatarView\";\n\nexport class RoomBeingCreatedView extends TemplateView {\n render(t, vm) {\n return t.main({className: \"RoomView middle\"}, [\n t.div({className: \"RoomHeader middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Close room`}),\n t.view(new AvatarView(vm, 32)),\n t.div({className: \"room-description\"}, [\n t.h2(vm => vm.name),\n ])\n ]),\n t.div({className: \"RoomView_body\"}, [\n t.mapView(vm => vm.error, error => {\n if (error) {\n return new ErrorView(vm);\n } else {\n return new LoadingView(vm.i18n`Setting up the room…`);\n }\n })\n ])\n ]);\n }\n}\n\nclass ErrorView extends TemplateView {\n render(t,vm) {\n return t.div({className: \"RoomBeingCreated_error centered-column\"}, [\n t.h3(vm.i18n`Could not create the room, something went wrong:`),\n t.div({className: \"RoomView_error form-group\"}, vm.error),\n t.div({className: \"button-row\"},\n t.button({\n className: \"button-action primary destructive\",\n onClick: () => vm.cancel()\n }, vm.i18n`Cancel`))\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {renderStaticAvatar} from \"../../avatar\";\n\nexport class InviteView extends TemplateView {\n render(t, vm) {\n let inviteNodes = [];\n if (vm.isDirectMessage) {\n inviteNodes.push(renderStaticAvatar(vm, 128, \"InviteView_dmAvatar\"));\n }\n let inviterNodes;\n if (vm.isDirectMessage) {\n inviterNodes = [t.strong(vm.name), ` (${vm.inviter?.id}) wants to chat with you.`];\n } else if (vm.inviter) {\n inviterNodes = [renderStaticAvatar(vm.inviter, 24), t.strong(vm.inviter.name), ` (${vm.inviter.id}) invited you.`];\n } else {\n inviterNodes = `You were invited to join.`;\n }\n inviteNodes.push(t.p({className: \"InviteView_inviter\"}, inviterNodes));\n if (!vm.isDirectMessage) {\n inviteNodes.push(t.div({className: \"InviteView_roomProfile\"}, [\n renderStaticAvatar(vm, 64, \"InviteView_roomAvatar\"),\n t.h3(vm.name),\n t.p({className: \"InviteView_roomDescription\"}, vm.roomDescription)\n ]));\n }\n\n return t.main({className: \"InviteView middle\"}, [\n t.div({className: \"RoomHeader middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Close invite`}),\n renderStaticAvatar(vm, 32),\n t.div({className: \"room-description\"}, [\n t.h2(vm => vm.name),\n ]),\n ]),\n t.if(vm => vm.error, t => t.div({className: \"RoomView_error\"}, vm => vm.error)),\n t.div({className: \"InviteView_body\"}, [\n t.div({className: \"InviteView_invite\"}, [\n ...inviteNodes,\n t.div({className: \"InviteView_buttonRow\"},\n t.button({\n className: \"button-action primary\",\n disabled: vm => vm.busy,\n onClick: () => vm.accept()\n }, vm.i18n`Accept`)\n ),\n t.div({className: \"InviteView_buttonRow\"},\n t.button({\n className: \"button-action primary destructive\",\n disabled: vm => vm.busy,\n onClick: () => vm.reject()\n }, vm.i18n`Reject`)\n ),\n ])\n ])\n ]);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {spinner} from \"../../common.js\";\n\nexport class LightboxView extends TemplateView {\n render(t, vm) {\n const close = t.a({href: vm.closeUrl, title: vm.i18n`Close`, className: \"close\"});\n const image = t.div({\n role: \"img\",\n \"aria-label\": vm => vm.name,\n title: vm => vm.name,\n className: {\n picture: true,\n hidden: vm => !vm.imageUrl,\n },\n style: vm => `background-image: url('${vm.imageUrl}'); max-width: ${vm.imageWidth}px; max-height: ${vm.imageHeight}px;`\n });\n const loading = t.div({\n className: {\n loading: true,\n hidden: vm => !!vm.imageUrl\n }\n }, [\n spinner(t),\n t.div(vm.i18n`Loading image…`)\n ]);\n const details = t.div({\n className: \"details\"\n }, [t.strong(vm => vm.name), t.br(), \"uploaded by \", t.strong(vm => vm.sender), vm => ` at ${vm.time} on ${vm.date}.`]);\n const dialog = t.div({\n role: \"dialog\",\n className: \"lightbox\",\n onClick: evt => this.clickToClose(evt),\n onKeydown: evt => this.closeOnEscKey(evt)\n }, [image, loading, details, close]);\n trapFocus(t, dialog);\n return dialog;\n }\n\n clickToClose(evt) {\n if (evt.target === this.root()) {\n this.value.close();\n }\n }\n\n closeOnEscKey(evt) {\n if (evt.key === \"Escape\" || evt.key === \"Esc\") {\n this.value.close();\n }\n }\n}\n\nfunction trapFocus(t, element) {\n const elements = focusables(element);\n const first = elements[0];\n const last = elements[elements.length - 1];\n\n t.addEventListener(element, \"keydown\", evt => {\n if (evt.key === \"Tab\") {\n if (evt.shiftKey) {\n if (document.activeElement === first) {\n last.focus();\n evt.preventDefault();\n }\n } else {\n if (document.activeElement === last) {\n first.focus();\n evt.preventDefault();\n }\n }\n }\n }, true);\n Promise.resolve().then(() => {\n first.focus();\n });\n}\n\nfunction focusables(element) {\n return element.querySelectorAll('a[href], button, textarea, input, select');\n}\n\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {spinner} from \"../common.js\";\n\nexport class SessionStatusView extends TemplateView {\n render(t, vm) {\n return t.div({className: {\n \"SessionStatusView\": true,\n \"hidden\": vm => !vm.isShown,\n }}, [\n spinner(t, {hidden: vm => !vm.isWaiting}),\n t.p(vm => vm.statusLabel),\n t.if(vm => vm.isConnectNowShown, t => t.button({className: \"link\", onClick: () => vm.connectNow()}, \"Retry now\")),\n t.if(vm => vm.isSecretStorageShown, t => t.a({href: vm.setupKeyBackupUrl}, \"Go to settings\")),\n t.if(vm => vm.canDismiss, t => t.div({className: \"end\"}, t.button({className: \"dismiss\", onClick: () => vm.dismiss()}))),\n ]);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {RoomView} from \"./room/RoomView.js\";\nimport {RoomBeingCreatedView} from \"./room/RoomBeingCreatedView.js\";\nimport {InviteView} from \"./room/InviteView.js\";\nimport {TemplateView} from \"../general/TemplateView\";\nimport {StaticView} from \"../general/StaticView.js\";\n\nexport class RoomGridView extends TemplateView {\n constructor(vm, viewClassForTile) {\n super(vm);\n this._viewClassForTile = viewClassForTile;\n }\n\n render(t, vm) {\n const children = [];\n for (let i = 0; i < (vm.height * vm.width); i+=1) {\n children.push(t.div({\n onClick: () => vm.focusTile(i),\n onFocusin: () => vm.focusTile(i),\n className: {\n \"container\": true,\n [`tile${i}`]: true,\n \"focused\": vm => vm.focusIndex === i\n },\n }, t.mapView(vm => vm.roomViewModelAt(i), roomVM => {\n if (roomVM) {\n if (roomVM.kind === \"roomBeingCreated\") {\n return new RoomBeingCreatedView(roomVM);\n } else if (roomVM.kind === \"invite\") {\n return new InviteView(roomVM);\n } else {\n return new RoomView(roomVM, this._viewClassForTile);\n }\n } else {\n return new StaticView(t => t.div({className: \"room-placeholder\"}, [\n t.h2({className: \"focused\"}, vm.i18n`Select a room on the left`),\n t.h2({className: \"unfocused\"}, vm.i18n`Click to select this tile`),\n ]));\n }\n })));\n }\n children.push(t.div({className: vm => `focus-ring tile${vm.focusIndex}`}));\n return t.div({className: \"RoomGridView middle layout3x2\"}, children);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView, Builder} from \"../../general/TemplateView\";\nimport {disableTargetCallback} from \"../../general/utils\";\nimport {ViewNode} from \"../../general/types\";\nimport {KeyBackupViewModel, Status, BackupWriteStatus} from \"../../../../../domain/session/settings/KeyBackupViewModel\";\nimport {KeyType} from \"../../../../../matrix/ssss/index\";\n\nexport class KeyBackupSettingsView extends TemplateView {\n render(t: Builder, vm: KeyBackupViewModel): ViewNode {\n return t.div([\n t.map(vm => vm.status, (status, t, vm) => {\n switch (status) {\n case Status.Enabled: return renderEnabled(t, vm);\n case Status.NewVersionAvailable: return renderNewVersionAvailable(t, vm);\n case Status.SetupWithPassphrase: return renderEnableFromPhrase(t, vm);\n case Status.SetupWithRecoveryKey: return renderEnableFromKey(t, vm);\n case Status.Pending: return t.p(vm.i18n`Waiting to go online…`);\n }\n }),\n t.map(vm => vm.backupWriteStatus, (status, t, vm) => {\n switch (status) {\n case BackupWriteStatus.Writing: {\n const progress = t.progress({\n min: 0+\"\",\n max: 100+\"\",\n value: vm => vm.backupPercentage,\n });\n return t.div([`Backup in progress `, progress, \" \", vm => vm.backupInProgressLabel]);\n }\n case BackupWriteStatus.Stopped: {\n let label;\n const error = vm.backupError;\n if (error) {\n label = `Backup has stopped because of an error: ${vm.backupError}`;\n } else {\n label = `Backup has stopped`;\n }\n return t.p([label, \" \", t.button({onClick: () => vm.startBackup()}, `Backup now`)]);\n }\n case BackupWriteStatus.Done:\n return t.p(`All keys are backed up.`);\n default:\n return undefined;\n }\n }),\n t.if(vm => vm.isMasterKeyTrusted, t => {\n return t.p(\"Cross-signing master key found and trusted.\")\n }),\n t.if(vm => vm.canSignOwnDevice, t => {\n return t.div([\n t.button(\n {\n onClick: disableTargetCallback(async () => {\n vm.navigateToVerification();\n }),\n },\n \"Verify by emoji\"\n ),\n ]);\n }),\n\n ]);\n }\n}\n\nfunction renderEnabled(t: Builder, vm: KeyBackupViewModel): ViewNode {\n const items = [\n t.p([vm.i18n`Key backup is enabled, using backup version ${vm.backupVersion}. `, t.button({onClick: () => vm.disable()}, vm.i18n`Disable`)])\n ];\n if (vm.dehydratedDeviceId) {\n items.push(t.p(vm.i18n`A dehydrated device id was set up with id ${vm.dehydratedDeviceId} which you can use during your next login with your secret storage key.`));\n }\n return t.div(items);\n}\n\nfunction renderNewVersionAvailable(t: Builder, vm: KeyBackupViewModel): ViewNode {\n const items = [\n t.p([vm.i18n`A new backup version has been created from another device. Disable key backup and enable it again with the new key.`, t.button({onClick: () => vm.disable()}, vm.i18n`Disable`)])\n ];\n return t.div(items);\n}\n\nfunction renderEnableFromKey(t: Builder, vm: KeyBackupViewModel): ViewNode {\n const useASecurityPhrase = t.button({className: \"link\", onClick: () => vm.showPhraseSetup()}, vm.i18n`use a security phrase`);\n return t.div([\n t.p(vm.i18n`Enter your secret storage security key below to ${vm.purpose}, which will enable you to decrypt messages received before you logged into this session. The security key is a code of 12 groups of 4 characters separated by a space that Element created for you when setting up security.`),\n renderError(t),\n renderEnableFieldRow(t, vm, vm.i18n`Security key`, (key, setupDehydratedDevice) => vm.enterSecurityKey(key, setupDehydratedDevice)),\n t.p([vm.i18n`Alternatively, you can `, useASecurityPhrase, vm.i18n` if you have one.`]),\n ]);\n}\n\nfunction renderEnableFromPhrase(t: Builder, vm: KeyBackupViewModel): ViewNode {\n const useASecurityKey = t.button({className: \"link\", onClick: () => vm.showKeySetup()}, vm.i18n`use your security key`);\n return t.div([\n t.p(vm.i18n`Enter your secret storage security phrase below to ${vm.purpose}, which will enable you to decrypt messages received before you logged into this session. The security phrase is a freeform secret phrase you optionally chose when setting up security in Element. It is different from your password to login, unless you chose to set them to the same value.`),\n renderError(t),\n renderEnableFieldRow(t, vm, vm.i18n`Security phrase`, (phrase, setupDehydratedDevice) => vm.enterSecurityPhrase(phrase, setupDehydratedDevice)),\n t.p([vm.i18n`You can also `, useASecurityKey, vm.i18n`.`]),\n ]);\n}\n\nfunction renderEnableFieldRow(t, vm, label, callback): ViewNode {\n let setupDehydrationCheck;\n const eventHandler = () => callback(input.value, setupDehydrationCheck?.checked || false);\n const input = t.input({type: \"password\", disabled: vm => vm.isBusy, placeholder: label});\n const children = [\n t.p([\n input,\n t.button({disabled: vm => vm.isBusy, onClick: eventHandler}, vm.decryptAction),\n ]),\n ];\n if (vm.offerDehydratedDeviceSetup) {\n setupDehydrationCheck = t.input({type: \"checkbox\", id:\"enable-dehydrated-device\"});\n const moreInfo = t.a({href: \"https://github.com/uhoreg/matrix-doc/blob/dehydration/proposals/2697-device-dehydration.md\", target: \"_blank\", rel: \"noopener\"}, \"more info\");\n children.push(t.p([\n setupDehydrationCheck,\n t.label({for: setupDehydrationCheck.id}, [vm.i18n`Back up my device as well (`, moreInfo, \")\"])\n ]));\n }\n return t.div({className: `row`}, [\n t.div({className: \"label\"}, label),\n t.div({className: \"content\"}, children),\n ]);\n}\n\nfunction renderError(t: Builder): ViewNode {\n return t.if(vm => vm.error !== undefined, (t, vm) => {\n return t.div([\n t.p({className: \"error\"}, vm => vm.i18n`Could not enable key backup: ${vm.error}.`),\n t.p(vm.i18n`Try double checking that you did not mix up your security key, security phrase and login password as explained above.`)\n ])\n });\n}\n\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView, TemplateBuilder} from \"../../general/TemplateView\";\nimport {ViewNode} from \"../../general/types\";\nimport {disableTargetCallback} from \"../../general/utils\";\nimport type {FeaturesViewModel, FeatureViewModel} from \"../../../../../domain/session/settings/FeaturesViewModel\";\n\nexport class FeaturesView extends TemplateView {\n render(t, vm: FeaturesViewModel): ViewNode {\n return t.div({\n className: \"FeaturesView\",\n }, [\n t.p(\"Enable experimental features here that are still in development. These are not yet ready for primetime, so expect bugs.\"),\n // we don't use a binding/ListView because this is a static list\n t.ul(vm.featureViewModels.map(vm => {\n return t.li(t.view(new FeatureView(vm)));\n }))\n ]);\n }\n}\n\nclass FeatureView extends TemplateView {\n render(t, vm): ViewNode {\n let id = `feature_${vm.id}`;\n return t.div({className: \"FeatureView\"}, [\n t.input({\n type: \"checkbox\",\n id,\n checked: vm => vm.enabled,\n onChange: evt => vm.enableFeature(evt.target.checked)\n }),\n t.div({class: \"FeatureView_container\"}, [\n t.h4(t.label({for: id}, vm.name)),\n t.p(vm.description)\n ])\n ]);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {disableTargetCallback} from \"../../general/utils\";\nimport {KeyBackupSettingsView} from \"./KeyBackupSettingsView\"\nimport {FeaturesView} from \"./FeaturesView\"\n\nexport class SettingsView extends TemplateView {\n render(t, vm) {\n let version = vm.version;\n if (vm.showUpdateButton) {\n version = t.span([\n vm.version,\n t.button({onClick: () => vm.checkForUpdate()}, vm.i18n`Check for updates`)\n ]);\n }\n\n const row = (t, label, content, extraClass = \"\") => {\n return t.div({className: `row ${extraClass}`}, [\n t.div({className: \"label\"}, label),\n t.div({className: \"content\"}, content),\n ]);\n };\n\n const settingNodes = [];\n\n settingNodes.push(\n t.h3(\"Session\"),\n row(t, vm.i18n`User ID`, vm.userId),\n row(t, vm.i18n`Session ID`, vm.deviceId, \"code\"),\n row(t, vm.i18n`Session key`, vm.fingerprintKey, \"code\"),\n row(t, \"\", t.button({\n onClick: () => vm.logout(),\n disabled: vm => vm.isLoggingOut\n }, vm.i18n`Log out`)),\n );\n settingNodes.push(\n t.h3(\"Key backup & security\"),\n t.view(new KeyBackupSettingsView(vm.keyBackupViewModel))\n );\n\n settingNodes.push(\n t.h3(\"Notifications\"),\n t.map(vm => vm.pushNotifications.supported, (supported, t) => {\n if (supported === null) {\n return t.p(vm.i18n`Loading…`);\n } else if (supported) {\n const label = vm => vm.pushNotifications.enabled ?\n vm.i18n`Push notifications are enabled`:\n vm.i18n`Push notifications are disabled`;\n const buttonLabel = vm => vm.pushNotifications.enabled ?\n vm.i18n`Disable`:\n vm.i18n`Enable`;\n return row(t, label, t.button({\n onClick: () => vm.togglePushNotifications(),\n disabled: vm => vm.pushNotifications.updating\n }, buttonLabel));\n } else {\n return t.p(vm.i18n`Push notifications are not supported on this browser`);\n }\n }),\n t.if(vm => vm.pushNotifications.supported && vm.pushNotifications.enabled, t => {\n return t.div([\n t.p([\n \"If you think push notifications are not being delivered, \",\n t.button({className: \"link\", onClick: () => vm.checkPushEnabledOnServer()}, \"check\"),\n \" if they got disabled on the server\"\n ]),\n t.map(vm => vm.pushNotifications.enabledOnServer, (enabled, t) => {\n if (enabled === true) {\n return t.p(\"Push notifications are still enabled on the server, so everything should be working. Sometimes notifications can get dropped if they can't be delivered within a given time.\");\n } else if (enabled === false) {\n return t.p(\"Push notifications have been disabled on the server, likely due to a bug. Please re-enable them by clicking Disable and then Enable again above.\");\n }\n }),\n t.map(vm => vm.pushNotifications.serverError, (err, t) => {\n if (err) {\n return t.p(\"Couldn't not check on server: \" + err.message);\n }\n })\n ]);\n })\n );\n \n settingNodes.push(\n t.h3(\"Preferences\"),\n row(t, vm.i18n`Scale down images when sending`, this._imageCompressionRange(t, vm)),\n t.if(vm => !import.meta.env.DEV && vm.activeTheme, (t, vm) => {\n return row(t, vm.i18n`Use the following theme`, this._themeOptions(t, vm));\n }),\n );\n const logButtons = [];\n if (import.meta.env.DEV) {\n logButtons.push(t.button({onClick: () => openLogs(vm)}, \"Open logs\"));\n }\n if (vm.canSendLogsToServer) {\n logButtons.push(t.button({onClick: disableTargetCallback(() => vm.sendLogsToServer())}, `Submit logs to ${vm.logsServer}`));\n }\n logButtons.push(t.button({onClick: () => vm.exportLogs()}, \"Download logs\"));\n\n settingNodes.push(\n t.h3(\"Experimental features\"),\n t.view(new FeaturesView(vm.featuresViewModel))\n );\n\n settingNodes.push(\n t.h3(\"Application\"),\n row(t, vm.i18n`Version`, version),\n row(t, vm.i18n`Storage usage`, vm => `${vm.storageUsage} / ${vm.storageQuota}`),\n row(t, vm.i18n`Debug logs`, logButtons),\n t.p({className: {hidden: vm => !vm.logsFeedbackMessage}}, vm => vm.logsFeedbackMessage),\n t.p([\"Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited, the usernames of other users and the names of files you send. They do not contain messages. For more information, review our \",\n t.a({href: \"https://element.io/privacy\", target: \"_blank\", rel: \"noopener\"}, \"privacy policy\"), \".\"]),\n t.p([])\n );\n\n return t.main({className: \"Settings middle\"}, [\n t.div({className: \"middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Close settings`}),\n t.h2(\"Settings\")\n ]),\n t.div({className: \"SettingsBody\"}, settingNodes)\n ]);\n }\n\n _imageCompressionRange(t, vm) {\n const step = 32;\n const min = Math.ceil(vm.minSentImageSizeLimit / step) * step;\n const max = (Math.floor(vm.maxSentImageSizeLimit / step) + 1) * step;\n const updateSetting = evt => vm.setSentImageSizeLimit(parseInt(evt.target.value, 10));\n return [t.input({\n type: \"range\",\n step,\n min,\n max,\n value: vm => vm.sentImageSizeLimit || max,\n onInput: updateSetting,\n onChange: updateSetting,\n }), \" \", t.output(vm => {\n return vm.sentImageSizeLimit ? \n vm.i18n`resize to ${vm.sentImageSizeLimit}px` :\n vm.i18n`no resizing`;\n })];\n }\n\n _themeOptions(t, vm) {\n const { themeName: activeThemeName, themeVariant: activeThemeVariant } = vm.activeTheme;\n const optionTags = [];\n // 1. render the dropdown containing the themes\n for (const name of Object.keys(vm.themeMapping)) {\n optionTags.push( t.option({ value: name, selected: name === activeThemeName} , name));\n }\n const select = t.select({\n onChange: (e) => {\n const themeName = e.target.value;\n if(!(\"id\" in vm.themeMapping[themeName])) {\n const colorScheme = darkRadioButton.checked ? \"dark\" : lightRadioButton.checked ? \"light\" : \"default\";\n // execute the radio-button callback so that the theme actually changes!\n // otherwise the theme would only change when another radio-button is selected.\n radioButtonCallback(colorScheme);\n return;\n }\n vm.changeThemeOption(themeName);\n }\n }, optionTags);\n // 2. render the radio-buttons used to choose variant\n const radioButtonCallback = (colorScheme) => {\n const selectedThemeName = select.options[select.selectedIndex].value;\n vm.changeThemeOption(selectedThemeName, colorScheme);\n };\n const isDarkSelected = activeThemeVariant === \"dark\";\n const isLightSelected = activeThemeVariant === \"light\";\n const darkRadioButton = t.input({ type: \"radio\", name: \"radio-chooser\", value: \"dark\", id: \"dark\", checked: isDarkSelected });\n const defaultRadioButton = t.input({ type: \"radio\", name: \"radio-chooser\", value: \"default\", id: \"default\", checked: !(isDarkSelected || isLightSelected) });\n const lightRadioButton = t.input({ type: \"radio\", name: \"radio-chooser\", value: \"light\", id: \"light\", checked: isLightSelected });\n const radioButtons = t.form({\n className: {\n hidden: () => {\n const themeName = select.options[select.selectedIndex].value;\n return \"id\" in vm.themeMapping[themeName];\n }\n },\n onChange: (e) => radioButtonCallback(e.target.value)\n },\n [\n defaultRadioButton,\n t.label({for: \"default\"}, \"Match system theme\"),\n darkRadioButton,\n t.label({for: \"dark\"}, \"dark\"),\n lightRadioButton,\n t.label({for: \"light\"}, \"light\"),\n ]);\n return t.div({ className: \"theme-chooser\" }, [select, radioButtons]);\n }\n}\n\n\nasync function openLogs(vm) {\n // Use vite-specific url so this asset doesn't get picked up by vite and included in the production build,\n // as opening the logs is only available during dev time, and @matrixdotorg/structured-logviewer is a dev dependency\n // This url is what import \"@matrixdotorg/structured-logviewer/index.html?url\" resolves to with vite.\n const win = window.open(`/@fs/${DEFINE_PROJECT_DIR}/node_modules/@matrixdotorg/structured-logviewer/index.html`);\n await new Promise((resolve, reject) => {\n let shouldSendPings = true;\n const cleanup = () => {\n shouldSendPings = false;\n window.removeEventListener(\"message\", waitForPong);\n };\n const waitForPong = event => {\n if (event.data.type === \"pong\") {\n cleanup();\n resolve();\n }\n };\n const sendPings = async () => {\n while (shouldSendPings) {\n win.postMessage({type: \"ping\"});\n await new Promise(rr => setTimeout(rr, 50));\n if (win.closed) {\n cleanup();\n }\n }\n };\n window.addEventListener(\"message\", waitForPong);\n sendPings().catch(reject);\n });\n const logs = await vm.exportLogsBlob();\n win.postMessage({type: \"open\", logs: logs.nativeBlob});\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {AvatarView} from \"../AvatarView\";\nimport {StaticView} from \"../general/StaticView\";\n\nexport class CreateRoomView extends TemplateView {\n render(t, vm) {\n return t.main({className: \"CreateRoomView middle\"}, [\n t.div({className: \"CreateRoomView_header middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Cancel room creation`}),\n t.h2(\"Create room\"),\n ]),\n t.div({className: \"CreateRoomView_body centered-column\"}, [\n //t.div({className: \"RoomView_error\"}, vm => vm.error),\n t.form({className: \"CreateRoomView_detailsForm form\", onChange: evt => this.onFormChange(evt), onSubmit: evt => this.onSubmit(evt)}, [\n t.div({className: \"vertical-layout\"}, [\n t.button({type: \"button\", className: \"CreateRoomView_selectAvatar\", onClick: () => vm.selectAvatar()},\n t.mapView(vm => vm.hasAvatar, hasAvatar => {\n if (hasAvatar) {\n return new AvatarView(vm, 64);\n } else {\n return new StaticView(undefined, t => {\n return t.div({className: \"CreateRoomView_selectAvatarPlaceholder\"})\n });\n }\n })\n ),\n t.div({className: \"stretch form-row text\"}, [\n t.label({for: \"name\"}, vm.i18n`Room name`),\n t.input({\n onInput: evt => vm.setName(evt.target.value),\n type: \"text\", name: \"name\", id: \"name\",\n placeholder: vm.i18n`Enter a room name`\n }),\n ]),\n ]),\n t.div({className: \"form-row text\"}, [\n t.label({for: \"topic\"}, vm.i18n`Topic (optional)`),\n t.textarea({\n onInput: evt => vm.setTopic(evt.target.value),\n name: \"topic\", id: \"topic\",\n placeholder: vm.i18n`Topic`\n }),\n ]),\n t.div({className: \"form-group\"}, [\n t.div({className: \"form-row check\"}, [\n t.input({type: \"radio\", name: \"isPublic\", id: \"isPrivate\", value: \"false\", checked: !vm.isPublic}),\n t.label({for: \"isPrivate\"}, vm.i18n`Private room, only upon invitation.`)\n ]),\n t.div({className: \"form-row check\"}, [\n t.input({type: \"radio\", name: \"isPublic\", id: \"isPublic\", value: \"true\", checked: vm.isPublic}),\n t.label({for: \"isPublic\"}, vm.i18n`Public room, anyone can join`)\n ]),\n ]),\n t.div({className: {\"form-row check\": true, hidden: vm => vm.isPublic}}, [\n t.input({type: \"checkbox\", name: \"isEncrypted\", id: \"isEncrypted\", checked: vm.isEncrypted}),\n t.label({for: \"isEncrypted\"}, vm.i18n`Enable end-to-end encryption`)\n ]),\n t.div({className: {\"form-row text\": true, hidden: vm => !vm.isPublic}}, [\n t.label({for: \"roomAlias\"}, vm.i18n`Room alias`),\n t.input({\n onInput: evt => vm.setRoomAlias(evt.target.value),\n type: \"text\", name: \"roomAlias\", id: \"roomAlias\",\n placeholder: vm.i18n`Room alias (, or # or #:hs.tld`}),\n ]),\n t.div({className: \"form-group\"}, [\n t.div(t.button({className: \"link\", type: \"button\", onClick: () => vm.toggleAdvancedShown()},\n vm => vm.isAdvancedShown ? vm.i18n`Hide advanced settings` : vm.i18n`Show advanced settings`)),\n t.div({className: {\"form-row check\": true, hidden: vm => !vm.isAdvancedShown}}, [\n t.input({type: \"checkbox\", name: \"isFederationDisabled\", id: \"isFederationDisabled\", checked: vm.isFederationDisabled}),\n t.label({for: \"isFederationDisabled\"}, [\n vm.i18n`Disable federation`,\n t.p({className: \"form-row-description\"}, vm.i18n`Can't be changed later. This will prevent people on other homeservers from joining the room. This is typically used when only people from your own organisation (if applicable) should be allowed in the room, and is otherwise not needed.`)\n ]),\n ]),\n ]),\n t.div({className: \"button-row\"}, [\n t.button({\n className: \"button-action primary\",\n type: \"submit\",\n disabled: vm => !vm.canCreate\n }, vm.i18n`Create room`),\n ]),\n ])\n ])\n ]);\n }\n\n onFormChange(evt) {\n switch (evt.target.name) {\n case \"isEncrypted\":\n this.value.setEncrypted(evt.target.checked);\n break;\n case \"isPublic\":\n this.value.setPublic(evt.currentTarget.isPublic.value === \"true\");\n break;\n case \"isFederationDisabled\":\n this.value.setFederationDisabled(evt.target.checked);\n break;\n }\n }\n\n onSubmit(evt) {\n evt.preventDefault();\n this.value.create();\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {classNames, tag} from \"../../general/html\";\nimport {AvatarView} from \"../../AvatarView.js\";\n\nexport class RoomDetailsView extends TemplateView {\n render(t, vm) {\n const encryptionString = () => vm.isEncrypted ? vm.i18n`On` : vm.i18n`Off`;\n return t.div({className: \"RoomDetailsView\"}, [\n t.div({className: \"RoomDetailsView_avatar\"},\n [\n t.view(new AvatarView(vm, 52)),\n t.mapView(vm => vm.isEncrypted, isEncrypted => new EncryptionIconView(isEncrypted))\n ]),\n t.div({className: \"RoomDetailsView_name\"}, [t.h2(vm => vm.name)]),\n this._createRoomAliasDisplay(vm),\n t.div({className: \"RoomDetailsView_rows\"},\n [\n this._createRightPanelButtonRow(t, vm.i18n`People`, { MemberCount: true }, vm => vm.memberCount,\n () => vm.openPanel(\"members\")),\n this._createRightPanelRow(t, vm.i18n`Encryption`, {EncryptionStatus: true}, encryptionString)\n ])\n ]);\n }\n\n _createRoomAliasDisplay(vm) {\n return vm.canonicalAlias ? tag.div({className: \"RoomDetailsView_id\"}, [vm.canonicalAlias]) :\n \"\";\n }\n\n _createRightPanelRow(t, label, labelClass, value) {\n const labelClassString = classNames({RoomDetailsView_label: true, ...labelClass});\n return t.div({className: \"RoomDetailsView_row\"}, [\n t.div({className: labelClassString}, [label]),\n t.div({className: \"RoomDetailsView_value\"}, value)\n ]);\n }\n\n _createRightPanelButtonRow(t, label, labelClass, value, onClick) {\n const labelClassString = classNames({RoomDetailsView_label: true, ...labelClass});\n return t.button({className: \"RoomDetailsView_row\", onClick}, [\n t.div({className: labelClassString}, [label]),\n t.div({className: \"RoomDetailsView_value\"}, value)\n ]);\n }\n\n}\n\nclass EncryptionIconView extends TemplateView {\n render(t, isEncrypted) {\n return t.div({className: \"EncryptionIconView\"},\n [t.div({className: isEncrypted ? \"EncryptionIconView_encrypted\" : \"EncryptionIconView_unencrypted\"})]);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// start is included in the range,\n// end is excluded,\n// so [2, 2[ means an empty range\nexport class Range {\n constructor(\n public readonly start: number,\n public readonly end: number\n ) {}\n\n get length() {\n return this.end - this.start;\n }\n\n contains(range: Range): boolean {\n return range.start >= this.start && range.end <= this.end;\n }\n\n containsIndex(idx: number): boolean {\n return idx >= this.start && idx < this.end;\n }\n\n toLocalIndex(idx: number) {\n return idx - this.start;\n }\n\n intersects(range: Range): boolean {\n return range.start < this.end && this.start < range.end;\n }\n\n forEachInIterator(it: Iterator, callback: ((T, i: number) => void)) {\n let i = 0;\n for (i = 0; i < this.start; i += 1) {\n it.next();\n }\n for (i = 0; i < this.length; i += 1) {\n const result = it.next();\n if (result.done) {\n break;\n } else {\n callback(result.value, this.start + i);\n }\n }\n }\n\n [Symbol.iterator](): Iterator {\n return new RangeIterator(this);\n }\n\n reverseIterable(): Iterable {\n return new ReverseRangeIterator(this);\n }\n\n clampIndex(idx: number, end = this.end - 1) {\n return Math.min(Math.max(this.start, idx), end);\n }\n\n getIndexZone(idx): RangeZone {\n if (idx < this.start) {\n return RangeZone.Before;\n } else if (idx < this.end) {\n return RangeZone.Inside;\n } else {\n return RangeZone.After;\n }\n }\n}\n\nexport enum RangeZone {\n Before = 1,\n Inside,\n After\n}\n\nclass RangeIterator implements Iterator {\n private idx: number;\n constructor(private readonly range: Range) {\n this.idx = range.start - 1;\n }\n\n next(): IteratorResult {\n if (this.idx < (this.range.end - 1)) {\n this.idx += 1;\n return {value: this.idx, done: false};\n } else {\n return {value: undefined, done: true};\n }\n }\n}\n\nclass ReverseRangeIterator implements Iterable, Iterator {\n private idx: number;\n constructor(private readonly range: Range) {\n this.idx = range.end;\n }\n\n [Symbol.iterator]() {\n return this;\n }\n\n next(): IteratorResult {\n if (this.idx > this.range.start) {\n this.idx -= 1;\n return {value: this.idx, done: false};\n } else {\n return {value: undefined, done: true};\n }\n }\n}\n\nexport function tests() {\n return {\n \"length\": assert => {\n const a = new Range(2, 5);\n assert.equal(a.length, 3);\n },\n \"iterator\": assert => {\n assert.deepEqual(Array.from(new Range(2, 5)), [2, 3, 4]);\n },\n \"reverseIterable\": assert => {\n assert.deepEqual(Array.from(new Range(2, 5).reverseIterable()), [4, 3, 2]);\n },\n \"containsIndex\": assert => {\n const a = new Range(2, 5);\n assert.equal(a.containsIndex(0), false);\n assert.equal(a.containsIndex(1), false);\n assert.equal(a.containsIndex(2), true);\n assert.equal(a.containsIndex(3), true);\n assert.equal(a.containsIndex(4), true);\n assert.equal(a.containsIndex(5), false);\n assert.equal(a.containsIndex(6), false);\n },\n \"intersects returns false for touching ranges\": assert => {\n const a = new Range(2, 5);\n const b = new Range(5, 10);\n assert.equal(a.intersects(b), false);\n assert.equal(b.intersects(a), false);\n },\n \"intersects returns false\": assert => {\n const a = new Range(2, 5);\n const b = new Range(50, 100);\n assert.equal(a.intersects(b), false);\n assert.equal(b.intersects(a), false);\n },\n \"intersects returns true for 1 overlapping item\": assert => {\n const a = new Range(2, 5);\n const b = new Range(4, 10);\n assert.equal(a.intersects(b), true);\n assert.equal(b.intersects(a), true);\n },\n \"contains beyond left edge\": assert => {\n const a = new Range(2, 5);\n const b = new Range(1, 3);\n assert.equal(a.contains(b), false);\n },\n \"contains at left edge\": assert => {\n const a = new Range(2, 5);\n const b = new Range(2, 3);\n assert.equal(a.contains(b), true);\n },\n \"contains between edges\": assert => {\n const a = new Range(2, 5);\n const b = new Range(3, 4);\n assert.equal(a.contains(b), true);\n },\n \"contains at right edge\": assert => {\n const a = new Range(2, 5);\n const b = new Range(3, 5);\n assert.equal(a.contains(b), true);\n },\n \"contains beyond right edge\": assert => {\n const a = new Range(2, 5);\n const b = new Range(4, 6);\n assert.equal(a.contains(b), false);\n },\n \"contains for non-intersecting ranges\": assert => {\n const a = new Range(2, 5);\n const b = new Range(5, 6);\n assert.equal(a.contains(b), false);\n },\n \"forEachInIterator with more values available\": assert => {\n const callbackValues: {v: string, i: number}[] = [];\n const values = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"];\n const it = values[Symbol.iterator]();\n new Range(2, 5).forEachInIterator(it, (v, i) => callbackValues.push({v, i}));\n assert.deepEqual(callbackValues, [\n {v: \"c\", i: 2},\n {v: \"d\", i: 3},\n {v: \"e\", i: 4},\n ]);\n },\n \"forEachInIterator with fewer values available\": assert => {\n const callbackValues: {v: string, i: number}[] = [];\n const values = [\"a\", \"b\", \"c\"];\n const it = values[Symbol.iterator]();\n new Range(2, 5).forEachInIterator(it, (v, i) => callbackValues.push({v, i}));\n assert.deepEqual(callbackValues, [\n {v: \"c\", i: 2},\n ]);\n },\n \"clampIndex\": assert => {\n assert.equal(new Range(2, 5).clampIndex(0), 2);\n assert.equal(new Range(2, 5).clampIndex(2), 2);\n assert.equal(new Range(2, 5).clampIndex(3), 3);\n assert.equal(new Range(2, 5).clampIndex(4), 4);\n assert.equal(new Range(2, 5).clampIndex(5), 4);\n assert.equal(new Range(2, 5).clampIndex(10), 4);\n }\n };\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Range, RangeZone} from \"./Range\";\nimport {defaultObserverWith} from \"../../../../observable/list/BaseObservableList\";\n\nfunction skipOnIterator(it: Iterator, pos: number): boolean {\n let i = 0;\n while (i < pos) {\n i += 1;\n if(it.next().done) {\n return false;\n }\n }\n return true;\n}\n\nfunction getIteratorValueAtIdx(it: Iterator, idx: number): undefined | T {\n if (skipOnIterator(it, idx)) {\n const result = it.next();\n if (!result.done) {\n return result.value;\n }\n }\n return undefined;\n}\n\nexport enum ResultType {\n Move,\n Add,\n Remove,\n RemoveAndAdd,\n UpdateRange\n}\n\nexport interface MoveResult {\n type: ResultType.Move;\n fromIdx: number;\n toIdx: number\n}\n\ninterface AddResult {\n type: ResultType.Add;\n newRange?: ListRange;\n /** the list index of an item to add */\n addIdx: number;\n /** the value to add at addIdx */\n value: T\n}\n\ninterface RemoveResult {\n type: ResultType.Remove;\n newRange?: ListRange;\n /** the list index of an item to remove, before the add or remove event has been taken into account */\n removeIdx: number;\n}\n\n// need to repeat the fields from RemoveResult and AddResult here\n// to make the discriminated union work\ninterface RemoveAndAddResult {\n type: ResultType.RemoveAndAdd;\n newRange?: ListRange;\n /** the list index of an item to remove, before the add or remove event has been taken into account */\n removeIdx: number;\n /** the list index of an item to add */\n addIdx: number;\n /** the value to add at addIdx */\n value: T;\n}\n\ninterface UpdateRangeResult {\n type: ResultType.UpdateRange;\n newRange?: ListRange;\n}\n\nexport type AddRemoveResult = AddResult | RemoveResult | RemoveAndAddResult | UpdateRangeResult;\n\nexport class ListRange extends Range {\n constructor(\n start: number,\n end: number,\n private _totalLength: number,\n private _viewportItemCount: number = end - start\n ) {\n super(start, end);\n }\n\n expand(amount: number): ListRange {\n // don't expand ranges that won't render anything\n if (this.length === 0) {\n return this;\n }\n const newStart = Math.max(0, this.start - amount);\n const newEnd = Math.min(this.totalLength, this.end + amount);\n return new ListRange(\n newStart,\n newEnd,\n this.totalLength,\n this._viewportItemCount\n );\n }\n\n get totalLength(): number {\n return this._totalLength;\n }\n\n get viewportItemCount(): number {\n return this._viewportItemCount;\n }\n\n static fromViewport(listLength: number, itemHeight: number, listHeight: number, scrollTop: number) {\n const topCount = Math.min(Math.max(0, Math.floor(scrollTop / itemHeight)), listLength);\n const itemsAfterTop = listLength - topCount;\n const viewportItemCount = listHeight !== 0 ? Math.ceil(listHeight / itemHeight) : 0;\n const renderCount = Math.min(viewportItemCount, itemsAfterTop);\n return new ListRange(topCount, topCount + renderCount, listLength, viewportItemCount);\n }\n\n queryAdd(idx: number, value: T, list: Iterable): AddRemoveResult {\n const maxAddIdx = this.viewportItemCount > this.length ? this.end : this.end - 1;\n if (idx <= maxAddIdx) {\n // use maxAddIdx to allow to grow the range by one at a time\n // if the viewport isn't filled yet\n const addIdx = this.clampIndex(idx, maxAddIdx);\n const addValue = addIdx === idx ? value : getIteratorValueAtIdx(list[Symbol.iterator](), addIdx)!;\n return this.createAddResult(addIdx, addValue);\n } else {\n // if the add happened after the range, we only update the range with the new length\n return {type: ResultType.UpdateRange, newRange: this.deriveRange(1, 0)};\n }\n }\n\n queryRemove(idx: number, list: Iterable): AddRemoveResult {\n if (idx < this.end) {\n const removeIdx = this.clampIndex(idx);\n return this.createRemoveResult(removeIdx, list);\n } else {\n return {type: ResultType.UpdateRange, newRange: this.deriveRange(-1, 0)};\n }\n }\n\n queryMove(fromIdx: number, toIdx: number, value: T, list: Iterable): MoveResult | AddRemoveResult | undefined {\n const fromZone = this.getIndexZone(fromIdx);\n const toZone = this.getIndexZone(toIdx);\n if (fromZone === toZone) {\n if (fromZone === RangeZone.Before || fromZone === RangeZone.After) {\n return;\n } else if (fromZone === RangeZone.Inside) {\n return {type: ResultType.Move, fromIdx, toIdx};\n }\n } else {\n const addIdx = this.clampIndex(toIdx);\n const removeIdx = this.clampIndex(fromIdx);\n const addValue = addIdx === toIdx ? value : getIteratorValueAtIdx(list[Symbol.iterator](), addIdx)!;\n return {type: ResultType.RemoveAndAdd, removeIdx, addIdx, value: addValue};\n }\n }\n\n private createAddResult(addIdx: number, value: T): AddRemoveResult {\n // if the view port isn't filled yet, we don't remove\n if (this.viewportItemCount > this.length) {\n return {type: ResultType.Add, addIdx, value, newRange: this.deriveRange(1, 1)};\n } else {\n const removeIdx = this.clampIndex(Number.MAX_SAFE_INTEGER);\n return {type: ResultType.RemoveAndAdd, removeIdx, addIdx, value, newRange: this.deriveRange(1, 0)};\n }\n }\n\n private createRemoveResult(removeIdx: number, list: Iterable): AddRemoveResult {\n if (this.end < this.totalLength) {\n // we have items below the range, we can add one from there to fill the viewport\n const addIdx = this.clampIndex(Number.MAX_SAFE_INTEGER);\n // we assume the value has already been removed from the list,\n // so we can just look up the next value which is already at the same idx\n const value = getIteratorValueAtIdx(list[Symbol.iterator](), addIdx)!;\n return {type: ResultType.RemoveAndAdd, removeIdx, value, addIdx, newRange: this.deriveRange(-1, 0)};\n } else if (this.start !== 0) {\n // move the range 1 item up so we still display a viewport full of items\n const newRange = this.deriveRange(-1, 0, 1);\n const addIdx = newRange.start;\n // we assume the value has already been removed from the list,\n // so we can just look up the next value which is already at the same idx\n const value = getIteratorValueAtIdx(list[Symbol.iterator](), addIdx)!;\n return {type: ResultType.RemoveAndAdd, removeIdx, value, addIdx, newRange};\n } else {\n // we can't add at the bottom nor top, already constrained\n return {type: ResultType.Remove, removeIdx, newRange: this.deriveRange(-1, 0)};\n }\n }\n\n private deriveRange(totalLengthInc: number, viewportItemCountDecr: number, startDecr: number = 0): ListRange {\n const start = this.start - startDecr;\n const totalLength = this.totalLength + totalLengthInc;\n // prevent end being larger than totalLength\n const end = Math.min(Math.max(start, this.end - startDecr + viewportItemCountDecr), totalLength);\n return new ListRange(\n start,\n end,\n totalLength,\n this.viewportItemCount\n );\n }\n}\n\nimport {ObservableArray} from \"../../../../observable/list/ObservableArray\";\n\nexport function tests() {\n return {\n \"fromViewport\": assert => {\n const range = ListRange.fromViewport(10, 20, 90, 30);\n assert.equal(range.start, 1);\n assert.equal(range.end, 6);\n assert.equal(range.totalLength, 10);\n },\n \"fromViewport at end\": assert => {\n const itemHeight = 20;\n const range = ListRange.fromViewport(10, itemHeight, 3 * itemHeight, 7 * itemHeight);\n assert.equal(range.start, 7);\n assert.equal(range.end, 10);\n assert.equal(range.totalLength, 10);\n },\n \"fromViewport with not enough items to fill viewport\": assert => {\n const itemHeight = 20;\n const range = ListRange.fromViewport(5, itemHeight, 8 * itemHeight, 0);\n assert.equal(range.start, 0);\n assert.equal(range.end, 5);\n assert.equal(range.totalLength, 5);\n assert.equal(range.length, 5);\n assert.equal(range.viewportItemCount, 8);\n },\n \"expand at start of list\": assert => {\n const range = new ListRange(1, 5, 10);\n const expanded = range.expand(2);\n assert.equal(expanded.start, 0);\n assert.equal(expanded.end, 7);\n assert.equal(expanded.totalLength, 10);\n assert.equal(expanded.length, 7);\n },\n \"expand at end of list\": assert => {\n const range = new ListRange(7, 9, 10);\n const expanded = range.expand(2);\n assert.equal(expanded.start, 5);\n assert.equal(expanded.end, 10);\n assert.equal(expanded.totalLength, 10);\n assert.equal(expanded.length, 5);\n },\n \"expand in middle of list\": assert => {\n const range = new ListRange(4, 6, 10);\n const expanded = range.expand(2);\n assert.equal(expanded.start, 2);\n assert.equal(expanded.end, 8);\n assert.equal(expanded.totalLength, 10);\n assert.equal(expanded.length, 6);\n },\n \"queryAdd with addition before range\": assert => {\n const list = new ObservableArray([\"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(1, 3, list.length);\n let added = false;\n list.subscribe(defaultObserverWith({\n onAdd(idx, value) {\n added = true;\n const result = range.queryAdd(idx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 2,\n addIdx: 1,\n value: \"b\",\n newRange: new ListRange(1, 3, 5)\n });\n }\n }));\n list.insert(0, \"a\");\n assert(added);\n },\n \"queryAdd with addition within range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"d\", \"e\"]);\n const range = new ListRange(1, 3, list.length);\n let added = false;\n list.subscribe(defaultObserverWith({\n onAdd(idx, value) {\n added = true;\n const result = range.queryAdd(idx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 2,\n addIdx: 2,\n value: \"c\",\n newRange: new ListRange(1, 3, 5)\n });\n }\n }));\n list.insert(2, \"c\");\n assert(added);\n },\n \"queryAdd with addition after range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\"]);\n const range = new ListRange(1, 3, list.length);\n let added = false;\n list.subscribe(defaultObserverWith({\n onAdd(idx, value) {\n added = true;\n const result = range.queryAdd(idx, value, list);\n assert.deepEqual(result, {\n type: ResultType.UpdateRange,\n newRange: new ListRange(1, 3, 5)\n });\n }\n }));\n list.insert(4, \"e\");\n assert(added);\n },\n \"queryAdd with too few items to fill viewport grows the range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"d\"]);\n const viewportItemCount = 4;\n const range = new ListRange(0, 3, list.length, viewportItemCount);\n let added = false;\n list.subscribe(defaultObserverWith({\n onAdd(idx, value) {\n added = true;\n const result = range.queryAdd(idx, value, list);\n assert.deepEqual(result, {\n type: ResultType.Add,\n newRange: new ListRange(0, 4, 4),\n addIdx: 2,\n value: \"c\"\n });\n }\n }));\n list.insert(2, \"c\");\n assert(added);\n },\n \"queryRemove with removal before range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(1, 3, list.length);\n let removed = false;\n list.subscribe(defaultObserverWith({\n onRemove(idx) {\n removed = true;\n const result = range.queryRemove(idx, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 1,\n addIdx: 2,\n value: \"d\",\n newRange: new ListRange(1, 3, 4)\n });\n }\n }));\n list.remove(0);\n assert(removed);\n },\n \"queryRemove with removal within range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(1, 3, list.length);\n let removed = false;\n list.subscribe(defaultObserverWith({\n onRemove(idx) {\n removed = true;\n const result = range.queryRemove(idx, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 2,\n addIdx: 2,\n value: \"d\",\n newRange: new ListRange(1, 3, 4)\n });\n assert.equal(list.length, 4);\n }\n }));\n list.remove(2);\n assert(removed);\n },\n \"queryRemove with removal after range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(1, 3, list.length);\n let removed = false;\n list.subscribe(defaultObserverWith({\n onRemove(idx) {\n removed = true;\n const result = range.queryRemove(idx, list);\n assert.deepEqual(result, {\n type: ResultType.UpdateRange,\n newRange: new ListRange(1, 3, 4)\n });\n }\n }));\n list.remove(3);\n assert(removed);\n },\n \"queryRemove at bottom of range moves range one up\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\"]);\n const range = new ListRange(1, 3, list.length);\n let removed = false;\n list.subscribe(defaultObserverWith({\n onRemove(idx) {\n removed = true;\n const result = range.queryRemove(idx, list);\n assert.deepEqual(result, {\n newRange: new ListRange(0, 2, 2),\n type: ResultType.RemoveAndAdd,\n removeIdx: 2,\n addIdx: 0,\n value: \"a\"\n });\n }\n }));\n list.remove(2);\n assert(removed);\n },\n \"queryRemove with range on full length shrinks range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\"]);\n const range = new ListRange(0, 3, list.length);\n let removed = false;\n list.subscribe(defaultObserverWith({\n onRemove(idx) {\n removed = true;\n const result = range.queryRemove(idx, list);\n assert.deepEqual(result, {\n newRange: new ListRange(0, 2, 2, 3),\n type: ResultType.Remove,\n removeIdx: 2,\n });\n }\n }));\n list.remove(2);\n assert(removed);\n },\n \"queryMove with move inside range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(1, 4, list.length);\n let moved = false;\n list.subscribe(defaultObserverWith({\n onMove(fromIdx, toIdx, value) {\n moved = true;\n const result = range.queryMove(fromIdx, toIdx, value, list);\n assert.deepEqual(result, {\n type: ResultType.Move,\n fromIdx: 2,\n toIdx: 3\n });\n }\n }));\n list.move(2, 3);\n assert(moved);\n },\n \"queryMove with move from before to inside range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(2, 5, list.length);\n let moved = false;\n list.subscribe(defaultObserverWith({\n onMove(fromIdx, toIdx, value) {\n moved = true;\n const result = range.queryMove(fromIdx, toIdx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 2,\n addIdx: 3,\n value: \"a\"\n });\n }\n }));\n list.move(0, 3); // move \"a\" to after \"d\"\n assert(moved);\n },\n \"queryMove with move from after to inside range\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(0, 3, list.length);\n let moved = false;\n list.subscribe(defaultObserverWith({\n onMove(fromIdx, toIdx, value) {\n moved = true;\n const result = range.queryMove(fromIdx, toIdx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 2,\n addIdx: 1,\n value: \"e\"\n });\n }\n }));\n list.move(4, 1); // move \"e\" to before \"b\"\n assert(moved);\n },\n \"queryMove with move inside range to after\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(0, 3, list.length);\n let moved = false;\n list.subscribe(defaultObserverWith({\n onMove(fromIdx, toIdx, value) {\n moved = true;\n const result = range.queryMove(fromIdx, toIdx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 1,\n addIdx: 2,\n value: \"d\"\n });\n }\n }));\n list.move(1, 3); // move \"b\" to after \"d\"\n assert(moved);\n },\n \"queryMove with move inside range to before\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(2, 5, list.length);\n let moved = false;\n list.subscribe(defaultObserverWith({\n onMove(fromIdx, toIdx, value) {\n moved = true;\n const result = range.queryMove(fromIdx, toIdx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 3,\n addIdx: 2,\n value: \"b\"\n });\n }\n }));\n list.move(3, 0); // move \"d\" to before \"a\"\n assert(moved);\n },\n \"queryMove with move from before range to after\": assert => {\n const list = new ObservableArray([\"a\", \"b\", \"c\", \"d\", \"e\"]);\n const range = new ListRange(1, 4, list.length);\n let moved = false;\n list.subscribe(defaultObserverWith({\n onMove(fromIdx, toIdx, value) {\n moved = true;\n const result = range.queryMove(fromIdx, toIdx, value, list);\n assert.deepEqual(result, {\n type: ResultType.RemoveAndAdd,\n removeIdx: 1,\n addIdx: 3,\n value: \"e\"\n });\n }\n }));\n list.move(0, 4); // move \"a\" to after \"e\"\n assert(moved);\n },\n // would be good to test here what multiple mutations look like with executing the result of queryXXX\n // on an array, much like we do in the view.\n };\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {tag} from \"./html\";\nimport {removeChildren, mountView} from \"./utils\";\nimport {ListRange, ResultType, AddRemoveResult} from \"./ListRange\";\nimport {ListView, IOptions as IParentOptions} from \"./ListView\";\nimport {IView} from \"./types\";\n\nexport interface IOptions extends IParentOptions {\n itemHeight: number;\n overflowItems?: number;\n}\n\nexport class LazyListView extends ListView {\n private renderRange?: ListRange;\n private height?: number;\n private itemHeight: number;\n private overflowItems: number;\n private scrollContainer?: HTMLElement;\n\n constructor(\n {itemHeight, overflowItems = 20, ...options}: IOptions, \n childCreator: (value: T) => V\n ) {\n super(options, childCreator);\n this.itemHeight = itemHeight;\n this.overflowItems = overflowItems;\n }\n\n handleEvent(e: Event) {\n if (e.type === \"scroll\") {\n this.handleScroll();\n } else {\n super.handleEvent(e);\n }\n }\n\n handleScroll() {\n const visibleRange = this._getVisibleRange();\n // don't contain empty ranges\n // as it will prevent clearing the list\n // once it is scrolled far enough out of view\n if (visibleRange.length !== 0 && !this.renderRange!.contains(visibleRange)) {\n const prevRenderRange = this.renderRange!;\n this.renderRange = visibleRange.expand(this.overflowItems);\n this.renderUpdate(prevRenderRange, this.renderRange);\n }\n }\n \n // override\n async loadList() {\n /*\n Wait two frames for the return from mount() to be inserted into DOM.\n This should be enough, but if this gives us trouble we can always use\n MutationObserver.\n */\n await new Promise(r => requestAnimationFrame(r));\n await new Promise(r => requestAnimationFrame(r));\n\n if (!this._list) {\n return;\n }\n this._subscription = this._list.subscribe(this);\n const visibleRange = this._getVisibleRange();\n this.renderRange = visibleRange.expand(this.overflowItems);\n this._childInstances = [];\n this.reRenderFullRange(this.renderRange);\n }\n\n private _getVisibleRange() {\n const {clientHeight, scrollTop} = this.root()!;\n if (clientHeight === 0) {\n throw new Error(\"LazyListView height is 0\");\n }\n return ListRange.fromViewport(this._list.length, this.itemHeight, clientHeight, scrollTop);\n }\n\n private reRenderFullRange(range: ListRange) {\n removeChildren(this._listElement!);\n const fragment = document.createDocumentFragment();\n const it = this._list[Symbol.iterator]();\n this._childInstances!.length = 0;\n range.forEachInIterator(it, item => {\n const child = this._childCreator(item);\n this._childInstances!.push(child);\n fragment.appendChild(mountView(child, this._mountArgs));\n });\n this._listElement!.appendChild(fragment);\n this.adjustPadding(range);\n }\n\n private renderUpdate(prevRange: ListRange, newRange: ListRange) {\n if (newRange.intersects(prevRange)) {\n // remove children in reverse order so child index isn't affected by previous removals\n for (const idxInList of prevRange.reverseIterable()) {\n if (!newRange.containsIndex(idxInList)) {\n const localIdx = idxInList - prevRange.start;\n this.removeChild(localIdx);\n }\n }\n // use forEachInIterator instead of for loop as we need to advance\n // the list iterator to the start of the range first\n newRange.forEachInIterator(this._list[Symbol.iterator](), (item, idxInList) => {\n if (!prevRange.containsIndex(idxInList)) {\n const localIdx = idxInList - newRange.start;\n this.addChild(localIdx, item);\n }\n });\n this.adjustPadding(newRange);\n } else {\n this.reRenderFullRange(newRange);\n }\n }\n\n private adjustPadding(range: ListRange) {\n const paddingTop = range.start * this.itemHeight;\n const paddingBottom = (range.totalLength - range.end) * this.itemHeight;\n const style = this._listElement!.style;\n style.paddingTop = `${paddingTop}px`;\n style.paddingBottom = `${paddingBottom}px`;\n }\n\n mount() {\n const listElement = super.mount();\n this.scrollContainer = tag.div({className: \"LazyListParent\"}, listElement) as HTMLElement;\n this.scrollContainer.addEventListener(\"scroll\", this);\n return this.scrollContainer;\n }\n\n unmount() {\n this.root()!.removeEventListener(\"scroll\", this);\n this.scrollContainer = undefined;\n super.unmount();\n }\n\n root(): Element | undefined {\n return this.scrollContainer;\n }\n\n private get _listElement(): HTMLElement | undefined {\n return super.root() as HTMLElement | undefined;\n }\n\n onAdd(idx: number, value: T) {\n const result = this.renderRange!.queryAdd(idx, value, this._list);\n this.applyRemoveAddResult(result);\n }\n\n onRemove(idx: number, value: T) {\n const result = this.renderRange!.queryRemove(idx, this._list);\n this.applyRemoveAddResult(result);\n }\n\n onMove(fromIdx: number, toIdx: number, value: T) {\n const result = this.renderRange!.queryMove(fromIdx, toIdx, value, this._list);\n if (result) {\n if (result.type === ResultType.Move) {\n this.moveChild(\n this.renderRange!.toLocalIndex(result.fromIdx),\n this.renderRange!.toLocalIndex(result.toIdx)\n );\n } else {\n this.applyRemoveAddResult(result);\n }\n }\n }\n\n onUpdate(i: number, value: T, params: any) {\n if (this.renderRange!.containsIndex(i)) {\n this.updateChild(this.renderRange!.toLocalIndex(i), value, params);\n }\n }\n\n private applyRemoveAddResult(result: AddRemoveResult) {\n // order is important here, the new range can have a different start\n if (result.type === ResultType.Remove || result.type === ResultType.RemoveAndAdd) {\n this.removeChild(this.renderRange!.toLocalIndex(result.removeIdx));\n }\n if (result.newRange) {\n this.renderRange = result.newRange;\n this.adjustPadding(this.renderRange)\n }\n if (result.type === ResultType.Add || result.type === ResultType.RemoveAndAdd) {\n this.addChild(this.renderRange!.toLocalIndex(result.addIdx), result.value);\n }\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {AvatarView} from \"../../AvatarView.js\";\n\nexport class MemberTileView extends TemplateView {\n render(t, vm) {\n return t.li({ className: \"MemberTileView\" },\n t.a({ href: vm.detailsUrl },\n [\n t.view(new AvatarView(vm, 32)),\n t.div({ className: \"MemberTileView_name\" }, (vm) => vm.name),\n ])\n );\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {LazyListView} from \"../../general/LazyListView\";\nimport {MemberTileView} from \"./MemberTileView.js\";\nimport {TemplateView} from \"../../general/TemplateView\";\n\nexport class MemberListView extends TemplateView {\n render(t, vm) {\n const list = new LazyListView({\n list: vm.memberTileViewModels,\n className: \"MemberListView__list\",\n itemHeight: 40\n }, tileViewModel => new MemberTileView(tileViewModel));\n return t.div({ className: \"MemberListView\" }, [\n t.div({ className: \"MemberListView__invite-container\" }, [\n t.button(\n {\n className: \"MemberListView__invite-btn button-action primary\",\n onClick: () => vm.openInvitePanel(),\n },\n vm.i18n`Invite to this room`\n ),\n ]),\n t.view(list),\n ]);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AvatarView} from \"../../AvatarView.js\";\nimport {TemplateView} from \"../../general/TemplateView\";\n\nexport class MemberDetailsView extends TemplateView {\n render(t, vm) {\n const securityNodes = [\n t.p(vm.isEncrypted ?\n vm.i18n`Messages in this room are end-to-end encrypted.` :\n vm.i18n`Messages in this room are not end-to-end encrypted.`),\n ]\n\n if (vm.features.crossSigning) {\n securityNodes.push(t.div({className: \"MemberDetailsView_shield_container\"}, [\n t.span({className: vm => `MemberDetailsView_shield_${vm.trustShieldColor}`}),\n t.p({className: \"MemberDetailsView_shield_description\"}, vm => vm.trustDescription)\n ]));\n }\n\n return t.div({className: \"MemberDetailsView\"},\n [ t.view(new AvatarView(vm, 128)),\n t.div({className: \"MemberDetailsView_name\"}, t.h2(vm => vm.name)),\n t.div({className: \"MemberDetailsView_id\"}, vm.userId),\n this._createSection(t, vm.i18n`Role`, vm => vm.role),\n this._createSection(t, vm.i18n`Security`, securityNodes),\n this._createOptions(t, vm)\n ]);\n }\n\n _createSection(t, label, value) {\n return t.div({ className: \"MemberDetailsView_section\" },\n [\n t.div({className: \"MemberDetailsView_label\"}, label),\n t.div({className: \"MemberDetailsView_value\"}, value)\n ]);\n }\n\n _createOptions(t, vm) {\n const options = [\n t.a({href: vm.linkToUser, target: \"_blank\", rel: \"noopener\"}, vm.i18n`Open Link to User`),\n t.button({className: \"text\", onClick: () => vm.openDirectMessage()}, vm.i18n`Open direct message`)\n ];\n if (vm.features.crossSigning) {\n if (vm.canVerifyUser) {\n options.push(t.button({ className: \"text\", onClick: () => vm.verifyUser() }, vm.i18n`Verify`));\n }\n const onClick = () => {\n if (confirm(\"You don't want to do this with any account but a test account. This will cross-sign this user without verifying their keys first. You won't be able to undo this apart from resetting your cross-signing keys.\")) {\n vm.signUser();\n }\n };\n options.push(t.button({className: \"text\", onClick}, vm.i18n`Cross-sign user (DO NOT USE, TESTING ONLY)`))\n }\n return t.div({ className: \"MemberDetailsView_section\" },\n [\n t.div({className: \"MemberDetailsView_label\"}, vm.i18n`Options`),\n t.div({className: \"MemberDetailsView_options\"}, options)\n ]);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport {spinner} from \"../../../common.js\";\nimport {WaitingForOtherUserViewModel} from \"../../../../../../domain/session/verification/stages/WaitingForOtherUserViewModel\";\n\nexport class WaitingForOtherUserView extends TemplateView {\n render(t: Builder, vm: WaitingForOtherUserViewModel) {\n return t.div({ className: \"WaitingForOtherUserView\" }, [\n t.div({ className: \"WaitingForOtherUserView__heading\" }, [\n spinner(t),\n t.h2(\n { className: \"WaitingForOtherUserView__title\" },\n vm.title,\n ),\n ]),\n t.p({ className: \"WaitingForOtherUserView__description\" },\n vm.description,\n ),\n t.div({ className: \"WaitingForOtherUserView__actions\" },\n t.button({\n className: {\n \"button-action\": true,\n \"primary\": true,\n \"destructive\": true,\n },\n onclick: () => vm.cancel(),\n }, \"Cancel\")\n ),\n ]);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport {VerificationCancelledViewModel} from \"../../../../../../domain/session/verification/stages/VerificationCancelledViewModel\";\n\nexport class VerificationCancelledView extends TemplateView {\n render(t: Builder, vm: VerificationCancelledViewModel) {\n return t.div(\n {\n className: \"VerificationCancelledView\",\n },\n [\n t.h2(\n { className: \"VerificationCancelledView__title\" },\n vm.title,\n ),\n t.p(\n { className: \"VerificationCancelledView__description\" },\n vm.description,\n ),\n t.div({ className: \"VerificationCancelledView__actions\" }, [\n t.button({\n className: {\n \"button-action\": true,\n \"primary\": true,\n },\n onclick: () => vm.dismiss(),\n }, \"Got it\")\n ]),\n ]\n );\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport {spinner} from \"../../../common.js\"\nimport type {SelectMethodViewModel} from \"../../../../../../domain/session/verification/stages/SelectMethodViewModel\";\n\nexport class SelectMethodView extends TemplateView {\n render(t: Builder) {\n return t.div({ className: \"SelectMethodView\" }, [\n t.map(vm => vm.hasProceeded, (hasProceeded, t, vm) => {\n if (hasProceeded) {\n return spinner(t);\n }\n else return t.div([\n t.div({ className: \"SelectMethodView__heading\" }, [\n t.h2( { className: \"SelectMethodView__title\" }, this.getHeading(t, vm)),\n ]),\n t.p({ className: \"SelectMethodView__description\" }, this.getSubheading(vm)),\n t.div({ className: \"SelectMethodView__actions\" }, [\n t.button(\n {\n className: {\n \"button-action\": true,\n primary: true,\n destructive: true,\n },\n onclick: () => vm.cancel(),\n },\n \"Cancel\"\n ),\n t.button(\n {\n className: {\n \"button-action\": true,\n primary: true,\n },\n onclick: () => vm.proceed(),\n },\n \"Proceed\"\n ),\n ]),\n ]);\n }),\n ]);\n }\n\n getHeading(t: Builder, vm: SelectMethodViewModel) {\n if (vm.isCrossSigningAnotherUser) {\n return [vm.i18n`Verify user `, t.span({\n className: \"SelectMethodView__name\"\n }, vm.otherUserId), vm.i18n` by comparing emojis?`];\n } else {\n return [vm.i18n`Verify device`, t.span({\n className: \"SelectMethodView__name\"\n }, vm.deviceName), vm.i18n` by comparing emojis?`];\n }\n }\n\n getSubheading(vm: SelectMethodViewModel): string {\n if (vm.isCrossSigningAnotherUser) {\n return vm.i18n`You are about to verify user (${vm.otherUserId}) by comparing emojis.`;\n } else {\n return vm.i18n`You are about to verify your other device (${vm.deviceName}) by comparing emojis.`;\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport {spinner} from \"../../../common.js\"\nimport type {VerifyEmojisViewModel} from \"../../../../../../domain/session/verification/stages/VerifyEmojisViewModel\";\n\nexport class VerifyEmojisView extends TemplateView {\n render(t: Builder, vm: VerifyEmojisViewModel) {\n const emojiList = vm.emojis.reduce((acc, [emoji, name]) => {\n const e = t.div({ className: \"EmojiContainer\" }, [\n t.div({ className: \"EmojiContainer__emoji\" }, emoji),\n t.div({ className: \"EmojiContainer__name\" }, name),\n ]);\n acc.push(e);\n return acc;\n }, [] as any);\n const emojiCollection = t.div({ className: \"EmojiCollection\" }, emojiList);\n return t.div({ className: \"VerifyEmojisView\" }, [\n t.div({ className: \"VerifyEmojisView__heading\" }, [\n t.h2(\n { className: \"VerifyEmojisView__title\" },\n vm.i18n`Do the emojis match?`\n ),\n ]),\n t.p(\n { className: \"VerifyEmojisView__description\" },\n vm.i18n`Confirm the emoji below are displayed on both devices, in the same order:`\n ),\n t.div({ className: \"VerifyEmojisView__emojis\" }, emojiCollection),\n t.map(vm => vm.isWaiting, (isWaiting, t, vm) => {\n if (isWaiting) {\n return t.div({ className: \"VerifyEmojisView__waiting\" }, [\n spinner(t),\n t.span(vm.i18n`Waiting for you to verify on your other device`),\n ]);\n }\n else {\n return t.div({ className: \"VerifyEmojisView__actions\" }, [\n t.button(\n {\n className: {\n \"button-action\": true,\n primary: true,\n destructive: true,\n },\n onclick: () => vm.setEmojiMatch(false),\n },\n vm.i18n`They don't match`\n ),\n t.button(\n {\n className: {\n \"button-action\": true,\n primary: true,\n },\n onclick: () => vm.setEmojiMatch(true),\n },\n vm.i18n`They match`\n ),\n ]);\n }\n })\n ]);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport type {VerificationCompleteViewModel} from \"../../../../../../domain/session/verification/stages/VerificationCompleteViewModel\";\n\nexport class VerificationCompleteView extends TemplateView {\n render(t: Builder, vm: VerificationCompleteViewModel) {\n return t.div({ className: \"VerificationCompleteView\" }, [\n t.div({className: \"VerificationCompleteView__icon\"}),\n t.div({ className: \"VerificationCompleteView__heading\" }, [\n t.h2(\n { className: \"VerificationCompleteView__title\" },\n vm.i18n`Verification completed successfully!`\n ),\n ]),\n t.p(\n { className: \"VerificationCompleteView__description\" }, vm.verificationSuccessfulMessage),\n t.div({ className: \"VerificationCompleteView__actions\" }, [\n t.button({\n className: {\n \"button-action\": true,\n \"primary\": true,\n },\n onclick: () => vm.dismiss(),\n }, \"Got it\")\n ]),\n ]);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport type {MissingKeysViewModel} from \"../../../../../../domain/session/verification/stages/MissingKeysViewModel\";\n\nexport class MissingKeysView extends TemplateView {\n render(t: Builder, vm: MissingKeysViewModel) {\n return t.div(\n {\n className: \"MissingKeysView\",\n },\n [\n t.h2(\n { className: \"MissingKeysView__heading\" },\n vm.i18n`Verification is currently not possible!`\n ),\n t.p(\n { className: \"MissingKeysView__description\" },\n vm.i18n`Some keys needed for verification are missing. You can fix this by enabling key backup in settings.` \n ),\n t.div({ className: \"MissingKeysView__actions\" }, [\n t.button({\n className: {\n \"button-action\": true,\n \"primary\": true,\n },\n onclick: () => vm.gotoSettings(),\n }, \"Open Settings\")\n ]),\n ]\n );\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, InlineTemplateView, TemplateView} from \"../../general/TemplateView\";\nimport {DeviceVerificationViewModel} from \"../../../../../domain/session/verification/DeviceVerificationViewModel\";\nimport {WaitingForOtherUserView} from \"./stages/WaitingForOtherUserView\";\nimport {VerificationCancelledView} from \"./stages/VerificationCancelledView\";\nimport {SelectMethodView} from \"./stages/SelectMethodView\";\nimport {VerifyEmojisView} from \"./stages/VerifyEmojisView\";\nimport {VerificationCompleteView} from \"./stages/VerificationCompleteView\";\nimport {MissingKeysView} from \"./stages/MissingKeysView\";\nimport {spinner} from \"../../common.js\";\n\nexport class DeviceVerificationView extends TemplateView {\n render(t: Builder, vm: DeviceVerificationViewModel) {\n return t.div({\n className: {\n \"middle\": !vm.isHappeningInRoom,\n \"DeviceVerificationView\": true,\n }\n }, [\n t.mapView(vm => vm.currentStageViewModel, (vm) => {\n switch (vm?.kind) {\n case \"waiting-for-user\": return new WaitingForOtherUserView(vm);\n case \"verification-cancelled\": return new VerificationCancelledView(vm);\n case \"select-method\": return new SelectMethodView(vm);\n case \"verify-emojis\": return new VerifyEmojisView(vm);\n case \"verification-completed\": return new VerificationCompleteView(vm);\n case \"keys-missing\": return new MissingKeysView(vm);\n default: return new InlineTemplateView(vm, () => spinner(t));\n }\n })\n ])\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../general/TemplateView\";\nimport {ErrorView} from \"../../general/ErrorView\";\nimport type {InvitePanelViewModel} from \"../../../../../domain/session/rightpanel/InvitePanelViewModel\";\n\nexport class InvitePanelView extends TemplateView {\n render(t: Builder, vm: InvitePanelViewModel) {\n const input = t.input({\n className: \"InvitePanelView__input\",\n type: \"text\",\n placeholder: \"Enter user-id of user\",\n onkeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\") {\n vm.invite((input as HTMLInputElement).value);\n }\n }\n });\n return t.div({ className: \"InvitePanelView\" }, [\n t.h3({ className: \"InvitePanelView__heading\" },\n (vm: InvitePanelViewModel) => vm.i18n`Invite to ${vm.roomName}`\n ),\n t.div({ className: \"InvitePanelView__form\" }, [\n input,\n t.button({\n className: \"InvitePanelView__btn button-action primary\",\n onClick: () => vm.invite((input as HTMLInputElement).value),\n }, \"Invite\"),\n ]),\n t.div({ className: \"InvitePanelView__error\" }, [\n t.ifView(vm => !!vm.errorViewModel, vm => new ErrorView(vm.errorViewModel!)),\n ]),\n ]);\n }\n\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../general/TemplateView\";\nimport {RoomDetailsView} from \"./RoomDetailsView.js\";\nimport {MemberListView} from \"./MemberListView.js\";\nimport {LoadingView} from \"../../general/LoadingView.js\";\nimport {MemberDetailsView} from \"./MemberDetailsView.js\";\nimport {DeviceVerificationView} from \"../verification/DeviceVerificationView\";\nimport {InvitePanelView} from \"./InvitePanelView\";\n\nexport class RightPanelView extends TemplateView {\n render(t) {\n return t.div({ className: \"RightPanelView\" },\n [\n t.ifView(vm => vm.activeViewModel, vm => new ButtonsView(vm)),\n t.mapView(vm => vm.activeViewModel, vm => this._viewFromType(vm))\n ]\n );\n }\n\n _viewFromType(vm) {\n const type = vm?.type;\n switch (type) {\n case \"room-details\":\n return new RoomDetailsView(vm);\n case \"member-list\":\n return new MemberListView(vm);\n case \"member-details\":\n return new MemberDetailsView(vm);\n case \"invite\":\n return new InvitePanelView(vm);\n case \"verification\":\n return new DeviceVerificationView(vm);\n default:\n return new LoadingView();\n }\n }\n}\n\nclass ButtonsView extends TemplateView {\n render(t, vm) {\n return t.div({ className: \"RightPanelView_buttons\" },\n [\n t.button({\n className: {\n \"back\": true,\n \"button-utility\": true,\n \"hide\": (vm) => !vm.activeViewModel.shouldShowBackButton\n }, onClick: () => vm.showPreviousPanel()}),\n t.button({className: \"close button-utility\", onClick: () => vm.closePanel()})\n ]);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ListView} from \"../../../general/ListView\";\nimport {TemplateView} from \"../../../general/TemplateView\";\n\nexport class ReactionsView extends ListView {\n constructor(reactionsViewModel) {\n const options = {\n className: \"Timeline_messageReactions\",\n tagName: \"div\",\n list: reactionsViewModel.reactions,\n onItemClick: reactionView => reactionView.onClick(),\n }\n super(options, reactionVM => new ReactionView(reactionVM));\n }\n}\n\nclass ReactionView extends TemplateView {\n render(t, vm) {\n return t.button({\n className: {\n active: vm => vm.isActive,\n pending: vm => vm.isPending\n },\n }, [vm.key, \" \", vm => `${vm.count}`]);\n }\n\n onClick() {\n this.value.toggle();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {renderStaticAvatar} from \"../../../avatar\";\nimport {tag} from \"../../../general/html\";\nimport {mountView} from \"../../../general/utils\";\nimport {TemplateView} from \"../../../general/TemplateView\";\nimport {Popup} from \"../../../general/Popup.js\";\nimport {Menu} from \"../../../general/Menu.js\";\nimport {ReactionsView} from \"./ReactionsView.js\";\n\nexport class BaseMessageView extends TemplateView {\n constructor(value, viewClassForTile, renderFlags, tagName = \"li\") {\n super(value);\n this._menuPopup = null;\n this._tagName = tagName;\n this._viewClassForTile = viewClassForTile;\n // TODO An enum could be nice to make code easier to read at call sites.\n this._renderFlags = renderFlags;\n }\n\n get _interactive() { return this._renderFlags?.interactive ?? true; }\n get _isReplyPreview() { return this._renderFlags?.reply; }\n\n render(t, vm) {\n const children = [this.renderMessageBody(t, vm)];\n if (this._interactive) {\n children.push(t.button({className: \"Timeline_messageOptions\"}, \"⋯\"));\n }\n const li = t.el(this._tagName, {\n className: {\n \"Timeline_message\": true,\n own: vm.isOwn,\n unsent: vm.isUnsent,\n unverified: vm => vm.isUnverified,\n disabled: !this._interactive,\n continuation: vm => vm.isContinuation,\n },\n 'data-event-id': vm.eventId\n }, children);\n // given that there can be many tiles, we don't add\n // unneeded DOM nodes in case of a continuation, and we add it\n // with a side-effect binding to not have to create sub views,\n // as the avatar or sender doesn't need any bindings or event handlers.\n // don't use `t` from within the side-effect callback\n t.mapSideEffect(vm => vm.isContinuation, (isContinuation, wasContinuation) => {\n if (isContinuation && wasContinuation === false) {\n li.removeChild(li.querySelector(\".Timeline_messageAvatar\"));\n li.removeChild(li.querySelector(\".Timeline_messageSender\"));\n } else if (!isContinuation && !this._isReplyPreview) {\n const avatar = tag.a({href: vm.memberPanelLink, className: \"Timeline_messageAvatar\"}, [renderStaticAvatar(vm, 30)]);\n const sender = tag.div(\n {\n className: `Timeline_messageSender usercolor${vm.avatarColorNumber}`,\n title: vm.sender,\n },\n vm.displayName,\n );\n li.insertBefore(avatar, li.firstChild);\n li.insertBefore(sender, li.firstChild);\n }\n });\n // similarly, we could do this with a simple ifView,\n // but that adds a comment node to all messages without reactions\n let reactionsView = null;\n t.mapSideEffect(vm => vm.reactions, reactions => {\n if (reactions && this._interactive && !reactionsView) {\n reactionsView = new ReactionsView(reactions);\n this.addSubView(reactionsView);\n li.appendChild(mountView(reactionsView));\n } else if (!reactions && reactionsView) {\n li.removeChild(reactionsView.root());\n reactionsView.unmount();\n this.removeSubView(reactionsView);\n reactionsView = null;\n }\n });\n return li;\n }\n\n /* This is called by the parent ListView, which just has 1 listener for the whole list */\n onClick(evt) {\n if (evt.target.className === \"Timeline_messageOptions\") {\n this._toggleMenu(evt.target);\n }\n }\n\n _toggleMenu(button) {\n if (this._menuPopup && this._menuPopup.isOpen) {\n this._menuPopup.close();\n } else {\n const options = this.createMenuOptions(this.value);\n if (!options.length) {\n return;\n }\n this.root().classList.add(\"menuOpen\");\n const onClose = () => this.root().classList.remove(\"menuOpen\");\n this._menuPopup = new Popup(new Menu(options), onClose);\n this._menuPopup.trackInTemplateView(this);\n this._menuPopup.showRelativeTo(button, 2);\n }\n }\n\n createMenuOptions(vm) {\n const options = [];\n if (vm.canReact && vm.shape !== \"redacted\" && !vm.isPending) {\n options.push(new QuickReactionsMenuOption(vm));\n options.push(Menu.option(vm.i18n`Reply`, () => vm.startReply()));\n }\n if (vm.canAbortSending) {\n options.push(Menu.option(vm.i18n`Cancel`, () => vm.abortSending()));\n } else if (vm.canRedact) {\n options.push(Menu.option(vm.i18n`Delete`, () => vm.redact()).setDestructive());\n }\n options.push(Menu.option(vm.i18n`Copy matrix.to permalink`, () => vm.copyPermalink()));\n return options;\n }\n\n renderMessageBody() {}\n}\n\nclass QuickReactionsMenuOption {\n constructor(vm) {\n this._vm = vm;\n }\n toDOM(t) {\n const emojiButtons = [\"👍\", \"👎\", \"😄\", \"🎉\", \"😕\", \"❤️\", \"🚀\", \"👀\"].map(emoji => {\n return t.button({onClick: () => this._vm.react(emoji)}, emoji);\n });\n const customButton = t.button({onClick: () => {\n const key = prompt(\"Enter your reaction (emoji)\");\n if (key) {\n this._vm.react(key);\n }\n }}, \"…\");\n return t.li({className: \"quick-reactions\"}, [...emojiButtons, customButton]);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {renderStaticAvatar} from \"../../../avatar\";\nimport {TemplateView} from \"../../../general/TemplateView\";\n\nexport class ReplyPreviewView extends TemplateView {\n constructor(vm, viewClassForTile) {\n super(vm);\n this._viewClassForTile = viewClassForTile;\n }\n render(t, vm) {\n const TileView = this._viewClassForTile(vm);\n if (!TileView) {\n throw new Error(`Shape ${vm.shape} is unrecognized.`)\n }\n const view = new TileView(vm, this._viewClassForTile, { reply: true, interactive: false });\n return t.div(\n { className: \"ReplyPreviewView\" },\n t.blockquote([\n t.a({ className: \"link\", target: \"_blank\", href: vm.permaLink }, \"In reply to\"),\n t.a({ className: \"pill\", target: \"_blank\", href: vm.senderProfileLink }, [\n renderStaticAvatar(vm, 12, undefined, true),\n vm.displayName,\n ]),\n t.br(),\n t.view(view),\n ])\n );\n }\n}\n\nexport class ReplyPreviewError extends TemplateView {\n render(t) {\n return t.blockquote({ className: \"ReplyPreviewView\" }, [\n t.div({ className: \"Timeline_messageBody statusMessage\" }, \"This reply could not be found.\")\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {tag, text} from \"../../../general/html\";\nimport {BaseMessageView} from \"./BaseMessageView.js\";\nimport {ReplyPreviewError, ReplyPreviewView} from \"./ReplyPreviewView.js\";\n\nexport class TextMessageView extends BaseMessageView {\n renderMessageBody(t, vm) {\n const time = t.time({className: {hidden: !vm.time}}, vm.time);\n const container = t.div({\n className: {\n \"Timeline_messageBody\": true,\n statusMessage: vm => vm.shape === \"message-status\",\n }\n }, t.mapView(vm => vm.replyTile, replyTile => {\n if (this._isReplyPreview) {\n // if this._isReplyPreview = true, this is already a reply preview, don't nest replies for now.\n return null;\n }\n else if (vm.isReply && !replyTile) {\n return new ReplyPreviewError();\n }\n else if (replyTile) {\n return new ReplyPreviewView(replyTile, this._viewClassForTile);\n }\n else {\n return null;\n }\n }));\n\n // exclude comment nodes as they are used by t.map and friends for placeholders\n const shouldRemove = (element) => element?.nodeType !== Node.COMMENT_NODE && element.className !== \"ReplyPreviewView\";\n\n t.mapSideEffect(vm => vm.body, body => {\n while (shouldRemove(container.lastChild)) {\n container.removeChild(container.lastChild);\n }\n for (const part of body.parts) {\n container.appendChild(renderPart(part));\n }\n container.appendChild(time);\n });\n\n return container;\n }\n}\n\nfunction renderList(listBlock) {\n const items = listBlock.items.map(item => tag.li(renderParts(item)));\n const start = listBlock.startOffset;\n if (start) {\n return tag.ol({ start }, items);\n } else {\n return tag.ul(items);\n }\n}\n\nfunction renderImage(imagePart) {\n const attributes = { src: imagePart.src };\n if (imagePart.width) { attributes.width = imagePart.width }\n if (imagePart.height) { attributes.height = imagePart.height }\n if (imagePart.alt) { attributes.alt = imagePart.alt }\n if (imagePart.title) { attributes.title = imagePart.title }\n return tag.img(attributes);\n}\n\nfunction renderPill(pillPart) {\n // The classes and structure are borrowed from avatar.js;\n // We don't call renderStaticAvatar because that would require\n // an intermediate object that has getAvatarUrl etc.\n const classes = `avatar size-12 usercolor${pillPart.avatarColorNumber}`;\n const avatar = tag.div({class: classes}, text(pillPart.avatarInitials));\n const children = renderParts(pillPart.children);\n children.unshift(avatar);\n return tag.a({class: \"pill\", href: pillPart.href, rel: \"noopener\", target: \"_blank\"}, children);\n}\n\nfunction renderTable(tablePart) {\n const children = [];\n if (tablePart.head) {\n const headers = tablePart.head\n .map(cell => tag.th(renderParts(cell)));\n children.push(tag.thead(tag.tr(headers)))\n }\n const rows = [];\n for (const row of tablePart.body) {\n const data = row.map(cell => tag.td(renderParts(cell)));\n rows.push(tag.tr(data));\n }\n children.push(tag.tbody(rows));\n return tag.table(children);\n}\n\n/**\n * Map from part to function that outputs DOM for the part\n */\nconst formatFunction = {\n header: headerBlock => tag[\"h\" + Math.min(6,headerBlock.level)](renderParts(headerBlock.inlines)),\n codeblock: codeBlock => tag.pre(tag.code(text(codeBlock.text))),\n table: tableBlock => renderTable(tableBlock),\n code: codePart => tag.code(text(codePart.text)),\n text: textPart => text(textPart.text),\n link: linkPart => tag.a({href: linkPart.url, className: \"link\", target: \"_blank\", rel: \"noopener\" }, renderParts(linkPart.inlines)),\n pill: renderPill,\n format: formatPart => tag[formatPart.format](renderParts(formatPart.children)),\n rule: () => tag.hr(),\n list: renderList,\n image: renderImage,\n newline: () => tag.br()\n};\n\nfunction renderPart(part) {\n const f = formatFunction[part.type];\n if (!f) {\n return text(`[unknown part type ${part.type}]`);\n }\n return f(part);\n}\n\nfunction renderParts(parts) {\n return Array.from(parts, renderPart);\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageView} from \"./BaseMessageView.js\";\nimport {Menu} from \"../../../general/Menu.js\";\n\nexport class BaseMediaView extends BaseMessageView {\n renderMessageBody(t, vm) {\n const heightRatioPercent = (vm.height / vm.width) * 100; \n let spacerStyle = `padding-top: ${heightRatioPercent}%;`;\n if (vm.platform.isIE11) {\n // preserving aspect-ratio in a grid with padding percentages\n // does not work in IE11, so we assume people won't use it\n // with viewports narrower than 400px where thumbnails will get\n // scaled. If they do, the thumbnail will still scale, but\n // there will be whitespace underneath the picture\n // An alternative would be to use position: absolute but that\n // can slow down rendering, and was bleeding through the lightbox.\n spacerStyle = `height: ${vm.height}px`;\n }\n const children = [\n t.div({className: \"spacer\", style: spacerStyle}),\n this.renderMedia(t, vm),\n t.time(vm.time),\n ];\n const status = t.div({\n className: {\n status: true,\n hidden: vm => !vm.status\n },\n }, vm => vm.status);\n children.push(status);\n if (vm.isPending) {\n const progress = t.progress({\n min: 0,\n max: 100,\n value: vm => vm.uploadPercentage,\n className: {hidden: vm => !vm.isUploading}\n });\n children.push(progress);\n }\n return t.div({className: \"Timeline_messageBody\"}, [\n t.div({className: \"media\", style: `max-width: ${vm.width}px`, \"data-testid\": \"media\"}, children),\n t.if(vm => vm.error, t => t.p({className: \"error\"}, vm.error))\n ]);\n }\n\n createMenuOptions(vm) {\n const options = super.createMenuOptions(vm);\n if (!vm.isPending) {\n let label;\n switch (vm.shape) {\n case \"image\": label = vm.i18n`Download image`; break;\n case \"video\": label = vm.i18n`Download video`; break;\n default: label = vm.i18n`Download media`; break;\n }\n options.push(Menu.option(label, () => vm.downloadMedia()));\n }\n return options;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMediaView} from \"./BaseMediaView.js\";\n\nexport class ImageView extends BaseMediaView {\n renderMedia(t, vm) {\n const img = t.img({\n src: vm => vm.thumbnailUrl,\n alt: vm => vm.label,\n title: vm => vm.label,\n style: `max-width: ${vm.width}px; max-height: ${vm.height}px;`\n });\n return vm.isPending || !vm.lightboxUrl ? img : t.a({href: vm.lightboxUrl}, img);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function domEventAsPromise(element: HTMLElement, successEvent: string): Promise {\n return new Promise((resolve, reject) => {\n let detach;\n const handleError = evt => {\n detach();\n reject(evt.target.error);\n };\n const handleSuccess = () => {\n detach();\n resolve();\n };\n detach = () => {\n element.removeEventListener(successEvent, handleSuccess);\n element.removeEventListener(\"error\", handleError);\n };\n element.addEventListener(successEvent, handleSuccess);\n element.addEventListener(\"error\", handleError);\n });\n}\n\n// Copies the given text to clipboard and returns a boolean of whether the action was\n// successful\nexport async function copyPlaintext(text: string): Promise {\n try {\n if (navigator?.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return true;\n } else {\n const textArea = document.createElement(\"textarea\");\n textArea.value = text;\n\n // Avoid scrolling to bottom\n textArea.style.top = \"0\";\n textArea.style.left = \"0\";\n textArea.style.position = \"fixed\";\n\n document.body.appendChild(textArea);\n\n const selection = document.getSelection();\n if (!selection) {\n console.error('copyPlaintext: Unable to copy text to clipboard in fallback mode because `selection` was null/undefined');\n return false;\n }\n\n const range = document.createRange();\n // range.selectNodeContents(textArea);\n range.selectNode(textArea);\n selection.removeAllRanges();\n selection.addRange(range);\n\n const successful = document.execCommand(\"copy\");\n selection.removeAllRanges();\n document.body.removeChild(textArea);\n if(!successful) {\n console.error('copyPlaintext: Unable to copy text to clipboard in fallback mode because the `copy` command is unsupported or disabled');\n }\n return successful;\n }\n } catch (err) {\n console.error(\"copyPlaintext: Ran into an error\", err);\n }\n return false;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMediaView} from \"./BaseMediaView.js\";\nimport {domEventAsPromise} from \"../../../../dom/utils\";\n\nexport class VideoView extends BaseMediaView {\n renderMedia(t) {\n const video = t.video({\n // provide empty data url if video is not decrypted yet.\n // Chrome/Electron need this to enable the play button.\n src: vm => vm.videoUrl || `data:${vm.mimeType},`,\n title: vm => vm.label,\n controls: true,\n preload: \"none\",\n poster: vm => vm.thumbnailUrl,\n onPlay: this._onPlay.bind(this),\n style: vm => `max-width: ${vm.width}px; max-height: ${vm.height}px;${vm.isPending ? \"z-index: -1\": \"\"}`\n });\n\n video.addEventListener(\"error\", this._onError.bind(this));\n\n return video;\n }\n\n async _onPlay(evt) {\n const vm = this.value;\n // download and decrypt the video if needed,\n if (!vm.videoUrl) {\n try {\n const video = evt.target;\n // this will trigger the src to update\n await vm.loadVideo();\n // important to only listen for this after src has changed,\n // or we get the error for the placeholder data url\n const loadPromise = domEventAsPromise(video, \"loadeddata\");\n // now, reload the video and play\n video.load();\n await loadPromise;\n video.play();\n } catch (err) {/* errors are already caught in error event handler */}\n } \n }\n\n _onError(evt) {\n const vm = this.value;\n const video = evt.target;\n const err = video.error;\n if (err instanceof window.MediaError && err.code === 4) {\n if (!video.src.startsWith(\"data:\")) {\n vm.setViewError(new Error(`this browser does not support videos of type ${vm.mimeType}.`));\n } else {\n // ignore placeholder url failing to load\n return;\n }\n } else {\n vm.setViewError(err);\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageView} from \"./BaseMessageView.js\";\n\nexport class FileView extends BaseMessageView {\n renderMessageBody(t, vm) {\n const children = [];\n if (vm.isPending) {\n children.push(vm => vm.label);\n } else {\n children.push(\n t.button({className: \"link\", onClick: () => vm.download()}, vm => vm.label),\n t.time(vm.time)\n );\n }\n return t.p({className: \"Timeline_messageBody statusMessage\"}, children);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageView} from \"./BaseMessageView.js\";\n\nexport class LocationView extends BaseMessageView {\n renderMessageBody(t, vm) {\n return t.p({className: \"Timeline_messageBody statusMessage\"}, [\n t.span(vm.label),\n t.a({className: \"Timeline_locationLink\", href: vm.mapsLink, target: \"_blank\", rel: \"noopener\"}, vm.i18n`Open in maps`),\n t.time(vm.time)\n ]);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageView} from \"./BaseMessageView.js\";\n\nexport class MissingAttachmentView extends BaseMessageView {\n renderMessageBody(t, vm) {\n return t.p({className: \"Timeline_messageBody statusMessage\"}, vm.label);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../../general/TemplateView\";\n\nexport class AnnouncementView extends TemplateView {\n // ignore other arguments\n constructor(vm) {\n super(vm);\n }\n\n render(t, vm) {\n return t.li({\n className: \"AnnouncementView\",\n 'data-event-id': vm.eventId\n }, t.div(vm => vm.announcement));\n }\n \n /* This is called by the parent ListView, which just has 1 listener for the whole list */\n onClick() {}\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseMessageView} from \"./BaseMessageView.js\";\nimport {Menu} from \"../../../general/Menu.js\";\n\nexport class RedactedView extends BaseMessageView {\n renderMessageBody(t) {\n return t.p({className: \"Timeline_messageBody statusMessage\"}, vm => vm.description);\n }\n\n createMenuOptions(vm) {\n const options = super.createMenuOptions(vm);\n if (vm.isRedacting) {\n options.push(Menu.option(vm.i18n`Cancel`, () => vm.abortPendingRedaction()));\n }\n return options;\n }\n}","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../../general/TemplateView\";\nimport {spinner} from \"../../../common.js\";\nimport {ErrorView} from \"../../../general/ErrorView\";\n\nexport class GapView extends TemplateView {\n // ignore other argument\n constructor(vm) {\n super(vm);\n }\n\n render(t, vm) {\n const className = {\n GapView: true,\n isLoading: vm => vm.isLoading,\n isAtTop: vm => vm.isAtTop,\n };\n return t.li({ className }, [\n t.div({class: \"GapView_container\"}, [\n t.if(vm => vm.showSpinner, (t) => spinner(t)),\n t.span(vm => vm.status),\n ]),\n t.if(vm => !!vm.errorViewModel, t => {\n return t.view(new ErrorView(vm.errorViewModel, {inline: true}));\n })\n ]);\n }\n\n /* This is called by the parent ListView, which just has 1 listener for the whole list */\n onClick() {}\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Builder, TemplateView} from \"../../../general/TemplateView\";\nimport type {CallTile} from \"../../../../../../domain/session/room/timeline/tiles/CallTile\";\nimport {ErrorView} from \"../../../general/ErrorView\";\nimport {ListView} from \"../../../general/ListView\";\nimport {AvatarView} from \"../../../AvatarView\";\n\nexport class CallTileView extends TemplateView {\n render(t: Builder, vm: CallTile) {\n return t.li(\n {className: \"CallTileView AnnouncementView\"},\n t.div(\n [\n t.if(vm => vm.errorViewModel, t => {\n return t.div({className: \"CallTileView_error\"}, t.view(new ErrorView(vm.errorViewModel, {inline: true})));\n }),\n t.div([\n t.div({className: \"CallTileView_title\"}, vm => vm.title),\n t.div({className: \"CallTileView_subtitle\"}, [\n vm.typeLabel, \" • \",\n t.span({className: \"CallTileView_memberCount\"}, vm => vm.memberCount)\n ]),\n t.view(new ListView({className: \"CallTileView_members\", tagName: \"div\", list: vm.memberViewModels}, vm => {\n return new AvatarView(vm, 24);\n })),\n t.div(vm => vm.duration),\n t.div([\n t.button({className: \"CallTileView_join button-action primary\", hidden: vm => !vm.canJoin}, \"Join\"),\n t.button({className: \"CallTileView_leave button-action primary destructive\", hidden: vm => !vm.canLeave}, \"Leave\")\n ])\n ])\n ])\n );\n }\n \n /* This is called by the parent ListView, which just has 1 listener for the whole list */\n onClick(evt) {\n if (evt.target.classList.contains(\"CallTileView_join\")) {\n this.value.join();\n } else if (evt.target.classList.contains(\"CallTileView_leave\")) {\n this.value.leave();\n }\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../../general/TemplateView\";\nimport type {DateTile} from \"../../../../../../domain/session/room/timeline/tiles/DateTile\";\n\nexport class DateHeaderView extends TemplateView {\n render(t, vm) {\n return t.h2({className: \"DateHeader\"}, t.time({dateTime: vm.machineReadableDate}, vm.relativeDate));\n }\n\n /* This is called by the parent ListView, which just has 1 listener for the whole list */\n onClick() {}\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../../../general/TemplateView\";\nimport {Status} from \"../../../../../../domain/session/room/timeline/tiles/VerificationTile\";\nimport {spinner} from \"../../../common.js\";\nimport type {IView} from \"../../../general/types\";\nimport type {Builder} from \"../../../general/TemplateView\";\nimport type {VerificationTile} from \"../../../../../../domain/session/room/timeline/tiles/VerificationTile\";\n\ntype IClickableView = {\n onClick: (evt) => void;\n} & IView; \n\nexport class VerificationTileView extends TemplateView {\n render(t: Builder, vm: VerificationTile) {\n return t.div({ className: \"VerificationTileView\" },\n t.mapView(vm => vm.status, (status: Status) => {\n switch (status) {\n case Status.Ready:\n return new VerificationReadyTileView(vm);\n case Status.Cancelled:\n return new VerificationCancelledTileView(vm);\n case Status.Completed:\n return new VerificationCompletedTileView(vm);\n case Status.InProgress:\n return new VerificationInProgressTileView(vm);\n }\n })\n );\n }\n\n onClick(evt) {\n // Propagate click events to the sub-view\n this._subViews?.forEach((s: IClickableView) => s.onClick?.(evt));\n }\n}\n\nclass VerificationReadyTileView extends TemplateView {\n render(t: Builder, vm: VerificationTile) {\n return t.div({ className: \"VerificationReadyTileView\" }, [\n t.div({ className: \"VerificationTileView__shield\" }),\n t.div({ className: \"VerificationTileView__description\" }, [\n t.div(vm.description)\n ]),\n t.div({ className: \"VerificationTileView__actions\" }, [\n t.button({ className: \"VerificationTileView__accept button-action primary\" }, \"Accept\"),\n t.button({ className: \"VerificationTileView__reject button-action secondary\" }, \"Reject\"),\n ]),\n ]);\n }\n\n onClick(evt) {\n if (evt.target.classList.contains(\"VerificationTileView__accept\")) {\n this.value.accept();\n } else if (evt.target.classList.contains(\"VerificationTileView__reject\")) {\n this.value.reject();\n }\n }\n}\n\n\nclass VerificationCancelledTileView extends TemplateView {\n render(t: Builder, vm: VerificationTile) {\n return t.div({ className: \"VerificationCancelledTileView\" }, [\n t.div({ className: \"VerificationTileView__description\" },\n vm.i18n`${vm.isCancelledByUs? \"You\": vm.sender} cancelled the verification!`),\n ]);\n }\n}\n\nclass VerificationCompletedTileView extends TemplateView {\n render(t: Builder, vm: VerificationTile) {\n return t.div({ className: \"VerificationCompletedTileView\" }, [\n t.div({ className: \"VerificationTileView__description\" }, [\n t.div({ className: \"VerificationTileView__shield\" }),\n t.div(vm.i18n`You verified ${vm.sender}`),\n ]),\n ]);\n }\n}\n\nclass VerificationInProgressTileView extends TemplateView {\n render(t: Builder, vm: VerificationTile) {\n return t.div({ className: \"VerificationInProgressTileView\" }, [\n t.div({ className: \"VerificationTileView__description\" },\n vm.i18n`Verification in progress`),\n t.div({ className: \"VerificationTileView__actions\" }, [\n spinner(t)\n ]),\n ]);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TextMessageView} from \"./timeline/TextMessageView.js\";\nimport {ImageView} from \"./timeline/ImageView.js\";\nimport {VideoView} from \"./timeline/VideoView.js\";\nimport {FileView} from \"./timeline/FileView.js\";\nimport {LocationView} from \"./timeline/LocationView.js\";\nimport {MissingAttachmentView} from \"./timeline/MissingAttachmentView.js\";\nimport {AnnouncementView} from \"./timeline/AnnouncementView.js\";\nimport {RedactedView} from \"./timeline/RedactedView.js\";\nimport {ITile, TileShape} from \"../../../../../domain/session/room/timeline/tiles/ITile\";\nimport {GapView} from \"./timeline/GapView.js\";\nimport {CallTileView} from \"./timeline/CallTileView\";\nimport {DateHeaderView} from \"./timeline/DateHeaderView\";\nimport {VerificationTileView} from \"./timeline/VerificationTileView\";\nimport type {TileViewConstructor} from \"./TimelineView\";\n\nexport function viewClassForTile(vm: ITile): TileViewConstructor {\n switch (vm.shape) {\n case TileShape.Gap:\n return GapView;\n case TileShape.Announcement:\n return AnnouncementView;\n case TileShape.Message:\n case TileShape.MessageStatus:\n return TextMessageView;\n case TileShape.Image:\n return ImageView;\n case TileShape.Video:\n return VideoView;\n case TileShape.File:\n return FileView;\n case TileShape.Location:\n return LocationView;\n case TileShape.MissingAttachment:\n return MissingAttachmentView;\n case TileShape.Redacted:\n return RedactedView;\n case TileShape.Call:\n return CallTileView;\n case TileShape.DateHeader:\n return DateHeaderView;\n case TileShape.Verification:\n return VerificationTileView;\n default:\n throw new Error(`Tiles of shape \"${vm.shape}\" are not supported, check the tileClassForEntry function in the view model`);\n }\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport type {JoinRoomViewModel} from \"../../../../domain/session/JoinRoomViewModel\";\nimport {spinner} from \"../common.js\";\n\nexport class JoinRoomView extends TemplateView {\n render(t, vm) {\n const input = t.input({\n type: \"text\",\n name: \"id\",\n id: \"id\",\n placeholder: vm.i18n`Enter a room id or alias`,\n disabled: vm => vm.joinInProgress,\n });\n return t.main({className: \"JoinRoomView middle\"}, [\n t.div({className: \"JoinRoomView_header middle-header\"}, [\n t.a({className: \"button-utility close-middle\", href: vm.closeUrl, title: vm.i18n`Cancel room join`}),\n t.h2(\"Join room\"),\n ]),\n t.div({className: \"JoinRoomView_body centered-column\"}, [\n t.form({className: \"JoinRoomView_detailsForm form\", onSubmit: evt => this.onSubmit(evt, input.value)}, [\n t.div({className: \"vertical-layout\"}, [\n t.div({className: \"stretch form-row text\"}, [\n t.label({for: \"id\"}, vm.i18n`Room id`),\n input,\n ]),\n ]),\n t.div({className: \"button-row\"}, [\n t.button({\n className: \"button-action primary\",\n type: \"submit\",\n disabled: vm => vm.joinInProgress\n }, vm.i18n`Join`),\n ]),\n t.map(vm => vm.status, (status, t) => {\n return t.div({ className: \"JoinRoomView_status\" }, [\n spinner(t, { hidden: vm => !vm.joinInProgress }),\n t.span(status),\n ]);\n })\n ])\n ])\n ]);\n }\n\n onSubmit(evt, id) {\n evt.preventDefault();\n this.value.join(id);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AvatarView} from \"../../AvatarView.js\";\nimport {ErrorView} from \"../../general/ErrorView\";\nimport {TemplateView, Builder} from \"../../general/TemplateView\";\nimport type {CallToastNotificationViewModel} from \"../../../../../domain/session/toast/calls/CallToastNotificationViewModel\";\n\nexport class CallToastNotificationView extends TemplateView {\n render(t: Builder, vm: CallToastNotificationViewModel) {\n return t.div({ className: \"CallToastNotificationView\" }, [\n t.div({ className: \"CallToastNotificationView__top\" }, [\n t.view(new AvatarView(vm, 24)),\n t.span({ className: \"CallToastNotificationView__name\" }, (vm) => vm.roomName),\n t.button({\n className: \"button-action CallToastNotificationView__dismiss-btn\",\n onClick: () => vm.dismiss(),\n }),\n ]),\n t.div({ className: \"CallToastNotificationView__description\" }, [\n t.span(vm.i18n`Video call started`)\n ]),\n t.div({ className: \"CallToastNotificationView__info\" }, [\n t.span({className: \"CallToastNotificationView__call-type\"}, vm.i18n`Video`),\n t.span({className: \"CallToastNotificationView__member-count\"}, (vm) => vm.memberCount),\n ]),\n t.div({ className: \"CallToastNotificationView__action\" }, [\n t.button({\n className: \"button-action primary\",\n onClick: () => vm.join(),\n }, vm.i18n`Join`),\n ]),\n t.if(vm => !!vm.errorViewModel, t => {\n return t.div({className: \"CallView_error\"}, t.view(new ErrorView(vm.errorViewModel!)));\n }),\n ]);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {TemplateView, Builder} from \"../../general/TemplateView\";\nimport type {VerificationToastNotificationViewModel} from \"../../../../../domain/session/toast/verification/VerificationToastNotificationViewModel\";\n\nexport class VerificationToastNotificationView extends TemplateView {\n render(t: Builder, vm: VerificationToastNotificationViewModel) {\n return t.div({ className: \"VerificationToastNotificationView\" }, [\n t.div({ className: \"VerificationToastNotificationView__top\" }, [\n t.span({ className: \"VerificationToastNotificationView__title\" },\n vm.i18n`Device Verification`),\n t.button({\n className: \"button-action VerificationToastNotificationView__dismiss-btn\",\n onClick: () => vm.dismiss(),\n }),\n ]),\n t.div({ className: \"VerificationToastNotificationView__description\" }, [\n t.span(vm.i18n`Do you want to verify device ${vm.otherDeviceId}?`),\n ]),\n t.div({ className: \"VerificationToastNotificationView__action\" }, [\n t.button({\n className: \"button-action primary destructive\",\n onClick: () => vm.dismiss(),\n }, vm.i18n`Ignore`),\n t.button({\n className: \"button-action primary\",\n onClick: () => vm.accept(),\n }, vm.i18n`Accept`),\n ]),\n ]);\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {CallToastNotificationView} from \"./CallToastNotificationView\";\nimport {VerificationToastNotificationView} from \"./VerificationToastNotificationView\";\nimport {ListView} from \"../../general/ListView\";\nimport {TemplateView, Builder} from \"../../general/TemplateView\";\nimport type {IView} from \"../../general/types\";\nimport type {CallToastNotificationViewModel} from \"../../../../../domain/session/toast/calls/CallToastNotificationViewModel\";\nimport type {ToastCollectionViewModel} from \"../../../../../domain/session/toast/ToastCollectionViewModel\";\nimport type {BaseToastNotificationViewModel} from \"../../../../../domain/session/toast/BaseToastNotificationViewModel\";\nimport type {VerificationToastNotificationViewModel} from \"../../../../../domain/session/toast/verification/VerificationToastNotificationViewModel\";\n\nfunction toastViewModelToView(vm: BaseToastNotificationViewModel): IView {\n switch (vm.kind) {\n case \"calls\":\n return new CallToastNotificationView(vm as CallToastNotificationViewModel); \n case \"verification\":\n return new VerificationToastNotificationView(vm as VerificationToastNotificationViewModel);\n default:\n throw new Error(`Cannot find view class for notification kind ${vm.kind}`);\n }\n}\n\nexport class ToastCollectionView extends TemplateView {\n render(t: Builder, vm: ToastCollectionViewModel) {\n return t.div({ className: \"ToastCollectionView\" }, [\n t.ifView(vm => !!vm.toastViewModels, t => {\n return new ListView({\n list: vm.toastViewModels,\n parentProvidesUpdates: false,\n }, (vm: CallToastNotificationViewModel) => toastViewModelToView(vm));\n }),\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {LeftPanelView} from \"./leftpanel/LeftPanelView.js\";\nimport {RoomView} from \"./room/RoomView.js\";\nimport {UnknownRoomView} from \"./room/UnknownRoomView.js\";\nimport {RoomBeingCreatedView} from \"./room/RoomBeingCreatedView.js\";\nimport {InviteView} from \"./room/InviteView.js\";\nimport {LightboxView} from \"./room/LightboxView.js\";\nimport {TemplateView} from \"../general/TemplateView\";\nimport {StaticView} from \"../general/StaticView.js\";\nimport {SessionStatusView} from \"./SessionStatusView.js\";\nimport {RoomGridView} from \"./RoomGridView.js\";\nimport {SettingsView} from \"./settings/SettingsView.js\";\nimport {CreateRoomView} from \"./CreateRoomView.js\";\nimport {RightPanelView} from \"./rightpanel/RightPanelView.js\";\nimport {viewClassForTile} from \"./room/common\";\nimport {JoinRoomView} from \"./JoinRoomView\";\nimport {DeviceVerificationView} from \"./verification/DeviceVerificationView\";\nimport {ToastCollectionView} from \"./toast/ToastCollectionView\";\n\nexport class SessionView extends TemplateView {\n render(t, vm) {\n return t.div({\n className: {\n \"SessionView\": true,\n \"middle-shown\": vm => !!vm.activeMiddleViewModel,\n \"right-shown\": vm => !!vm.rightPanelViewModel\n },\n }, [\n t.view(new ToastCollectionView(vm.toastCollectionViewModel)),\n t.view(new SessionStatusView(vm.sessionStatusViewModel)),\n t.view(new LeftPanelView(vm.leftPanelViewModel)),\n t.mapView(vm => vm.activeMiddleViewModel, () => {\n if (vm.roomGridViewModel) {\n return new RoomGridView(vm.roomGridViewModel, viewClassForTile);\n } else if (vm.settingsViewModel) {\n return new SettingsView(vm.settingsViewModel);\n } else if (vm.createRoomViewModel) {\n return new CreateRoomView(vm.createRoomViewModel);\n } else if (vm.joinRoomViewModel) {\n return new JoinRoomView(vm.joinRoomViewModel);\n } else if (vm.verificationViewModel) {\n return new DeviceVerificationView(vm.verificationViewModel);\n } else if (vm.currentRoomViewModel) {\n if (vm.currentRoomViewModel.kind === \"invite\") {\n return new InviteView(vm.currentRoomViewModel);\n } else if (vm.currentRoomViewModel.kind === \"room\") {\n return new RoomView(vm.currentRoomViewModel, viewClassForTile);\n } else if (vm.currentRoomViewModel.kind === \"roomBeingCreated\") {\n return new RoomBeingCreatedView(vm.currentRoomViewModel);\n } else {\n return new UnknownRoomView(vm.currentRoomViewModel);\n }\n } else {\n return new StaticView(t => t.div({className: \"room-placeholder\"}, t.h2(vm.i18n`Choose a room on the left side.`)));\n }\n }),\n t.mapView(vm => vm.lightboxViewModel, lightboxViewModel => lightboxViewModel ? new LightboxView(lightboxViewModel) : null),\n t.mapView(vm => vm.rightPanelViewModel, rightPanelViewModel => rightPanelViewModel ? new RightPanelView(rightPanelViewModel) : null)\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function hydrogenGithubLink(t) {\n if (DEFINE_VERSION === \"develop\") {\n return t.a(\n {\n target: \"_blank\",\n href: `https://github.com/vector-im/hydrogen-web`,\n },\n `Hydrogen develop, ${DEFINE_GLOBAL_HASH}`\n );\n } else if (DEFINE_VERSION && DEFINE_GLOBAL_HASH) {\n return t.a(\n {\n target: \"_blank\",\n href: `https://github.com/vector-im/hydrogen-web/releases/tag/v${DEFINE_VERSION}`,\n },\n `Hydrogen v${DEFINE_VERSION} (${DEFINE_GLOBAL_HASH}) on Github`\n );\n } else {\n return t.a(\n {\n target: \"_blank\",\n href: \"https://github.com/vector-im/hydrogen-web\",\n },\n \"Hydrogen on Github\"\n );\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\n\nexport class PasswordLoginView extends TemplateView {\n render(t, vm) {\n const disabled = vm => !!vm.isBusy;\n const username = t.input({\n id: \"username\",\n type: \"text\",\n placeholder: vm.i18n`Username`,\n disabled\n });\n const password = t.input({\n id: \"password\",\n type: \"password\",\n placeholder: vm.i18n`Password`,\n disabled\n });\n \n return t.div({className: \"PasswordLoginView form\"}, [\n t.if(vm => vm.error, t => t.div({ className: \"error\" }, vm => vm.error)),\n t.form({\n onSubmit: evnt => {\n evnt.preventDefault();\n vm.login(username.value, password.value);\n }\n }, [\n t.if(vm => vm.errorMessage, (t, vm) => t.p({className: \"error\"}, vm.i18n(vm.errorMessage))),\n t.div({ className: \"form-row text\" }, [t.label({ for: \"username\" }, vm.i18n`Username`), username]),\n t.div({ className: \"form-row text\" }, [t.label({ for: \"password\" }, vm.i18n`Password`), password]),\n t.div({ className: \"button-row\" }, [\n t.button({\n className: \"button-action primary\",\n type: \"submit\",\n disabled\n }, vm.i18n`Log In`),\n ]),\n ])\n ]);\n }\n}\n\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {KeyBackupSettingsView} from \"../session/settings/KeyBackupSettingsView\";\n\nexport class AccountSetupView extends TemplateView {\n render(t, vm) {\n return t.div({className: \"Settings\" /* hack for now to get the layout right*/}, [\n t.h3(vm.i18n`Restore your encrypted history?`),\n t.ifView(vm => vm.decryptDehydratedDeviceViewModel, vm => new KeyBackupSettingsView(vm.decryptDehydratedDeviceViewModel)),\n t.map(vm => vm.deviceDecrypted, (decrypted, t) => {\n if (decrypted) {\n return t.p(vm.i18n`That worked out, you're good to go!`);\n } else {\n return t.p(vm.i18n`This will claim the dehydrated device ${vm.dehydratedDeviceId}, and will set up a new one.`);\n }\n }),\n t.div({ className: \"button-row\" }, [\n t.button({\n className: \"button-action primary\",\n onClick: () => { vm.finish(); },\n type: \"button\",\n }, vm => vm.deviceDecrypted ? vm.i18n`Continue` : vm.i18n`Continue without restoring`),\n ]),\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {spinner} from \"../common.js\";\nimport {AccountSetupView} from \"./AccountSetupView.js\";\n\n/** a view used both in the login view and the loading screen\nto show the current state of loading the session.\nJust a spinner and a label, meant to be used as a paragraph */\nexport class SessionLoadStatusView extends TemplateView {\n render(t) {\n const exportLogsButtonIfFailed = t.if(vm => vm.hasError, (t, vm) => {\n return t.button({\n onClick: () => vm.exportLogs()\n }, vm.i18n`Export logs`);\n });\n const logoutButtonIfFailed = t.if(vm => vm.hasError, (t, vm) => {\n return t.button({\n onClick: () => vm.logout()\n }, vm.i18n`Log out`);\n });\n return t.div({className: \"SessionLoadStatusView\"}, [\n t.p({className: \"status\"}, [\n spinner(t, {hidden: vm => !vm.loading}),\n t.p(vm => vm.loadLabel),\n exportLogsButtonIfFailed,\n logoutButtonIfFailed\n ]),\n t.ifView(vm => vm.accountSetupViewModel, vm => new AccountSetupView(vm.accountSetupViewModel)),\n ]);\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {SessionLoadStatusView} from \"./SessionLoadStatusView.js\";\n\nexport class CompleteSSOView extends TemplateView {\n render(t) {\n return t.div({ className: \"CompleteSSOView\" },\n [\n t.p({ className: \"CompleteSSOView_title\" }, \"Finishing up your SSO Login\"),\n t.if(vm => vm.errorMessage, (t, vm) => t.p({className: \"error\"}, vm.i18n(vm.errorMessage))),\n t.mapView(vm => vm.loadViewModel, loadViewModel => loadViewModel ? new SessionLoadStatusView(loadViewModel) : null),\n ]\n );\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {hydrogenGithubLink} from \"./common.js\";\nimport {PasswordLoginView} from \"./PasswordLoginView.js\";\nimport {CompleteSSOView} from \"./CompleteSSOView.js\";\nimport {SessionLoadStatusView} from \"./SessionLoadStatusView.js\";\nimport {spinner} from \"../common.js\";\n\nexport class LoginView extends TemplateView {\n render(t, vm) {\n const disabled = vm => vm.isBusy;\n\n return t.div({className: \"PreSessionScreen\"}, [\n t.button({\n className: \"button-utility LoginView_back\",\n onClick: () => vm.goBack(),\n disabled\n }),\n t.div({className: \"logo\"}),\n t.h1([vm.i18n`Sign In`]),\n t.mapView(vm => vm.completeSSOLoginViewModel, vm => vm ? new CompleteSSOView(vm) : null),\n t.if(vm => vm.showHomeserver, (t, vm) => t.div({ className: \"LoginView_sso form-row text\" },\n [\n t.label({for: \"homeserver\"}, vm.i18n`Homeserver`),\n t.input({\n id: \"homeserver\",\n type: \"text\",\n placeholder: vm.i18n`Your matrix homeserver`,\n value: vm.homeserver,\n disabled,\n onInput: event => vm.setHomeserver(event.target.value),\n onChange: () => vm.queryHomeserver(),\n }),\n t.p({className: {\n LoginView_forwardInfo: true,\n hidden: vm => !vm.resolvedHomeserver\n }}, vm => vm.i18n`You will connect to ${vm.resolvedHomeserver}.`),\n t.if(vm => vm.errorMessage, (t, vm) => t.p({className: \"error\"}, vm.i18n(vm.errorMessage))),\n ]\n )),\n t.if(vm => vm.isFetchingLoginOptions, t => t.div({className: \"LoginView_query-spinner\"}, [spinner(t), t.p(\"Fetching available login options...\")])),\n t.mapView(vm => vm.passwordLoginViewModel, vm => vm ? new PasswordLoginView(vm): null),\n t.if(vm => vm.passwordLoginViewModel && vm.startSSOLoginViewModel, t => t.p({className: \"LoginView_separator\"}, vm.i18n`or`)),\n t.mapView(vm => vm.startSSOLoginViewModel, vm => vm ? new StartSSOLoginView(vm) : null),\n t.mapView(vm => vm.loadViewModel, loadViewModel => loadViewModel ? new SessionLoadStatusView(loadViewModel) : null),\n // use t.mapView rather than t.if to create a new view when the view model changes too\n t.p(hydrogenGithubLink(t))\n ]);\n }\n}\n\nclass StartSSOLoginView extends TemplateView {\n render(t, vm) {\n return t.div({ className: \"StartSSOLoginView\" },\n t.button({\n className: \"StartSSOLoginView_button button-action secondary\",\n type: \"button\",\n onClick: () => vm.startSSOLogin(),\n disabled: vm => vm.isBusy\n }, vm.i18n`Log in with SSO`)\n );\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView, InlineTemplateView} from \"./general/TemplateView\";\nimport {spinner} from \"./common.js\";\n\nexport class LogoutView extends TemplateView {\n render(t, vm) {\n const confirmView = new InlineTemplateView(vm, t => {\n return t.div([\n t.p(\"Are you sure you want to log out?\"),\n t.div({ className: \"button-row\" }, [\n t.a({\n className: \"button-action\",\n type: \"submit\",\n href: vm.cancelUrl,\n }, [\"Cancel\"]),\n t.button({\n className: \"button-action primary destructive\",\n type: \"submit\",\n onClick: () => vm.logout(),\n }, vm.i18n`Log out`)\n ]),\n ]);\n });\n const progressView = new InlineTemplateView(vm, t => {\n return t.p({className: \"status\", hidden: vm => !vm.showStatus}, [\n spinner(t, {hidden: vm => !vm.busy}), t.span(vm => vm.status)\n ]);\n });\n\n return t.div({className: \"LogoutScreen\"}, [\n t.div({className: \"content\"}, [\n t.mapView(vm => vm.showConfirm, showConfirm => {\n return showConfirm ? confirmView : progressView;\n })\n ]),\n ]);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"./general/TemplateView\";\nimport {spinner} from \"./common.js\";\n\nexport class ForcedLogoutView extends TemplateView {\n render(t) {\n return t.div({ className: \"LogoutScreen\" }, [\n t.div({ className: \"content\" },\n t.map(vm => vm.showStatus, (showStatus, t, vm) => {\n if (showStatus) {\n return t.p({ className: \"status\" }, [\n spinner(t, { hidden: vm => !vm.showSpinner }),\n t.span(vm => vm.status)\n ]);\n }\n else {\n return t.div([\n t.p(\"Your access token is no longer valid! You can reauthenticate in the next screen.\"),\n t.div({ className: \"button-row\" }, [\n t.button({\n className: \"button-action primary\",\n type: \"submit\",\n onClick: () => vm.proceed(),\n }, vm.i18n`Proceed`)\n ]),\n ]);\n }\n })\n ),\n ]);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {TemplateView} from \"../general/TemplateView\";\nimport {SessionLoadStatusView} from \"./SessionLoadStatusView.js\";\n\nexport class SessionLoadView extends TemplateView {\n render(t, vm) {\n return t.div({className: \"PreSessionScreen\"}, [\n t.div({className: \"logo\"}),\n t.div({className: \"SessionLoadView\"}, [\n t.view(new SessionLoadStatusView(vm))\n ]),\n t.div({className: {\"button-row\": true, hidden: vm => vm.loading}},\n t.a({className: \"button-action primary\", href: vm.backUrl}, vm.i18n`Go back`))\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ListView} from \"../general/ListView\";\nimport {TemplateView} from \"../general/TemplateView\";\nimport {hydrogenGithubLink} from \"./common.js\";\nimport {SessionLoadStatusView} from \"./SessionLoadStatusView.js\";\n\nclass SessionPickerItemView extends TemplateView {\n _onDeleteClick() {\n if (confirm(\"Are you sure?\")) {\n this.value.delete();\n }\n }\n\n _onClearClick() {\n if (confirm(\"Are you sure?\")) {\n this.value.clear();\n }\n }\n\n render(t, vm) {\n return t.li([\n t.a({className: \"session-info\", href: vm.openUrl}, [\n t.div({className: `avatar usercolor${vm.avatarColorNumber}`}, vm => vm.avatarInitials),\n t.div({className: \"user-id\"}, vm => vm.label),\n ])\n ]);\n }\n}\n\nexport class SessionPickerView extends TemplateView {\n render(t, vm) {\n const sessionList = new ListView({\n list: vm.sessions,\n parentProvidesUpdates: false,\n }, sessionInfo => {\n return new SessionPickerItemView(sessionInfo);\n });\n\n return t.div({className: \"PreSessionScreen\"}, [\n t.div({className: \"logo\"}),\n t.div({className: \"SessionPickerView\"}, [\n t.h1([\"Continue as …\"]),\n t.view(sessionList),\n t.div({className: \"button-row\"}, [\n t.a({\n className: \"button-action primary\",\n href: vm.cancelUrl\n }, vm.i18n`Sign In`)\n ]),\n t.ifView(vm => vm.loadViewModel, () => new SessionLoadStatusView(vm.loadViewModel)),\n t.p(hydrogenGithubLink(t))\n ])\n ]);\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {SessionView} from \"./session/SessionView.js\";\nimport {LoginView} from \"./login/LoginView\";\nimport {LogoutView} from \"./LogoutView.js\";\nimport {ForcedLogoutView} from \"./ForcedLogoutView.js\";\nimport {SessionLoadView} from \"./login/SessionLoadView.js\";\nimport {SessionPickerView} from \"./login/SessionPickerView.js\";\nimport {TemplateView} from \"./general/TemplateView\";\nimport {StaticView} from \"./general/StaticView.js\";\n\nexport class RootView extends TemplateView {\n render(t, vm) {\n return t.mapView(vm => vm.activeSection, activeSection => {\n switch (activeSection) {\n case \"error\":\n return new StaticView(t => {\n return t.div({className: \"StatusView\"}, [\n t.h1(\"Something went wrong\"),\n t.p(vm.errorText),\n ])\n });\n case \"session\":\n return new SessionView(vm.sessionViewModel);\n case \"login\":\n return new LoginView(vm.loginViewModel);\n case \"logout\":\n return new LogoutView(vm.logoutViewModel);\n case \"forced-logout\":\n return new ForcedLogoutView(vm.forcedLogoutViewModel);\n case \"picker\":\n return new SessionPickerView(vm.sessionPickerViewModel);\n case \"redirecting\":\n return new StaticView(t => t.p(\"Redirecting...\"));\n case \"loading\":\n return new SessionLoadView(vm.sessionLoadViewModel);\n default:\n throw new Error(`Unknown section: ${vm.activeSection}`);\n }\n });\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../../utils/error\";\n\nclass Timeout {\n constructor(ms) {\n this._reject = null;\n this._handle = null;\n this._promise = new Promise((resolve, reject) => {\n this._reject = reject;\n this._handle = setTimeout(() => {\n this._reject = null;\n resolve();\n }, ms);\n });\n }\n\n elapsed() {\n return this._promise;\n }\n\n abort() {\n if (this._reject) {\n this._reject(new AbortError());\n clearTimeout(this._handle);\n this._handle = null;\n this._reject = null;\n }\n }\n\n dispose() {\n this.abort();\n }\n}\n\nclass Interval {\n constructor(ms, callback) {\n this._handle = setInterval(callback, ms);\n }\n\n dispose() {\n if (this._handle) {\n clearInterval(this._handle);\n this._handle = null;\n }\n }\n}\n\nclass TimeMeasure {\n constructor() {\n this._start = window.performance.now();\n }\n\n measure() {\n return window.performance.now() - this._start;\n }\n}\n\nexport class Clock {\n createMeasure() {\n return new TimeMeasure();\n }\n\n createTimeout(ms) {\n return new Timeout(ms);\n }\n\n createInterval(callback, ms) {\n return new Interval(ms, callback);\n }\n\n now() {\n return Date.now();\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// 3 (imaginary) interfaces are implemented here:\n// - OfflineAvailability (done by registering the sw)\n// - UpdateService (see checkForUpdate method, and should also emit events rather than showing confirm dialog here)\n// - ConcurrentAccessBlocker (see preventConcurrentSessionAccess method)\nexport class ServiceWorkerHandler {\n constructor(sessionInfoStorage) {\n this._waitingForReply = new Map();\n this._messageIdCounter = 0;\n this._navigation = null;\n this._registration = null;\n this._registrationPromise = null;\n this._currentController = null;\n this._sessionInfoStorage = sessionInfoStorage;\n this.haltRequests = false;\n this._authData = {};\n }\n\n setNavigation(navigation) {\n this._navigation = navigation;\n }\n\n /**\n * Set the access-token and homeserver to be used within the service worker.\n * @param auth An object with accessToken and homeserver\n */\n updateAuthData(auth) {\n if (!auth.accessToken && !auth.homeserver) {\n throw new Error(\n \"updateAuthData argument must contain accessToken, homeserver or both!\"\n );\n }\n this._authData = { ...this._authData, ...auth };\n }\n\n registerAndStart(path) {\n this._registrationPromise = (async () => {\n navigator.serviceWorker.addEventListener(\"message\", this);\n navigator.serviceWorker.addEventListener(\"controllerchange\", this);\n this._registration = await navigator.serviceWorker.register(path);\n await navigator.serviceWorker.ready;\n this._currentController = navigator.serviceWorker.controller;\n this._registration.addEventListener(\"updatefound\", this);\n this._registrationPromise = null;\n // do we have a new service worker waiting to activate?\n if (this._registration.waiting && this._registration.active) {\n this._proposeUpdate();\n }\n console.log(\"Service Worker registered\");\n })();\n }\n\n async _onMessage(event) {\n const { data } = event;\n const replyTo = data.replyTo;\n if (replyTo) {\n const resolve = this._waitingForReply.get(replyTo);\n if (resolve) {\n this._waitingForReply.delete(replyTo);\n resolve(data.payload);\n }\n }\n if (data.type === \"hasSessionOpen\") {\n const hasOpen =\n this._navigation.observe(\"session\").get() ===\n data.payload.sessionId;\n event.source.postMessage({ replyTo: data.id, payload: hasOpen });\n } else if (data.type === \"hasRoomOpen\") {\n const hasSessionOpen =\n this._navigation.observe(\"session\").get() ===\n data.payload.sessionId;\n const hasRoomOpen =\n this._navigation.observe(\"room\").get() === data.payload.roomId;\n event.source.postMessage({\n replyTo: data.id,\n payload: hasSessionOpen && hasRoomOpen,\n });\n } else if (data.type === \"closeSession\") {\n const { sessionId } = data.payload;\n this._closeSessionIfNeeded(sessionId).finally(() => {\n event.source.postMessage({ replyTo: data.id });\n });\n } else if (data.type === \"haltRequests\") {\n // this flag is read in fetch.js\n this.haltRequests = true;\n event.source.postMessage({ replyTo: data.id });\n } else if (data.type === \"openRoom\") {\n this._navigation.push(\"room\", data.payload.roomId);\n } else if (data.type === \"getAuthInfo\") {\n event.source.postMessage({\n replyTo: data.id,\n payload: this._authData,\n });\n }\n }\n\n _closeSessionIfNeeded(sessionId) {\n const currentSession = this._navigation?.path.get(\"session\");\n if (sessionId && currentSession?.value === sessionId) {\n return new Promise((resolve) => {\n const unsubscribe = this._navigation.pathObservable.subscribe(\n (path) => {\n const session = path.get(\"session\");\n if (!session || session.value !== sessionId) {\n unsubscribe();\n resolve();\n }\n }\n );\n this._navigation.push(\"session\");\n });\n } else {\n return Promise.resolve();\n }\n }\n\n async _proposeUpdate() {\n if (document.hidden) {\n return;\n }\n const version = await this._sendAndWaitForReply(\n \"version\",\n null,\n this._registration.waiting\n );\n const isSdk = DEFINE_IS_SDK;\n const isDev = this.version === \"develop\";\n // Don't ask for confirmation when being used as an sdk/ when being run in dev server\n if (\n isSdk ||\n isDev ||\n confirm(\n `Version ${version.version} (${version.buildHash}) is available. Reload to apply?`\n )\n ) {\n console.log(\"Service Worker has been updated!\");\n // prevent any fetch requests from going to the service worker\n // from any client, so that it is not kept active\n // when calling skipWaiting on the new one\n await this._sendAndWaitForReply(\"haltRequests\");\n // only once all requests are blocked, ask the new\n // service worker to skipWaiting\n this._send(\"skipWaiting\", null, this._registration.waiting);\n }\n }\n\n handleEvent(event) {\n switch (event.type) {\n case \"message\":\n this._onMessage(event);\n break;\n case \"updatefound\":\n this._registration.installing.addEventListener(\n \"statechange\",\n this\n );\n break;\n case \"statechange\": {\n if (event.target.state === \"installed\") {\n this._proposeUpdate();\n event.target.removeEventListener(\"statechange\", this);\n }\n break;\n }\n case \"controllerchange\":\n if (!this._currentController) {\n // Clients.claim() in the SW can trigger a controllerchange event\n // if we had no SW before. This is fine,\n // and now our requests will be served from the SW.\n this._currentController =\n navigator.serviceWorker.controller;\n } else {\n // active service worker changed,\n // refresh, so we can get all assets\n // (and not only some if we would not refresh)\n // up to date from it\n document.location.reload();\n }\n break;\n }\n }\n\n async _send(type, payload, worker = undefined) {\n if (this._registrationPromise) {\n await this._registrationPromise;\n }\n if (!worker) {\n worker = this._registration.active;\n }\n worker.postMessage({ type, payload });\n }\n\n async _sendAndWaitForReply(type, payload, worker = undefined) {\n if (this._registrationPromise) {\n await this._registrationPromise;\n }\n if (!worker) {\n worker = this._registration.active;\n }\n this._messageIdCounter += 1;\n const id = this._messageIdCounter;\n const promise = new Promise((resolve) => {\n this._waitingForReply.set(id, resolve);\n });\n worker.postMessage({ type, id, payload });\n return await promise;\n }\n\n async checkForUpdate() {\n if (this._registrationPromise) {\n await this._registrationPromise;\n }\n this._registration.update();\n }\n\n get version() {\n return DEFINE_VERSION;\n }\n\n get buildHash() {\n return DEFINE_GLOBAL_HASH;\n }\n\n async preventConcurrentSessionAccess(sessionId) {\n return this._sendAndWaitForReply(\"closeSession\", { sessionId });\n }\n\n async getRegistration() {\n if (this._registrationPromise) {\n await this._registrationPromise;\n }\n return this._registration;\n }\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class NotificationService {\n constructor(serviceWorkerHandler, pushConfig) {\n this._serviceWorkerHandler = serviceWorkerHandler;\n this._pushConfig = pushConfig;\n }\n\n async enablePush(pusherFactory, defaultPayload) {\n const registration = await this._serviceWorkerHandler?.getRegistration();\n if (registration?.pushManager) {\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: this._pushConfig.applicationServerKey,\n });\n const subscriptionData = subscription.toJSON();\n const pushkey = subscriptionData.keys.p256dh;\n const data = {\n endpoint: subscriptionData.endpoint,\n auth: subscriptionData.keys.auth,\n // don't deliver unread count push messages\n // as we don't want to show a notification in this case\n events_only: true,\n default_payload: defaultPayload\n };\n return pusherFactory.httpPusher(\n this._pushConfig.gatewayUrl,\n this._pushConfig.appId,\n pushkey,\n data\n );\n }\n }\n\n async disablePush() {\n const registration = await this._serviceWorkerHandler?.getRegistration();\n if (registration?.pushManager) {\n const subscription = await registration.pushManager.getSubscription();\n if (subscription) {\n await subscription.unsubscribe();\n }\n }\n }\n\n async isPushEnabled() {\n const registration = await this._serviceWorkerHandler?.getRegistration();\n if (registration?.pushManager) {\n const subscription = await registration.pushManager.getSubscription();\n return !!subscription;\n }\n return false;\n }\n\n async supportsPush() {\n if (!this._pushConfig) {\n return false;\n }\n const registration = await this._serviceWorkerHandler?.getRegistration();\n return registration && \"pushManager\" in registration;\n }\n\n async enableNotifications() {\n if (\"Notification\" in window) {\n return (await Notification.requestPermission()) === \"granted\";\n }\n return false;\n }\n\n async supportsNotifications() {\n return \"Notification\" in window;\n }\n\n async areNotificationsEnabled() {\n if (\"Notification\" in window) {\n return Notification.permission === \"granted\";\n } else {\n return false;\n }\n }\n\n async showNotification(title, body = undefined) {\n if (\"Notification\" in window) {\n new Notification(title, {body});\n return;\n }\n // Chrome on Android does not support the Notification constructor\n const registration = await this._serviceWorkerHandler?.getRegistration();\n registration?.showNotification(title, {body});\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"../../../observable/value\";\n\nexport class History extends BaseObservableValue {\n \n constructor() {\n super();\n this._lastSessionHash = undefined;\n }\n \n handleEvent(event) {\n if (event.type === \"hashchange\") {\n this.emit(this.get());\n this._storeHash(this.get());\n }\n }\n\n get() {\n /*\n All URLS in Hydrogen will use /#/segment/value/...\n But for SSO, we need to handle /?loginToken=\n Handle that as a special case for now.\n */\n if (document.location.search.includes(\"loginToken\")) {\n return document.location.search;\n }\n return document.location.hash;\n }\n\n /** does not emit */\n replaceUrlSilently(url) {\n window.history.replaceState(null, null, url);\n this._storeHash(url);\n }\n\n /** does not emit */\n pushUrlSilently(url) {\n window.history.pushState(null, null, url);\n this._storeHash(url);\n }\n\n pushUrl(url) {\n document.location.hash = url;\n }\n\n urlAsPath(url) {\n if (url.startsWith(\"#\")) {\n return url.substr(1);\n } else {\n return url;\n }\n }\n\n pathAsUrl(path) {\n return `#${path}`;\n }\n\n onSubscribeFirst() {\n this._lastSessionHash = window.localStorage?.getItem(\"hydrogen_last_url_hash\");\n window.addEventListener('hashchange', this);\n }\n\n onUnsubscribeLast() {\n window.removeEventListener('hashchange', this);\n }\n\n _storeHash(hash) {\n window.localStorage?.setItem(\"hydrogen_last_url_hash\", hash);\n }\n\n getLastSessionUrl() {\n return this._lastSessionHash;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"../../../observable/value\";\n\nexport class OnlineStatus extends BaseObservableValue {\n constructor() {\n super();\n this._onOffline = this._onOffline.bind(this);\n this._onOnline = this._onOnline.bind(this);\n }\n\n _onOffline() {\n this.emit(false);\n }\n\n _onOnline() {\n this.emit(true);\n }\n\n get() {\n return navigator.onLine;\n }\n\n onSubscribeFirst() {\n window.addEventListener('offline', this._onOffline);\n window.addEventListener('online', this._onOnline);\n }\n\n onUnsubscribeLast() {\n window.removeEventListener('offline', this._onOffline);\n window.removeEventListener('online', this._onOnline);\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport base64 from \"base64-arraybuffer\";\n\n// turn IE11 result into promise\nfunction subtleCryptoResult(promiseOrOp, method) {\n if (promiseOrOp instanceof Promise) {\n return promiseOrOp;\n } else {\n return new Promise((resolve, reject) => {\n promiseOrOp.oncomplete = e => resolve(e.target.result);\n promiseOrOp.onerror = () => reject(new Error(\"Crypto error on \" + method));\n });\n }\n}\n\nclass HMACCrypto {\n constructor(subtleCrypto) {\n this._subtleCrypto = subtleCrypto;\n }\n /**\n * [hmac description]\n * @param {BufferSource} key\n * @param {BufferSource} mac\n * @param {BufferSource} data\n * @param {HashName} hash\n * @return {boolean}\n */\n async verify(key, mac, data, hash) {\n const opts = {\n name: 'HMAC',\n hash: {name: hashName(hash)},\n };\n const hmacKey = await subtleCryptoResult(this._subtleCrypto.importKey(\n 'raw',\n key,\n opts,\n false,\n ['verify'],\n ), \"importKey\");\n const isVerified = await subtleCryptoResult(this._subtleCrypto.verify(\n opts,\n hmacKey,\n mac,\n data,\n ), \"verify\");\n return isVerified;\n }\n\n async compute(key, data, hash) {\n const opts = {\n name: 'HMAC',\n hash: {name: hashName(hash)},\n };\n const hmacKey = await subtleCryptoResult(this._subtleCrypto.importKey(\n 'raw',\n key,\n opts,\n false,\n ['sign'],\n ), \"importKey\");\n const buffer = await subtleCryptoResult(this._subtleCrypto.sign(\n opts,\n hmacKey,\n data,\n ), \"sign\");\n return new Uint8Array(buffer);\n }\n}\n\nclass DeriveCrypto {\n constructor(subtleCrypto, crypto, cryptoExtras) {\n this._subtleCrypto = subtleCrypto;\n this._crypto = crypto;\n this._cryptoExtras = cryptoExtras;\n }\n /**\n * [pbkdf2 description]\n * @param {BufferSource} password\n * @param {Number} iterations\n * @param {BufferSource} salt\n * @param {HashName} hash\n * @param {Number} length the desired length of the generated key, in bits (not bytes!)\n * @return {BufferSource}\n */\n async pbkdf2(password, iterations, salt, hash, length) {\n if (!this._subtleCrypto.deriveBits) {\n throw new Error(\"PBKDF2 is not supported\");\n }\n const key = await subtleCryptoResult(this._subtleCrypto.importKey(\n 'raw',\n password,\n {name: 'PBKDF2'},\n false,\n ['deriveBits'],\n ), \"importKey\");\n const keybits = await subtleCryptoResult(this._subtleCrypto.deriveBits(\n {\n name: 'PBKDF2',\n salt,\n iterations,\n hash: hashName(hash),\n },\n key,\n length,\n ), \"deriveBits\");\n return new Uint8Array(keybits);\n }\n\n /**\n * [hkdf description]\n * @param {BufferSource} key [description]\n * @param {BufferSource} salt [description]\n * @param {BufferSource} info [description]\n * @param {HashName} hash the hash to use\n * @param {Number} length desired length of the generated key in bits (not bytes!)\n * @return {[type]} [description]\n */\n async hkdf(key, salt, info, hash, length) {\n if (!this._subtleCrypto.deriveBits) {\n return this._cryptoExtras.hkdf(this._crypto, key, salt, info, hash, length);\n }\n const hkdfkey = await subtleCryptoResult(this._subtleCrypto.importKey(\n 'raw',\n key,\n {name: \"HKDF\"},\n false,\n [\"deriveBits\"],\n ), \"importKey\");\n const keybits = await subtleCryptoResult(this._subtleCrypto.deriveBits({\n name: \"HKDF\",\n salt,\n info,\n hash: hashName(hash),\n },\n hkdfkey,\n length,\n ), \"deriveBits\");\n return new Uint8Array(keybits);\n }\n}\n\nclass AESCrypto {\n constructor(subtleCrypto, crypto) {\n this._subtleCrypto = subtleCrypto;\n this._crypto = crypto;\n }\n /**\n * [decrypt description]\n * @param {BufferSource} key [description]\n * @param {Object} jwkKey [description]\n * @param {BufferSource} iv [description]\n * @param {BufferSource} data [description]\n * @param {Number} counterLength the size of the counter, in bits\n * @return {BufferSource} [description]\n */\n async decryptCTR({key, jwkKey, iv, data, counterLength = 64}) {\n const opts = {\n name: \"AES-CTR\",\n counter: iv,\n length: counterLength,\n };\n let aesKey;\n try {\n const selectedKey = key || jwkKey;\n const format = jwkKey ? \"jwk\" : \"raw\";\n aesKey = await subtleCryptoResult(this._subtleCrypto.importKey(\n format,\n selectedKey,\n opts,\n false,\n ['decrypt'],\n ), \"importKey\");\n } catch (err) {\n throw new Error(`Could not import key for AES-CTR decryption: ${err.message}`);\n }\n try {\n const plaintext = await subtleCryptoResult(this._subtleCrypto.decrypt(\n // see https://developer.mozilla.org/en-US/docs/Web/API/AesCtrParams\n opts,\n aesKey,\n data,\n ), \"decrypt\");\n return new Uint8Array(plaintext);\n } catch (err) {\n throw new Error(`Could not decrypt with AES-CTR: ${err.message}`);\n }\n }\n\n async encryptCTR({key, jwkKey, iv, data}) {\n const opts = {\n name: \"AES-CTR\",\n counter: iv,\n length: 64,\n };\n let aesKey;\n const selectedKey = key || jwkKey;\n const format = jwkKey ? \"jwk\" : \"raw\";\n try {\n aesKey = await subtleCryptoResult(this._subtleCrypto.importKey(\n format,\n selectedKey,\n opts,\n false,\n ['encrypt'],\n ), \"importKey\");\n } catch (err) {\n throw new Error(`Could not import key for AES-CTR encryption: ${err.message}`);\n }\n try {\n const ciphertext = await subtleCryptoResult(this._subtleCrypto.encrypt(\n // see https://developer.mozilla.org/en-US/docs/Web/API/AesCtrParams\n opts,\n aesKey,\n data,\n ), \"encrypt\");\n return new Uint8Array(ciphertext);\n } catch (err) {\n throw new Error(`Could not encrypt with AES-CTR: ${err.message}`);\n }\n }\n\n /**\n * Generate a CTR key\n * @param {String} format \"raw\" or \"jwk\"\n * @param {Number} length 128 or 256\n * @return {Promise} an object for jwk, or a BufferSource for raw\n */\n async generateKey(format, length = 256) {\n const cryptoKey = await subtleCryptoResult(this._subtleCrypto.generateKey(\n {\"name\": \"AES-CTR\", length}, true, [\"encrypt\", \"decrypt\"]));\n return subtleCryptoResult(this._subtleCrypto.exportKey(format, cryptoKey));\n }\n\n async generateIV() {\n return generateIV(this._crypto);\n }\n}\n\nfunction generateIV(crypto) {\n const randomBytes = crypto.getRandomValues(new Uint8Array(8));\n const ivArray = new Uint8Array(16);\n for (let i = 0; i < randomBytes.length; i += 1) {\n ivArray[i] = randomBytes[i];\n }\n return ivArray;\n}\n\nfunction jwkKeyToRaw(jwkKey) {\n if (jwkKey.alg !== \"A256CTR\") {\n throw new Error(`Unknown algorithm: ${jwkKey.alg}`);\n }\n if (!jwkKey.key_ops.includes(\"decrypt\")) {\n throw new Error(`decrypt missing from key_ops`);\n }\n if (jwkKey.kty !== \"oct\") {\n throw new Error(`Invalid key type, \"oct\" expected: ${jwkKey.kty}`);\n }\n // convert base64-url to normal base64\n const base64UrlKey = jwkKey.k;\n const base64Key = base64UrlKey.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return base64.decode(base64Key);\n}\n\nfunction encodeUnpaddedBase64(buffer) {\n const str = base64.encode(buffer);\n const paddingIdx = str.indexOf(\"=\");\n if (paddingIdx !== -1) {\n return str.substr(0, paddingIdx);\n } else {\n return str;\n }\n}\n\nfunction encodeUrlBase64(buffer) {\n const unpadded = encodeUnpaddedBase64(buffer);\n return unpadded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction rawKeyToJwk(key) {\n return {\n \"alg\": \"A256CTR\",\n \"ext\": true,\n \"k\": encodeUrlBase64(key),\n \"key_ops\": [\n \"encrypt\",\n \"decrypt\"\n ],\n \"kty\": \"oct\"\n };\n}\n\n\nclass AESLegacyCrypto {\n constructor(aesjs, crypto) {\n this._aesjs = aesjs;\n this._crypto = crypto;\n }\n /**\n * [decrypt description]\n * @param {BufferSource} key [description]\n * @param {BufferSource} iv [description]\n * @param {BufferSource} ciphertext [description]\n * @param {Number} counterLength the size of the counter, in bits\n * @return {BufferSource} [description]\n */\n async decryptCTR({key, jwkKey, iv, data, counterLength = 64}) {\n if (counterLength !== 64) {\n throw new Error(`Unsupported counter length: ${counterLength}`);\n }\n if (jwkKey) {\n key = jwkKeyToRaw(jwkKey);\n }\n const aesjs = this._aesjs;\n var aesCtr = new aesjs.ModeOfOperation.ctr(new Uint8Array(key), new aesjs.Counter(new Uint8Array(iv)));\n return aesCtr.decrypt(new Uint8Array(data));\n }\n\n async encryptCTR({key, jwkKey, iv, data}) {\n if (jwkKey) {\n key = jwkKeyToRaw(jwkKey);\n }\n const aesjs = this._aesjs;\n var aesCtr = new aesjs.ModeOfOperation.ctr(new Uint8Array(key), new aesjs.Counter(new Uint8Array(iv)));\n return aesCtr.encrypt(new Uint8Array(data));\n }\n\n /**\n * Generate a CTR key\n * @param {String} format \"raw\" or \"jwk\"\n * @param {Number} length 128 or 256\n * @return {Promise} an object for jwk, or a BufferSource for raw\n */\n async generateKey(format, length = 256) {\n let key = crypto.getRandomValues(new Uint8Array(length / 8));\n if (format === \"jwk\") {\n key = rawKeyToJwk(key);\n }\n return key;\n }\n\n async generateIV() {\n return generateIV(this._crypto);\n }\n}\n\nfunction hashName(name) {\n if (name !== \"SHA-256\" && name !== \"SHA-512\") {\n throw new Error(`Invalid hash name: ${name}`);\n }\n return name;\n}\n\nexport class Crypto {\n constructor(cryptoExtras) {\n const crypto = window.crypto || window.msCrypto;\n const subtleCrypto = crypto.subtle || crypto.webkitSubtle;\n this._subtleCrypto = subtleCrypto;\n // not exactly guaranteeing AES-CTR support\n // but in practice IE11 doesn't have this\n if (!subtleCrypto.deriveBits && cryptoExtras?.aesjs) {\n this.aes = new AESLegacyCrypto(cryptoExtras.aesjs, crypto);\n } else {\n this.aes = new AESCrypto(subtleCrypto, crypto);\n }\n this.hmac = new HMACCrypto(subtleCrypto);\n this.derive = new DeriveCrypto(subtleCrypto, this, cryptoExtras);\n }\n\n /**\n * [digest description]\n * @param {HashName} hash\n * @param {BufferSource} data\n * @return {BufferSource}\n */\n async digest(hash, data) {\n return await subtleCryptoResult(this._subtleCrypto.digest(hashName(hash), data));\n }\n\n digestSize(hash) {\n switch (hashName(hash)) {\n case \"SHA-512\": return 64;\n case \"SHA-256\": return 32;\n default: throw new Error(`Not implemented for ${hashName(hash)}`);\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport async function estimateStorageUsage() {\n if (navigator?.storage?.estimate) {\n const {quota, usage} = await navigator.storage.estimate();\n return {quota, usage};\n } else {\n return {quota: null, usage: null};\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../../utils/error\";\n\nclass WorkerState {\n constructor(worker) {\n this.worker = worker;\n this.busy = false;\n }\n\n attach(pool) {\n this.worker.addEventListener(\"message\", pool);\n this.worker.addEventListener(\"error\", pool);\n }\n\n detach(pool) {\n this.worker.removeEventListener(\"message\", pool);\n this.worker.removeEventListener(\"error\", pool);\n }\n}\n\nclass Request {\n constructor(message, pool) {\n this._promise = new Promise((_resolve, _reject) => {\n this._resolve = _resolve;\n this._reject = _reject;\n });\n this._message = message;\n this._pool = pool;\n this._worker = null;\n }\n\n abort() {\n if (this._isNotDisposed) {\n this._pool._abortRequest(this);\n this._dispose();\n }\n }\n\n response() {\n return this._promise;\n }\n\n _dispose() {\n this._reject = null;\n this._resolve = null;\n }\n\n get _isNotDisposed() {\n return this._resolve && this._reject;\n }\n}\n\nexport class WorkerPool {\n // TODO: extract DOM specific bits and write unit tests\n constructor(path, amount) {\n this._workers = [];\n for (let i = 0; i < amount ; ++i) {\n const worker = new WorkerState(new Worker(path));\n worker.attach(this);\n this._workers[i] = worker;\n }\n this._requests = new Map();\n this._counter = 0;\n this._pendingFlag = false;\n this._init = null;\n\n }\n\n init() {\n const promise = new Promise((resolve, reject) => {\n this._init = {resolve, reject};\n });\n this.sendAll({type: \"ping\"})\n .then(this._init.resolve, this._init.reject)\n .finally(() => {\n this._init = null;\n });\n return promise;\n }\n\n handleEvent(e) {\n if (e.type === \"message\") {\n const message = e.data;\n const request = this._requests.get(message.replyToId);\n if (request) {\n request._worker.busy = false;\n if (request._isNotDisposed) {\n if (message.type === \"success\") {\n request._resolve(message.payload);\n } else if (message.type === \"error\") {\n const err = new Error(message.message);\n err.stack = message.stack;\n request._reject(err);\n }\n request._dispose();\n }\n this._requests.delete(message.replyToId);\n }\n this._sendPending();\n } else if (e.type === \"error\") {\n if (this._init) {\n this._init.reject(new Error(\"worker error during init\"));\n }\n console.error(\"worker error\", e);\n }\n }\n\n _getPendingRequest() {\n for (const r of this._requests.values()) {\n if (!r._worker) {\n return r;\n }\n }\n }\n\n _getFreeWorker() {\n for (const w of this._workers) {\n if (!w.busy) {\n return w;\n }\n }\n }\n\n _sendPending() {\n this._pendingFlag = false;\n let success;\n do {\n success = false;\n const request = this._getPendingRequest();\n if (request) {\n const worker = this._getFreeWorker();\n if (worker) {\n this._sendWith(request, worker);\n success = true;\n }\n }\n } while (success);\n }\n\n _sendWith(request, worker) {\n request._worker = worker;\n worker.busy = true;\n worker.worker.postMessage(request._message);\n }\n\n _enqueueRequest(message) {\n this._counter += 1;\n message.id = this._counter;\n const request = new Request(message, this);\n this._requests.set(message.id, request);\n return request;\n }\n\n send(message) {\n const request = this._enqueueRequest(message);\n const worker = this._getFreeWorker();\n if (worker) {\n this._sendWith(request, worker);\n }\n return request;\n }\n\n // assumes all workers are free atm\n sendAll(message) {\n const promises = this._workers.map(worker => {\n const request = this._enqueueRequest(Object.assign({}, message));\n this._sendWith(request, worker);\n return request.response();\n });\n return Promise.all(promises);\n }\n\n dispose() {\n for (const w of this._workers) {\n w.detach(this);\n w.worker.terminate();\n }\n }\n\n _trySendPendingInNextTick() {\n if (!this._pendingFlag) {\n this._pendingFlag = true;\n Promise.resolve().then(() => {\n this._sendPending();\n });\n }\n }\n\n _abortRequest(request) {\n request._reject(new AbortError());\n if (request._worker) {\n request._worker.busy = false;\n }\n this._requests.delete(request._message.id);\n // allow more requests to be aborted before trying to send other pending\n this._trySendPendingInNextTick();\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BlobHandle} from \"./BlobHandle.js\";\nimport {domEventAsPromise} from \"./utils\";\n\nexport class ImageHandle {\n static async fromBlob(blob) {\n const img = await loadImgFromBlob(blob);\n const {width, height} = img;\n return new ImageHandle(blob, width, height, img);\n }\n\n constructor(blob, width, height, imgElement) {\n this.blob = blob;\n this.width = width;\n this.height = height;\n this._domElement = imgElement;\n }\n\n get maxDimension() {\n return Math.max(this.width, this.height);\n }\n\n async _getDomElement() {\n if (!this._domElement) {\n this._domElement = await loadImgFromBlob(this.blob);\n }\n return this._domElement;\n }\n\n async scale(maxDimension) {\n const aspectRatio = this.width / this.height;\n const scaleFactor = Math.min(1, maxDimension / (aspectRatio >= 1 ? this.width : this.height));\n const scaledWidth = Math.round(this.width * scaleFactor);\n const scaledHeight = Math.round(this.height * scaleFactor);\n const canvas = document.createElement(\"canvas\");\n canvas.width = scaledWidth;\n canvas.height = scaledHeight;\n const ctx = canvas.getContext(\"2d\");\n const drawableElement = await this._getDomElement();\n ctx.drawImage(drawableElement, 0, 0, scaledWidth, scaledHeight);\n let mimeType = this.blob.mimeType === \"image/jpeg\" ? \"image/jpeg\" : \"image/png\";\n let nativeBlob;\n if (canvas.toBlob) {\n nativeBlob = await new Promise(resolve => canvas.toBlob(resolve, mimeType));\n } else if (canvas.msToBlob) {\n // TODO: provide a mimetype override in blob handle for this case\n mimeType = \"image/png\";\n nativeBlob = canvas.msToBlob();\n } else {\n throw new Error(\"canvas can't be turned into blob\");\n }\n // unsafe is ok because it's a jpeg or png image\n const blob = BlobHandle.fromBlobUnsafe(nativeBlob);\n return new ImageHandle(blob, scaledWidth, scaledHeight, null);\n }\n\n dispose() {\n this.blob.dispose();\n }\n}\n\nexport class VideoHandle extends ImageHandle {\n get duration() {\n if (typeof this._domElement.duration === \"number\") {\n return Math.round(this._domElement.duration * 1000);\n }\n return undefined;\n }\n\n static async fromBlob(blob) {\n const video = await loadVideoFromBlob(blob);\n const {videoWidth, videoHeight} = video;\n return new VideoHandle(blob, videoWidth, videoHeight, video);\n }\n}\n\nexport function hasReadPixelPermission() {\n const canvas = document.createElement(\"canvas\");\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext(\"2d\");\n const rgb = [\n Math.round(Math.random() * 255),\n Math.round(Math.random() * 255),\n Math.round(Math.random() * 255),\n ]\n ctx.fillStyle = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;\n ctx.fillRect(0, 0, 1, 1);\n const data = ctx.getImageData(0, 0, 1, 1).data;\n return data[0] === rgb[0] && data[1] === rgb[1] && data[2] === rgb[2];\n}\n\nasync function loadImgFromBlob(blob) {\n const img = document.createElement(\"img\");\n const loadPromise = domEventAsPromise(img, \"load\");\n img.src = blob.url;\n await loadPromise;\n return img;\n}\n\nasync function loadVideoFromBlob(blob) {\n const video = document.createElement(\"video\");\n video.muted = true;\n const loadPromise = domEventAsPromise(video, \"loadedmetadata\");\n video.src = blob.url;\n video.load();\n await loadPromise;\n // seek to the first 1/10s to make sure that drawing the video\n // on a canvas won't give a blank image\n const seekPromise = domEventAsPromise(video, \"seeked\");\n // needed for safari to reliably fire the seeked event,\n // somewhat hacky but using raf for example didn't do the trick\n await new Promise(r => setTimeout(r, 200));\n video.currentTime = 0.1;\n await seekPromise;\n return video;\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport async function downloadInIframe(container, iframeSrc, blobHandle, filename, isIOS) {\n let iframe = container.querySelector(\"iframe.downloadSandbox\");\n if (!iframe) {\n iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\"sandbox\", \"allow-scripts allow-downloads allow-downloads-without-user-activation\");\n iframe.setAttribute(\"src\", iframeSrc);\n iframe.className = \"hidden downloadSandbox\";\n container.appendChild(iframe);\n let detach;\n await new Promise((resolve, reject) => {\n detach = () => {\n iframe.removeEventListener(\"load\", resolve);\n iframe.removeEventListener(\"error\", reject); \n }\n iframe.addEventListener(\"load\", resolve);\n iframe.addEventListener(\"error\", reject);\n });\n detach();\n }\n if (isIOS) {\n // iOS can't read a blob in a sandboxed iframe,\n // see https://github.com/vector-im/hydrogen-web/issues/244\n const buffer = await blobHandle.readAsBuffer();\n iframe.contentWindow.postMessage({\n type: \"downloadBuffer\",\n buffer,\n mimeType: blobHandle.mimeType,\n filename: filename\n }, \"*\");\n } else {\n iframe.contentWindow.postMessage({\n type: \"downloadBlob\",\n blob: blobHandle.nativeBlob,\n filename: filename\n }, \"*\");\n }\n}\n","/*! @license DOMPurify 2.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.0/LICENSE */\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar hasOwnProperty = Object.hasOwnProperty,\n setPrototypeOf = Object.setPrototypeOf,\n isFrozen = Object.isFrozen,\n getPrototypeOf = Object.getPrototypeOf,\n getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar freeze = Object.freeze,\n seal = Object.seal,\n create = Object.create; // eslint-disable-line import/no-mutable-exports\n\nvar _ref = typeof Reflect !== 'undefined' && Reflect,\n apply = _ref.apply,\n construct = _ref.construct;\n\nif (!apply) {\n apply = function apply(fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\n\nif (!construct) {\n construct = function construct(Func, args) {\n return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))();\n };\n}\n\nvar arrayForEach = unapply(Array.prototype.forEach);\nvar arrayPop = unapply(Array.prototype.pop);\nvar arrayPush = unapply(Array.prototype.push);\n\nvar stringToLowerCase = unapply(String.prototype.toLowerCase);\nvar stringMatch = unapply(String.prototype.match);\nvar stringReplace = unapply(String.prototype.replace);\nvar stringIndexOf = unapply(String.prototype.indexOf);\nvar stringTrim = unapply(String.prototype.trim);\n\nvar regExpTest = unapply(RegExp.prototype.test);\n\nvar typeErrorCreate = unconstruct(TypeError);\n\nfunction unapply(func) {\n return function (thisArg) {\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return apply(func, thisArg, args);\n };\n}\n\nfunction unconstruct(func) {\n return function () {\n for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n return construct(func, args);\n };\n}\n\n/* Add properties to a lookup table */\nfunction addToSet(set, array) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n var l = array.length;\n while (l--) {\n var element = array[l];\n if (typeof element === 'string') {\n var lcElement = stringToLowerCase(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/* Shallow clone an object */\nfunction clone(object) {\n var newObject = create(null);\n\n var property = void 0;\n for (property in object) {\n if (apply(hasOwnProperty, object, [property])) {\n newObject[property] = object[property];\n }\n }\n\n return newObject;\n}\n\n/* IE10 doesn't support __lookupGetter__ so lets'\n * simulate it. It also automatically checks\n * if the prop is function or getter and behaves\n * accordingly. */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n var desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(element) {\n console.warn('fallback value for', element);\n return null;\n }\n\n return fallbackValue;\n}\n\nvar html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\n\n// SVG\nvar svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\n\nvar svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nvar svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'feimage', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\n\nvar mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nvar mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\n\nvar text = freeze(['#text']);\n\nvar html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']);\n\nvar svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\n\nvar mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\n\nvar xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nvar MUSTACHE_EXPR = seal(/\\{\\{[\\s\\S]*|[\\s\\S]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nvar ERB_EXPR = seal(/<%[\\s\\S]*|[\\s\\S]*%>/gm);\nvar DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nvar ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nvar IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nvar IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nvar ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {Document} document The document object (to determine policy name suffix)\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported).\n */\nvar _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {\n if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n var suffix = null;\n var ATTR_NAME = 'data-tt-policy-suffix';\n if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {\n suffix = document.currentScript.getAttribute(ATTR_NAME);\n }\n\n var policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML: function createHTML(html$$1) {\n return html$$1;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\n\nfunction createDOMPurify() {\n var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n\n var DOMPurify = function DOMPurify(root) {\n return createDOMPurify(root);\n };\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = '2.3.0';\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n var originalDocument = window.document;\n\n var document = window.document;\n var DocumentFragment = window.DocumentFragment,\n HTMLTemplateElement = window.HTMLTemplateElement,\n Node = window.Node,\n Element = window.Element,\n NodeFilter = window.NodeFilter,\n _window$NamedNodeMap = window.NamedNodeMap,\n NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,\n Text = window.Text,\n Comment = window.Comment,\n DOMParser = window.DOMParser,\n trustedTypes = window.trustedTypes;\n\n\n var ElementPrototype = Element.prototype;\n\n var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n var getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n var template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);\n var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : '';\n\n var _document = document,\n implementation = _document.implementation,\n createNodeIterator = _document.createNodeIterator,\n createDocumentFragment = _document.createDocumentFragment,\n getElementsByTagName = _document.getElementsByTagName;\n var importNode = originalDocument.importNode;\n\n\n var documentMode = {};\n try {\n documentMode = clone(document).documentMode ? document.documentMode : {};\n } catch (_) {}\n\n var hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;\n\n var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,\n ERB_EXPR$$1 = ERB_EXPR,\n DATA_ATTR$$1 = DATA_ATTR,\n ARIA_ATTR$$1 = ARIA_ATTR,\n IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE$$1 = ATTR_WHITESPACE;\n var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n\n var ALLOWED_TAGS = null;\n var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text)));\n\n /* Allowed attribute names */\n var ALLOWED_ATTR = null;\n var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n var FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n var FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n var ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n var ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n var ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n var SAFE_FOR_TEMPLATES = false;\n\n /* Decide if document with ... should be returned */\n var WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n var SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n var FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n var RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n var RETURN_DOM_FRAGMENT = false;\n\n /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM\n * `Node` is imported into the current `Document`. If this flag is not enabled the\n * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by\n * DOMPurify.\n *\n * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`\n * might cause XSS from attacks hidden in closed shadowroots in case the browser\n * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/\n */\n var RETURN_DOM_IMPORT = true;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n var RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks? */\n var SANITIZE_DOM = true;\n\n /* Keep element content when removing element? */\n var KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n var IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n var USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n var FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n\n /* Tags that are safe for data: URIs */\n var DATA_URI_TAGS = null;\n var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n\n /* Attributes safe for values like \"javascript:\" */\n var URI_SAFE_ATTRIBUTES = null;\n var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'summary', 'title', 'value', 'style', 'xmlns']);\n\n var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n var NAMESPACE = HTML_NAMESPACE;\n var IS_EMPTY_INPUT = false;\n\n /* Keep a reference to config to pass to hooks */\n var CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n var formElement = document.createElement('form');\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n var _parseConfig = function _parseConfig(cfg) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n /* Set configuration parameters */\n ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;\n URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text)));\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html);\n addToSet(ALLOWED_ATTR, html$1);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg);\n addToSet(ALLOWED_ATTR, svg$1);\n addToSet(ALLOWED_ATTR, xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg$1);\n addToSet(ALLOWED_ATTR, xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl);\n addToSet(ALLOWED_ATTR, mathMl$1);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n\n var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n var ALL_SVG_TAGS = addToSet({}, svg);\n addToSet(ALL_SVG_TAGS, svgFilters);\n addToSet(ALL_SVG_TAGS, svgDisallowed);\n\n var ALL_MATHML_TAGS = addToSet({}, mathMl);\n addToSet(ALL_MATHML_TAGS, mathMlDisallowed);\n\n /**\n *\n *\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n var _checkValidNamespace = function _checkValidNamespace(element) {\n var parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: HTML_NAMESPACE,\n tagName: 'template'\n };\n }\n\n var tagName = stringToLowerCase(element.tagName);\n var parentTagName = stringToLowerCase(parent.tagName);\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via\n // svg if parent is either or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erronously deleted from\n // HTML namespace.\n var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG or MathML). Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n var _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, { element: node });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n node.parentNode.removeChild(node);\n } catch (_) {\n try {\n node.outerHTML = emptyHTML;\n } catch (_) {\n node.remove();\n }\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n var _removeAttribute = function _removeAttribute(name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node\n });\n }\n\n node.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\"\" attributes\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n var _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n var doc = void 0;\n var leadingWhitespace = void 0;\n\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n var matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n var body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * _createIterator\n *\n * @param {Document} root document/fragment to create iterator for\n * @return {Iterator} iterator instance\n */\n var _createIterator = function _createIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n var _isClobbered = function _isClobbered(elm) {\n if (elm instanceof Text || elm instanceof Comment) {\n return false;\n }\n\n if (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function') {\n return true;\n }\n\n return false;\n };\n\n /**\n * _isNode\n *\n * @param {Node} obj object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n var _isNode = function _isNode(object) {\n return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n var _executeHook = function _executeHook(entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], function (hook) {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n var _sanitizeElements = function _sanitizeElements(currentNode) {\n var content = void 0;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check if tagname contains Unicode */\n if (stringMatch(currentNode.nodeName, /[\\u0080-\\uFFFF]/)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n var tagName = stringToLowerCase(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName: tagName,\n allowedTags: ALLOWED_TAGS\n });\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\\w]/g, currentNode.innerHTML) && regExpTest(/<[/\\w]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n var parentNode = getParentNode(currentNode) || currentNode.parentNode;\n var childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n\n if (childNodes && parentNode) {\n var childCount = childNodes.length;\n\n for (var i = childCount - 1; i >= 0; --i) {\n parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\\/no(script|embed)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {\n /* Get the element's text content */\n content = currentNode.textContent;\n content = stringReplace(content, MUSTACHE_EXPR$$1, ' ');\n content = stringReplace(content, ERB_EXPR$$1, ' ');\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n return false;\n\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if (!value) ; else {\n return false;\n }\n\n return true;\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n var attr = void 0;\n var value = void 0;\n var lcName = void 0;\n var l = void 0;\n /* Execute a hook if present */\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n var attributes = currentNode.attributes;\n\n /* Check if we have attributes; if not we might have a text node */\n\n if (!attributes) {\n return;\n }\n\n var hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR\n };\n l = attributes.length;\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n attr = attributes[l];\n var _attr = attr,\n name = _attr.name,\n namespaceURI = _attr.namespaceURI;\n\n value = stringTrim(attr.value);\n lcName = stringToLowerCase(name);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n value = stringReplace(value, MUSTACHE_EXPR$$1, ' ');\n value = stringReplace(value, ERB_EXPR$$1, ' ');\n }\n\n /* Is `value` valid for this attribute? */\n var lcTag = currentNode.nodeName.toLowerCase();\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n arrayPop(DOMPurify.removed);\n } catch (_) {}\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n var shadowNode = void 0;\n var shadowIterator = _createIterator(fragment);\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(shadowNode);\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} configuration object\n */\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg) {\n var body = void 0;\n var importedNode = void 0;\n var currentNode = void 0;\n var oldNode = void 0;\n var returnNode = void 0;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n // eslint-disable-next-line no-negated-condition\n if (typeof dirty.toString !== 'function') {\n throw typeErrorCreate('toString is not a function');\n } else {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n }\n }\n\n /* Check we can run. Otherwise fall back or ignore */\n if (!DOMPurify.isSupported) {\n if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {\n if (typeof dirty === 'string') {\n return window.toStaticHTML(dirty);\n }\n\n if (_isNode(dirty)) {\n return window.toStaticHTML(dirty.outerHTML);\n }\n }\n\n return dirty;\n }\n\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) ; else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : emptyHTML;\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n var nodeIterator = _createIterator(IN_PLACE ? dirty : body);\n\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Fix IE's strange behavior with manipulated textNodes #89 */\n if (currentNode.nodeType === 3 && currentNode === oldNode) {\n continue;\n }\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(currentNode);\n\n oldNode = currentNode;\n }\n\n oldNode = null;\n\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (RETURN_DOM_IMPORT) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');\n serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, ' ');\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n DOMPurify.setConfig = function (cfg) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {string} tag Tag name of containing element.\n * @param {string} attr Attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n var lcTag = stringToLowerCase(tag);\n var lcName = stringToLowerCase(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n */\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n arrayPop(hooks[entryPoint]);\n }\n };\n\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n *\n */\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n}\n\nvar purify = createDOMPurify();\n\nexport default purify;\n//# sourceMappingURL=purify.es.js.map\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport DOMPurify from \"dompurify\"\n\nclass HTMLParseResult {\n constructor(bodyNode) {\n this._bodyNode = bodyNode;\n }\n\n get rootNodes() {\n return Array.from(this._bodyNode.childNodes);\n }\n \n getChildNodes(node) {\n return Array.from(node.childNodes);\n }\n\n getAttributeNames(node) {\n return Array.from(node.getAttributeNames());\n }\n\n getAttributeValue(node, attr) {\n return node.getAttribute(attr);\n }\n\n isTextNode(node) { \n return node.nodeType === Node.TEXT_NODE;\n }\n\n getNodeText(node) {\n return node.textContent;\n }\n\n isElementNode(node) {\n return node.nodeType === Node.ELEMENT_NODE;\n }\n\n getNodeElementName(node) {\n return node.tagName;\n }\n}\n\nconst sanitizeConfig = {\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx|mxc):|[^a-z]|[a-z+.-]+(?:[^a-z+.-:]|$))/i,\n FORBID_TAGS: ['mx-reply'],\n KEEP_CONTENT: false,\n}\n\nexport function parseHTML(html) {\n // If DOMPurify uses DOMParser, can't we just get the built tree from it\n // instead of re-parsing?\n const sanitized = DOMPurify.sanitize(html, sanitizeConfig);\n const bodyNode = new DOMParser().parseFromString(`${sanitized}`, \"text/html\").body;\n return new HTMLParseResult(bodyNode);\n}\n","/*\nCopyright 2021 Šimon Brandner \nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {MediaDevices as IMediaDevices, Stream, Track, TrackKind, VolumeMeasurer} from \"../../types/MediaDevices\";\n\nconst POLLING_INTERVAL = 200; // ms\nexport const SPEAKING_THRESHOLD = -60; // dB\nconst SPEAKING_SAMPLE_COUNT = 8; // samples\n\nexport class MediaDevicesWrapper implements IMediaDevices {\n constructor(private readonly mediaDevices: MediaDevices) {}\n\n enumerate(): Promise {\n return this.mediaDevices.enumerateDevices();\n }\n\n async getMediaTracks(audio: true | MediaDeviceInfo, video: boolean | MediaDeviceInfo): Promise {\n const stream = await this.mediaDevices.getUserMedia(this.getUserMediaContraints(audio, video));\n stream.addEventListener(\"removetrack\", evt => {\n console.log(`removing track ${evt.track.id} (${evt.track.kind}) from stream ${stream.id}`);\n });\n return stream as Stream;\n }\n\n async getScreenShareTrack(): Promise {\n const stream = await this.mediaDevices.getDisplayMedia(this.getScreenshareContraints());\n return stream as Stream;\n }\n\n private getUserMediaContraints(audio: boolean | MediaDeviceInfo, video: boolean | MediaDeviceInfo): MediaStreamConstraints {\n const isWebkit = !!navigator[\"webkitGetUserMedia\"];\n\n return {\n audio: audio\n ? {\n deviceId: typeof audio !== \"boolean\" ? { ideal: audio.deviceId } : undefined,\n }\n : false,\n video: video\n ? {\n deviceId: typeof video !== \"boolean\" ? { ideal: video.deviceId } : undefined,\n /* We want 640x360. Chrome will give it only if we ask exactly,\n FF refuses entirely if we ask exactly, so have to ask for ideal\n instead\n XXX: Is this still true?\n */\n width: isWebkit ? { exact: 640 } : { ideal: 640 },\n height: isWebkit ? { exact: 360 } : { ideal: 360 },\n }\n : false,\n };\n }\n\n private getScreenshareContraints(): MediaStreamConstraints {\n return {\n audio: false,\n video: true,\n };\n }\n\n createVolumeMeasurer(stream: Stream, callback: () => void): VolumeMeasurer {\n return new WebAudioVolumeMeasurer(stream as MediaStream, callback);\n }\n}\n\nexport class WebAudioVolumeMeasurer implements VolumeMeasurer {\n private measuringVolumeActivity = false;\n private audioContext?: AudioContext;\n private analyser: AnalyserNode;\n private frequencyBinCount: Float32Array;\n private speakingThreshold = SPEAKING_THRESHOLD;\n private speaking = false;\n private volumeLooperTimeout: number;\n private speakingVolumeSamples: number[];\n private callback: () => void;\n private stream: MediaStream;\n\n constructor(stream: MediaStream, callback: () => void) {\n this.stream = stream;\n this.callback = callback;\n this.speakingVolumeSamples = new Array(SPEAKING_SAMPLE_COUNT).fill(-Infinity);\n this.initVolumeMeasuring();\n this.measureVolumeActivity(true);\n }\n\n get isSpeaking(): boolean { return this.speaking; }\n /**\n * Starts emitting volume_changed events where the emitter value is in decibels\n * @param enabled emit volume changes\n */\n private measureVolumeActivity(enabled: boolean): void {\n if (enabled) {\n if (!this.audioContext || !this.analyser || !this.frequencyBinCount) return;\n\n this.measuringVolumeActivity = true;\n this.volumeLooper();\n } else {\n this.measuringVolumeActivity = false;\n this.speakingVolumeSamples.fill(-Infinity);\n this.callback();\n // this.emit(CallFeedEvent.VolumeChanged, -Infinity);\n }\n }\n\n private initVolumeMeasuring(): void {\n const AudioContext = window.AudioContext || window[\"webkitAudioContext\"] as undefined | typeof window.AudioContext;\n if (!AudioContext) return;\n\n this.audioContext = new AudioContext();\n\n this.analyser = this.audioContext.createAnalyser();\n this.analyser.fftSize = 512;\n this.analyser.smoothingTimeConstant = 0.1;\n\n const mediaStreamAudioSourceNode = this.audioContext.createMediaStreamSource(this.stream);\n mediaStreamAudioSourceNode.connect(this.analyser);\n\n this.frequencyBinCount = new Float32Array(this.analyser.frequencyBinCount);\n }\n\n public setSpeakingThreshold(threshold: number) {\n this.speakingThreshold = threshold;\n }\n\n private volumeLooper = () => {\n if (!this.analyser) return;\n\n if (!this.measuringVolumeActivity) return;\n\n this.analyser.getFloatFrequencyData(this.frequencyBinCount);\n\n let maxVolume = -Infinity;\n for (let i = 0; i < this.frequencyBinCount.length; i++) {\n if (this.frequencyBinCount[i] > maxVolume) {\n maxVolume = this.frequencyBinCount[i];\n }\n }\n\n this.speakingVolumeSamples.shift();\n this.speakingVolumeSamples.push(maxVolume);\n\n this.callback();\n // this.emit(CallFeedEvent.VolumeChanged, maxVolume);\n\n let newSpeaking = false;\n\n for (let i = 0; i < this.speakingVolumeSamples.length; i++) {\n const volume = this.speakingVolumeSamples[i];\n\n if (volume > this.speakingThreshold) {\n newSpeaking = true;\n break;\n }\n }\n\n if (this.speaking !== newSpeaking) {\n this.speaking = newSpeaking;\n this.callback();\n // this.emit(CallFeedEvent.Speaking, this.speaking);\n }\n\n this.volumeLooperTimeout = setTimeout(this.volumeLooper, POLLING_INTERVAL) as unknown as number;\n };\n\n public stop(): void {\n clearTimeout(this.volumeLooperTimeout);\n this.analyser.disconnect();\n this.audioContext?.close();\n }\n}\n","/*\nCopyright 2021 Šimon Brandner \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {Stream, Track, TrackKind} from \"../../types/MediaDevices\";\nimport {WebRTC, Sender, PeerConnection} from \"../../types/WebRTC\";\nimport {SDPStreamMetadataPurpose} from \"../../../matrix/calls/callEventTypes\";\n\nconst POLLING_INTERVAL = 200; // ms\nexport const SPEAKING_THRESHOLD = -60; // dB\nconst SPEAKING_SAMPLE_COUNT = 8; // samples\n\nexport class DOMWebRTC implements WebRTC {\n createPeerConnection(forceTURN: boolean, turnServers: RTCIceServer[], iceCandidatePoolSize): PeerConnection {\n const peerConn = new RTCPeerConnection({\n iceTransportPolicy: forceTURN ? 'relay' : undefined,\n iceServers: turnServers,\n iceCandidatePoolSize: iceCandidatePoolSize,\n }) as PeerConnection;\n return new Proxy(peerConn, {\n get(target, prop, receiver) {\n if (prop === \"close\") {\n console.trace(\"calling peerConnection.close\");\n }\n const value = target[prop];\n if (typeof value === \"function\") {\n return value.bind(target);\n } else {\n return value;\n }\n }\n });\n }\n\n prepareSenderForPurpose(peerConnection: PeerConnection, sender: Sender, purpose: SDPStreamMetadataPurpose): void {\n if (purpose === SDPStreamMetadataPurpose.Screenshare) {\n this.getRidOfRTXCodecs(peerConnection as RTCPeerConnection, sender as RTCRtpSender);\n }\n }\n\n private getRidOfRTXCodecs(peerConnection: RTCPeerConnection, sender: RTCRtpSender): void {\n // RTCRtpReceiver.getCapabilities and RTCRtpSender.getCapabilities don't seem to be supported on FF\n if (!RTCRtpReceiver.getCapabilities || !RTCRtpSender.getCapabilities) return;\n\n const recvCodecs = RTCRtpReceiver.getCapabilities(\"video\")?.codecs ?? [];\n const sendCodecs = RTCRtpSender.getCapabilities(\"video\")?.codecs ?? [];\n const codecs = [...sendCodecs, ...recvCodecs];\n\n for (const codec of codecs) {\n if (codec.mimeType === \"video/rtx\") {\n const rtxCodecIndex = codecs.indexOf(codec);\n codecs.splice(rtxCodecIndex, 1);\n }\n }\n\n const transceiver = peerConnection.getTransceivers().find(t => t.sender === sender);\n if (transceiver && (\n transceiver.sender.track?.kind === \"video\" ||\n transceiver.receiver.track?.kind === \"video\"\n )\n ) {\n transceiver.setCodecPreferences(codecs);\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport type NormalVariant = {\n id: string;\n cssLocation: string;\n variables?: any;\n};\n\nexport type Variant = NormalVariant & {\n variantName: string;\n};\n\nexport type DefaultVariant = {\n dark: Variant;\n light: Variant;\n default: Variant;\n}\n\nexport type ThemeInformation = NormalVariant | DefaultVariant; \n\nexport enum ColorSchemePreference {\n Dark,\n Light\n};\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function getColoredSvgString(svgString, primaryColor, secondaryColor) {\n let coloredSVGCode = svgString.replaceAll(\"#ff00ff\", primaryColor);\n coloredSVGCode = coloredSVGCode.replaceAll(\"#00ffff\", secondaryColor);\n if (svgString === coloredSVGCode) {\n throw new Error(\"svg-colorizer made no color replacements! The input svg should only contain colors #ff00ff (primary, case-sensitive) and #00ffff (secondary, case-sensitive).\");\n }\n return coloredSVGCode;\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {Platform} from \"../Platform.js\";\nimport {getColoredSvgString} from \"./shared/svg-colorizer.mjs\";\n\ntype ParsedStructure = {\n [variableName: string]: {\n svg: Promise<{ status: number; body: string }>;\n primary: string | null;\n secondary: string | null;\n };\n};\n\nexport class IconColorizer {\n private _iconVariables: Record;\n private _resolvedVariables: Record;\n private _manifestLocation: string;\n private _platform: Platform;\n\n constructor(platform: Platform, iconVariables: Record, resolvedVariables: Record, manifestLocation: string) {\n this._platform = platform;\n this._iconVariables = iconVariables;\n this._resolvedVariables = resolvedVariables;\n this._manifestLocation = manifestLocation;\n }\n\n async toVariables(): Promise> {\n const { parsedStructure, promises } = await this._fetchAndParseIcons();\n await Promise.all(promises);\n return this._produceColoredIconVariables(parsedStructure);\n }\n\n private async _fetchAndParseIcons(): Promise<{ parsedStructure: ParsedStructure, promises: any[] }> {\n const promises: any[] = [];\n const parsedStructure: ParsedStructure = {};\n for (const [variable, url] of Object.entries(this._iconVariables)) {\n const urlObject = new URL(`https://${url}`);\n const pathWithoutQueryParams = urlObject.hostname;\n const relativePath = new URL(pathWithoutQueryParams, new URL(this._manifestLocation, window.location.origin));\n const responsePromise = this._platform.request(relativePath, { method: \"GET\", format: \"text\", cache: true, }).response()\n promises.push(responsePromise);\n const searchParams = urlObject.searchParams;\n parsedStructure[variable] = {\n svg: responsePromise,\n primary: searchParams.get(\"primary\"),\n secondary: searchParams.get(\"secondary\")\n };\n }\n return { parsedStructure, promises };\n }\n\n private async _produceColoredIconVariables(parsedStructure: ParsedStructure): Promise> {\n let coloredVariables: Record = {};\n for (const [variable, { svg, primary, secondary }] of Object.entries(parsedStructure)) {\n const { body: svgCode } = await svg;\n if (!primary) {\n throw new Error(`Primary color variable ${primary} not in list of variables!`);\n }\n const primaryColor = this._resolvedVariables[primary], secondaryColor = this._resolvedVariables[secondary!];\n const coloredSvgCode = getColoredSvgString(svgCode, primaryColor, secondaryColor);\n const dataURI = `url('data:image/svg+xml;utf8,${encodeURIComponent(coloredSvgCode)}')`;\n coloredVariables[variable] = dataURI;\n }\n return coloredVariables;\n }\n}\n","module.exports=function(n){var t={};function r(e){if(t[e])return t[e].exports;var o=t[e]={i:e,l:!1,exports:{}};return n[e].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:e})},r.r=function(n){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(n,\"__esModule\",{value:!0})},r.t=function(n,t){if(1&t&&(n=r(n)),8&t)return n;if(4&t&&\"object\"==typeof n&&n&&n.__esModule)return n;var e=Object.create(null);if(r.r(e),Object.defineProperty(e,\"default\",{enumerable:!0,value:n}),2&t&&\"string\"!=typeof n)for(var o in n)r.d(e,o,function(t){return n[t]}.bind(null,o));return e},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,\"a\",t),t},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},r.p=\"\",r(r.s=0)}([function(n,t,r){\"use strict\";function e(n){let t,r;const e={light:function(){return!a()},dark:a,lighten:d,darken:l,saturate:p,desaturate:function(n=0){return p(n*=-1)},increaseContrast:function(n=0){return b(n*=-1)},decreaseContrast:b,active:function(){return b(.123)},highlight:function(){return b(.1)},selected:function(){return b(.066)},text:function(){return r=s()?o(\"#333333\"):o(\"#FFFFFF\"),e},shadow:function(){return r=s()?o(\"#000000\"):o(\"#FFFFFF\"),e},hex:function(){const n=r;return r=t,\"#\"+n.map(n=>parseInt(n+\"\",10).toString(16).padStart(2,\"0\")).join(\"\")},rgb:function(){const n=r;return r=t,`rgb(${n.join()})`},rgba:function(n=1){const e=r;return r=t,`rgba(${e.join()}, ${n})`},setHex:c,setRgb:function(n=[0,0,0]){let[o,u,c]=n;return o=f(o,0,255),u=f(u,0,255),c=f(c,0,255),t=[o,u,c],r=[o,u,c],e}};function c(n=\"#000000\"){return t=o(n),r=t,e}function a(){const[n,e,o]=r;return r=t,(299*n+587*e+114*o)/1e3<128}function s(){const[n,t,e]=r;return(299*n+587*t+114*e)/1e3>=128}function l(n=0){return d(n*=-1)}function d(n=0){let[t,o,c]=i(r);return c=f(c+n,0,1),r=u([t,o,c]),e}function p(n=0){let[t,o,c]=i(r);return o=f(o+n,0,1),r=u([t,o,c]),e}function b(n=0){return s()?l(n):d(n)}return c(n),e}function o(n){if(\"string\"!=typeof n)throw new TypeError(\"Expected a string\");3===(n=n.replace(/^#/,\"\")).length&&(n=n[0]+n[0]+n[1]+n[1]+n[2]+n[2]);var t=parseInt(n,16);return[t>>16,t>>8&255,255&t]}function u(n){const[t,r,e]=n;let o,u,c;if(0===r)o=u=c=e;else{const n=function(n,t,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?n+6*(t-n)*r:r<.5?t:r<2/3?n+(t-n)*(2/3-r)*6:n},i=e<.5?e*(1+r):e+r-e*r,a=2*e-i;o=f(n(a,i,t+1/3),0,1),u=f(n(a,i,t),0,1),c=f(n(a,i,t-1/3),0,1)}return[Math.round(255*o),Math.round(255*u),Math.round(255*c)]}r.r(t),r.d(t,\"offColor\",(function(){return e})),r.d(t,\"hexRgb\",(function(){return o})),r.d(t,\"hslToRgb\",(function(){return u})),r.d(t,\"color\",(function(){return c})),r.d(t,\"rgbToHsl\",(function(){return i}));const c=e;function i(n){const t=n[0]/255,r=n[1]/255,e=n[2]/255,o=Math.max(t,r,e),u=Math.min(t,r,e);let c=(o+u)/2,i=(o+u)/2;const f=(o+u)/2;if(o===u)c=i=0;else{const n=o-u;switch(i=f>.5?n/(2-o-u):n/(o+u),o){case t:c=(r-e)/n+(r=t?n:t}}]);","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/index.min.js');\n} else {\n module.exports = require('./cjs/index.js');\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport * as pkg from 'off-color';\nconst offColor = pkg.offColor ?? pkg.default.offColor;\n\nexport function derive(value, operation, argument, isDark) {\n const argumentAsNumber = parseInt(argument);\n if (isDark) {\n // For dark themes, invert the operation\n if (operation === 'darker') {\n operation = \"lighter\";\n }\n else if (operation === 'lighter') {\n operation = \"darker\";\n }\n }\n switch (operation) {\n case \"darker\": {\n const newColorString = offColor(value).darken(argumentAsNumber / 100).hex();\n return newColorString;\n }\n case \"lighter\": {\n const newColorString = offColor(value).lighten(argumentAsNumber / 100).hex();\n return newColorString;\n }\n case \"alpha\": {\n return offColor(value).rgba(argumentAsNumber / 100);\n }\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n \nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {derive} from \"./shared/color.mjs\";\n\nexport class DerivedVariables {\n private _baseVariables: Record;\n private _variablesToDerive: string[]\n private _isDark: boolean\n private _aliases: Record = {};\n private _derivedAliases: string[] = [];\n\n constructor(baseVariables: Record, variablesToDerive: string[], isDark: boolean) {\n this._baseVariables = baseVariables;\n this._variablesToDerive = variablesToDerive;\n this._isDark = isDark;\n }\n\n toVariables(): Record {\n const resolvedVariables: any = {};\n this._detectAliases();\n for (const variable of this._variablesToDerive) {\n const resolvedValue = this._derive(variable);\n if (resolvedValue) {\n resolvedVariables[variable] = resolvedValue;\n }\n }\n for (const [alias, variable] of Object.entries(this._aliases) as any) {\n resolvedVariables[alias] = this._baseVariables[variable] ?? resolvedVariables[variable];\n }\n for (const variable of this._derivedAliases) {\n const resolvedValue = this._deriveAlias(variable, resolvedVariables);\n if (resolvedValue) {\n resolvedVariables[variable] = resolvedValue;\n }\n }\n return resolvedVariables;\n }\n\n private _detectAliases(): void {\n const newVariablesToDerive: string[] = [];\n for (const variable of this._variablesToDerive) {\n const [alias, value] = variable.split(\"=\");\n if (value) {\n this._aliases[alias] = value;\n }\n else {\n newVariablesToDerive.push(variable);\n }\n }\n this._variablesToDerive = newVariablesToDerive;\n }\n\n private _derive(variable: string): string | undefined {\n const RE_VARIABLE_VALUE = /(.+)--(.+)-(.+)/;\n const matches = variable.match(RE_VARIABLE_VALUE);\n if (matches) {\n const [, baseVariable, operation, argument] = matches;\n const value = this._baseVariables[baseVariable];\n if (!value ) {\n if (this._aliases[baseVariable]) {\n this._derivedAliases.push(variable);\n return;\n }\n else {\n throw new Error(`Cannot find value for base variable \"${baseVariable}\"!`);\n }\n }\n const resolvedValue = derive(value, operation, argument, this._isDark);\n return resolvedValue;\n }\n }\n\n private _deriveAlias(variable: string, resolvedVariables: Record): string | undefined {\n const RE_VARIABLE_VALUE = /(.+)--(.+)-(.+)/;\n const matches = variable.match(RE_VARIABLE_VALUE);\n if (matches) {\n const [, baseVariable, operation, argument] = matches;\n const value = resolvedVariables[baseVariable];\n if (!value ) {\n throw new Error(`Cannot find value for alias \"${baseVariable}\" when trying to derive ${variable}!`);\n }\n const resolvedValue = derive(value, operation, argument, this._isDark);\n return resolvedValue;\n }\n }\n}\n\nimport * as pkg from \"off-color\";\n// @ts-ignore \nconst offColor = pkg.offColor ?? pkg.default.offColor;\n\nexport function tests() {\n return {\n \"Simple variable derivation\": assert => {\n const deriver = new DerivedVariables({ \"background-color\": \"#ff00ff\" }, [\"background-color--darker-5\"], false);\n const result = deriver.toVariables();\n const resultColor = offColor(\"#ff00ff\").darken(5/100).hex();\n assert.deepEqual(result, {\"background-color--darker-5\": resultColor});\n },\n\n \"For dark themes, lighten and darken are inverted\": assert => {\n const deriver = new DerivedVariables({ \"background-color\": \"#ff00ff\" }, [\"background-color--darker-5\"], true);\n const result = deriver.toVariables();\n const resultColor = offColor(\"#ff00ff\").lighten(5/100).hex();\n assert.deepEqual(result, {\"background-color--darker-5\": resultColor});\n },\n\n \"Aliases can be derived\": assert => {\n const deriver = new DerivedVariables({ \"background-color\": \"#ff00ff\" }, [\"my-awesome-alias=background-color\",\"my-awesome-alias--darker-5\"], false);\n const result = deriver.toVariables();\n const resultColor = offColor(\"#ff00ff\").darken(5/100).hex();\n assert.deepEqual(result, {\n \"my-awesome-alias\": \"#ff00ff\",\n \"my-awesome-alias--darker-5\": resultColor,\n });\n },\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport type {ThemeInformation} from \"./types\";\nimport type {Platform} from \"../../Platform.js\";\nimport type {ThemeManifest} from \"../../../types/theme\";\nimport {ColorSchemePreference} from \"./types\";\nimport {IconColorizer} from \"../IconColorizer\";\nimport {DerivedVariables} from \"../DerivedVariables\";\nimport {ILogItem} from \"../../../../logging/types\";\n\nexport class RuntimeThemeParser {\n private _themeMapping: Record = {};\n private _preferredColorScheme?: ColorSchemePreference;\n private _platform: Platform;\n\n constructor(platform: Platform, preferredColorScheme?: ColorSchemePreference) {\n this._preferredColorScheme = preferredColorScheme;\n this._platform = platform;\n }\n\n async parse(manifest: ThemeManifest, baseManifest: ThemeManifest, baseManifestLocation: string, log: ILogItem): Promise {\n await log.wrap(\"RuntimeThemeParser.parse\", async () => {\n const {cssLocation, derivedVariables, icons} = this._getSourceData(baseManifest, baseManifestLocation, log);\n const themeName = manifest.name;\n if (!themeName) {\n throw new Error(`Theme name not found in manifest!`);\n }\n let defaultDarkVariant: any = {}, defaultLightVariant: any = {};\n for (const [variant, variantDetails] of Object.entries(manifest.values?.variants!) as [string, any][]) {\n try {\n const themeId = `${manifest.id}-${variant}`;\n const { name: variantName, default: isDefault, dark, variables } = variantDetails;\n const resolvedVariables = new DerivedVariables(variables, derivedVariables, dark).toVariables();\n Object.assign(variables, resolvedVariables);\n const iconVariables = await new IconColorizer(this._platform, icons, variables, baseManifestLocation).toVariables();\n Object.assign(variables, resolvedVariables, iconVariables);\n const themeDisplayName = `${themeName} ${variantName}`;\n if (isDefault) {\n const defaultVariant = dark ? defaultDarkVariant : defaultLightVariant;\n Object.assign(defaultVariant, { variantName, id: themeId, cssLocation, variables });\n continue;\n }\n this._themeMapping[themeDisplayName] = { cssLocation, id: themeId, variables: variables, };\n }\n catch (e) {\n console.error(e);\n continue;\n }\n }\n if (defaultDarkVariant.id && defaultLightVariant.id) {\n const defaultVariant = this._preferredColorScheme === ColorSchemePreference.Dark ? defaultDarkVariant : defaultLightVariant;\n this._themeMapping[themeName] = { dark: defaultDarkVariant, light: defaultLightVariant, default: defaultVariant };\n }\n else {\n const variant = defaultDarkVariant.id ? defaultDarkVariant : defaultLightVariant;\n this._themeMapping[`${themeName} ${variant.variantName}`] = { id: variant.id, cssLocation: variant.cssLocation };\n }\n });\n }\n\n private _getSourceData(manifest: ThemeManifest, location: string, log: ILogItem)\n : { cssLocation: string, derivedVariables: string[], icons: Record} {\n return log.wrap(\"getSourceData\", () => {\n const runtimeCSSLocation = manifest.source?.[\"runtime-asset\"];\n if (!runtimeCSSLocation) {\n throw new Error(`Run-time asset not found in source section for theme at ${location}`);\n }\n const cssLocation = new URL(runtimeCSSLocation, new URL(location, window.location.origin)).href;\n const derivedVariables = manifest.source?.[\"derived-variables\"];\n if (!derivedVariables) {\n throw new Error(`Derived variables not found in source section for theme at ${location}`);\n }\n const icons = manifest.source?.[\"icon\"];\n if (!icons) {\n throw new Error(`Icon mapping not found in source section for theme at ${location}`);\n }\n return { cssLocation, derivedVariables, icons };\n });\n }\n\n get themeMapping(): Record {\n return this._themeMapping;\n }\n\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type {ThemeInformation} from \"./types\";\nimport type {ThemeManifest} from \"../../../types/theme\";\nimport type {ILogItem} from \"../../../../logging/types\";\nimport {ColorSchemePreference} from \"./types\";\n\nexport class BuiltThemeParser {\n private _themeMapping: Record = {};\n private _preferredColorScheme?: ColorSchemePreference;\n\n constructor(preferredColorScheme?: ColorSchemePreference) {\n this._preferredColorScheme = preferredColorScheme;\n }\n\n parse(manifest: ThemeManifest, manifestLocation: string, log: ILogItem) {\n log.wrap(\"BuiltThemeParser.parse\", () => {\n /*\n After build has finished, the source section of each theme manifest\n contains `built-assets` which is a mapping from the theme-id to\n cssLocation of theme\n */\n const builtAssets: Record = manifest.source?.[\"built-assets\"];\n const themeName = manifest.name;\n if (!themeName) {\n throw new Error(`Theme name not found in manifest at ${manifestLocation}`);\n }\n let defaultDarkVariant: any = {}, defaultLightVariant: any = {};\n for (let [themeId, cssLocation] of Object.entries(builtAssets)) {\n try {\n /**\n * This cssLocation is relative to the location of the manifest file.\n * So we first need to resolve it relative to the root of this hydrogen instance.\n */\n cssLocation = new URL(cssLocation, new URL(manifestLocation, window.location.origin)).href;\n }\n catch {\n continue;\n }\n const variant = themeId.match(/.+-(.+)/)?.[1];\n const variantDetails = manifest.values?.variants[variant!];\n if (!variantDetails) {\n throw new Error(`Variant ${variant} is missing in manifest at ${manifestLocation}`);\n }\n const { name: variantName, default: isDefault, dark } = variantDetails;\n const themeDisplayName = `${themeName} ${variantName}`;\n if (isDefault) {\n /**\n * This is a default variant!\n * We'll add these to the themeMapping (separately) keyed with just the\n * theme-name (i.e \"Element\" instead of \"Element Dark\").\n * We need to be able to distinguish them from other variants!\n * \n * This allows us to render radio-buttons with \"dark\" and\n * \"light\" options.\n */\n const defaultVariant = dark ? defaultDarkVariant : defaultLightVariant;\n defaultVariant.variantName = variantName;\n defaultVariant.id = themeId\n defaultVariant.cssLocation = cssLocation;\n continue;\n }\n // Non-default variants are keyed in themeMapping with \"theme_name variant_name\"\n // eg: \"Element Dark\"\n this._themeMapping[themeDisplayName] = {\n cssLocation,\n id: themeId\n };\n }\n if (defaultDarkVariant.id && defaultLightVariant.id) {\n /**\n * As mentioned above, if there's both a default dark and a default light variant,\n * add them to themeMapping separately.\n */\n const defaultVariant = this._preferredColorScheme === ColorSchemePreference.Dark ? defaultDarkVariant : defaultLightVariant;\n this._themeMapping[themeName] = { dark: defaultDarkVariant, light: defaultLightVariant, default: defaultVariant };\n }\n else {\n /**\n * If only one default variant is found (i.e only dark default or light default but not both),\n * treat it like any other variant.\n */\n const variant = defaultDarkVariant.id ? defaultDarkVariant : defaultLightVariant;\n this._themeMapping[`${themeName} ${variant.variantName}`] = { id: variant.id, cssLocation: variant.cssLocation };\n }\n });\n }\n\n get themeMapping(): Record {\n return this._themeMapping;\n }\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {RuntimeThemeParser} from \"./parsers/RuntimeThemeParser\";\nimport {ColorSchemePreference} from \"./parsers/types\";\nimport {BuiltThemeParser} from \"./parsers/BuiltThemeParser\";\nimport type {Variant, ThemeInformation} from \"./parsers/types\";\nimport type {ThemeManifest} from \"../../types/theme\";\nimport type {ILogItem} from \"../../../logging/types\";\nimport type {Platform} from \"../Platform.js\";\nimport {LogLevel} from \"../../../logging/LogFilter\";\n\nexport class ThemeLoader {\n private _platform: Platform;\n private _themeMapping: Record;\n private _injectedVariables?: Record;\n\n constructor(platform: Platform) {\n this._platform = platform;\n }\n\n async init(manifestLocations: string[], log?: ILogItem): Promise {\n await this._platform.logger.wrapOrRun(log, \"ThemeLoader.init\", async (log) => {\n let noManifestsAvailable = true;\n const failedManifestLoads: string[] = [];\n const parseErrors: string[] = [];\n const results = await Promise.all(\n manifestLocations.map(location => this._platform.request(location, { method: \"GET\", format: \"json\", cache: true, }).response())\n );\n const runtimeThemeParser = new RuntimeThemeParser(this._platform, this.preferredColorScheme);\n const builtThemeParser = new BuiltThemeParser(this.preferredColorScheme);\n const runtimeThemePromises: Promise[] = [];\n for (let i = 0; i < results.length; ++i) {\n const result = results[i];\n const { status, body } = result;\n if (!(status >= 200 && status <= 299)) {\n console.error(`Failed to load manifest at ${manifestLocations[i]}, status: ${status}`);\n log.log({ l: \"Manifest fetch failed\", location: manifestLocations[i], status }, LogLevel.Error);\n failedManifestLoads.push(manifestLocations[i])\n continue;\n }\n noManifestsAvailable = false;\n try {\n if (body.extends) {\n const indexOfBaseManifest = results.findIndex(result => \"value\" in result && result.value.body.id === body.extends);\n if (indexOfBaseManifest === -1) {\n throw new Error(`Base manifest for derived theme at ${manifestLocations[i]} not found!`);\n }\n const { body: baseManifest } = (results[indexOfBaseManifest] as PromiseFulfilledResult<{ body: ThemeManifest }>).value;\n const baseManifestLocation = manifestLocations[indexOfBaseManifest];\n const promise = runtimeThemeParser.parse(body, baseManifest, baseManifestLocation, log);\n runtimeThemePromises.push(promise);\n }\n else {\n builtThemeParser.parse(body, manifestLocations[i], log);\n }\n }\n catch(e) {\n console.error(e);\n parseErrors.push(e.message);\n }\n }\n await Promise.all(runtimeThemePromises);\n this._themeMapping = { ...builtThemeParser.themeMapping, ...runtimeThemeParser.themeMapping };\n if (noManifestsAvailable) {\n // We need at least one working theme manifest!\n throw new Error(`All configured theme manifests failed to load, the following were tried: ${failedManifestLoads.join(\", \")}`);\n }\n else if (Object.keys(this._themeMapping).length === 0 && parseErrors.length) {\n // Something is wrong..., themeMapping is empty!\n throw new Error(`Failed to parse theme manifests, the following errors were encountered: ${parseErrors.join(\", \")}`);\n }\n this._addDefaultThemeToMapping(log);\n log.log({ l: \"Preferred colorscheme\", scheme: this.preferredColorScheme === ColorSchemePreference.Dark ? \"dark\" : \"light\" });\n log.log({ l: \"Result\", themeMapping: this._themeMapping });\n });\n }\n\n async setTheme(themeName: string, themeVariant?: \"light\" | \"dark\" | \"default\", log?: ILogItem) {\n await this._platform.logger.wrapOrRun(log, { l: \"change theme\", name: themeName, variant: themeVariant }, async (l) => {\n let cssLocation: string, variables: Record;\n let themeDetails = this._themeMapping[themeName];\n if (\"id\" in themeDetails) {\n cssLocation = themeDetails.cssLocation;\n variables = themeDetails.variables;\n }\n else {\n if (!themeVariant) {\n throw new Error(\"themeVariant is undefined!\");\n }\n cssLocation = themeDetails[themeVariant].cssLocation;\n variables = themeDetails[themeVariant].variables;\n }\n await this._platform.replaceStylesheet(cssLocation, l);\n if (variables) {\n log?.log({l: \"Derived Theme\", variables});\n this._injectCSSVariables(variables);\n }\n else {\n this._removePreviousCSSVariables();\n }\n this._platform.settingsStorage.setString(\"theme-name\", themeName);\n if (themeVariant) {\n this._platform.settingsStorage.setString(\"theme-variant\", themeVariant);\n }\n else {\n this._platform.settingsStorage.remove(\"theme-variant\");\n }\n });\n }\n\n private _injectCSSVariables(variables: Record): void {\n const root = document.documentElement;\n for (const [variable, value] of Object.entries(variables)) {\n root.style.setProperty(`--${variable}`, value);\n }\n this._injectedVariables = variables;\n }\n\n private _removePreviousCSSVariables(): void {\n if (!this._injectedVariables) {\n return;\n }\n const root = document.documentElement;\n for (const variable of Object.keys(this._injectedVariables)) {\n root.style.removeProperty(`--${variable}`);\n }\n this._injectedVariables = undefined;\n }\n\n /** Maps theme display name to theme information */\n get themeMapping(): Record {\n return this._themeMapping;\n }\n\n async getActiveTheme(): Promise<{themeName: string, themeVariant?: string}> {\n let themeName = await this._platform.settingsStorage.getString(\"theme-name\");\n let themeVariant = await this._platform.settingsStorage.getString(\"theme-variant\");\n if (!themeName || !this._themeMapping[themeName]) {\n themeName = \"Default\" in this._themeMapping ? \"Default\" : Object.keys(this._themeMapping)[0];\n if (!this._themeMapping[themeName][themeVariant]) {\n themeVariant = \"default\" in this._themeMapping[themeName] ? \"default\" : undefined;\n }\n }\n return { themeName, themeVariant };\n }\n\n getDefaultTheme(): string | undefined {\n switch (this.preferredColorScheme) {\n case ColorSchemePreference.Dark:\n return this._platform.config[\"defaultTheme\"]?.dark;\n case ColorSchemePreference.Light:\n return this._platform.config[\"defaultTheme\"]?.light;\n }\n }\n\n private _findThemeDetailsFromId(themeId: string): {themeName: string, themeData: Partial} | undefined {\n for (const [themeName, themeData] of Object.entries(this._themeMapping)) {\n if (\"id\" in themeData && themeData.id === themeId) {\n return { themeName, themeData };\n }\n else if (\"light\" in themeData && themeData.light?.id === themeId) {\n return { themeName, themeData: themeData.light };\n }\n else if (\"dark\" in themeData && themeData.dark?.id === themeId) {\n return { themeName, themeData: themeData.dark };\n }\n }\n }\n\n private _addDefaultThemeToMapping(log: ILogItem) {\n log.wrap(\"addDefaultThemeToMapping\", l => { \n const defaultThemeId = this.getDefaultTheme();\n if (defaultThemeId) {\n const themeDetails = this._findThemeDetailsFromId(defaultThemeId);\n if (themeDetails) {\n this._themeMapping[\"Default\"] = { id: \"default\", cssLocation: themeDetails.themeData.cssLocation! };\n const variables = themeDetails.themeData.variables;\n if (variables) {\n this._themeMapping[\"Default\"].variables = variables;\n }\n }\n }\n l.log({ l: \"Default Theme\", theme: defaultThemeId});\n });\n }\n\n get preferredColorScheme(): ColorSchemePreference | undefined {\n if (window.matchMedia(\"(prefers-color-scheme: dark)\").matches) {\n return ColorSchemePreference.Dark;\n }\n else if (window.matchMedia(\"(prefers-color-scheme: light)\").matches) {\n return ColorSchemePreference.Light;\n }\n }\n}\n","/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport enum TimeScope {\n Minute = 60 * 1000,\n Hours = 60 * TimeScope.Minute,\n Day = 24 * TimeScope.Hours,\n}\n\nexport function formatDuration(milliseconds: number): string {\n let days = 0;\n let hours = 0;\n let minutes = 0;\n if (milliseconds >= TimeScope.Day) {\n days = Math.floor(milliseconds / TimeScope.Day);\n milliseconds -= days * TimeScope.Day;\n }\n if (milliseconds >= TimeScope.Hours) {\n hours = Math.floor(milliseconds / TimeScope.Hours);\n milliseconds -= hours * TimeScope.Hours;\n }\n if (milliseconds >= TimeScope.Minute) {\n minutes = Math.floor(milliseconds / TimeScope.Minute);\n milliseconds -= minutes * TimeScope.Minute;\n }\n const seconds = Math.floor(milliseconds / 1000);\n let result = \"\";\n if (days) {\n result = `${days}d `;\n }\n if (hours || days) {\n result += `${hours}h `;\n }\n if (minutes || hours || days) {\n result += `${minutes}m `;\n }\n result += `${seconds}s`;\n return result;\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport type { ITimeFormatter } from \"../../types/types\";\nimport {Clock} from \"./Clock\";\nimport {formatDuration, TimeScope} from \"../../../utils/timeFormatting\";\n\nexport class TimeFormatter implements ITimeFormatter {\n\n private todayMidnight: Date;\n private relativeDayFormatter: Intl.RelativeTimeFormat;\n private weekdayFormatter: Intl.DateTimeFormat;\n private currentYearFormatter: Intl.DateTimeFormat;\n private otherYearFormatter: Intl.DateTimeFormat;\n private timeFormatter: Intl.DateTimeFormat;\n\n constructor(private clock: Clock) {\n // don't use the clock time here as the DOM relative formatters don't support setting the reference date anyway\n this.todayMidnight = new Date();\n this.todayMidnight.setHours(0, 0, 0, 0);\n this.relativeDayFormatter = new Intl.RelativeTimeFormat(undefined, {numeric: \"auto\"});\n this.weekdayFormatter = new Intl.DateTimeFormat(undefined, {weekday: 'long'});\n this.currentYearFormatter = new Intl.DateTimeFormat(undefined, {\n weekday: 'long',\n month: 'long',\n day: 'numeric'\n });\n this.otherYearFormatter = new Intl.DateTimeFormat(undefined, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n this.timeFormatter = new Intl.DateTimeFormat(undefined, {hour: \"numeric\", minute: \"2-digit\"});\n }\n \n formatTime(date: Date): string {\n return this.timeFormatter.format(date);\n }\n\n formatMachineReadableDate(date: Date): string {\n return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; \n }\n\n formatRelativeDate(date: Date): string {\n let daysDiff = Math.floor((date.getTime() - this.todayMidnight.getTime()) / TimeScope.Day);\n if (daysDiff >= -1 && daysDiff <= 1) {\n // Tomorrow, Today, Yesterday\n return capitalizeFirstLetter(this.relativeDayFormatter.format(daysDiff, \"day\"));\n } else if (daysDiff > -7 && daysDiff < 0) {\n // Wednesday\n return this.weekdayFormatter.format(date);\n } else if (this.todayMidnight.getFullYear() === date.getFullYear()) {\n // Friday, November 6\n return this.currentYearFormatter.format(date);\n } else {\n // Friday, November 5, 2021\n return this.otherYearFormatter.format(date);\n }\n }\n\n formatDuration(milliseconds: number): string {\n return formatDuration(milliseconds);\n }\n}\n\nfunction capitalizeFirstLetter(str: string) {\n return str.slice(0, 1).toLocaleUpperCase() + str.slice(1);\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {createFetchRequest} from \"./dom/request/fetch.js\";\nimport {xhrRequest} from \"./dom/request/xhr.js\";\nimport {StorageFactory} from \"../../matrix/storage/idb/StorageFactory\";\nimport {SessionInfoStorage} from \"../../matrix/sessioninfo/localstorage/SessionInfoStorage\";\nimport {SettingsStorage} from \"./dom/SettingsStorage.js\";\nimport {Encoding} from \"./utils/Encoding.js\";\nimport {OlmWorker} from \"../../matrix/e2ee/OlmWorker.js\";\nimport {IDBLogPersister} from \"../../logging/IDBLogPersister\";\nimport {ConsoleReporter} from \"../../logging/ConsoleReporter\";\nimport {Logger} from \"../../logging/Logger\";\nimport {RootView} from \"./ui/RootView.js\";\nimport {Clock} from \"./dom/Clock.js\";\nimport {ServiceWorkerHandler} from \"./dom/ServiceWorkerHandler.js\";\nimport {NotificationService} from \"./dom/NotificationService.js\";\nimport {History} from \"./dom/History.js\";\nimport {OnlineStatus} from \"./dom/OnlineStatus.js\";\nimport {Crypto} from \"./dom/Crypto.js\";\nimport {estimateStorageUsage} from \"./dom/StorageEstimate.js\";\nimport {WorkerPool} from \"./dom/WorkerPool.js\";\nimport {BlobHandle} from \"./dom/BlobHandle.js\";\nimport {hasReadPixelPermission, ImageHandle, VideoHandle} from \"./dom/ImageHandle.js\";\nimport {downloadInIframe} from \"./dom/download.js\";\nimport {Disposables} from \"../../utils/Disposables\";\nimport {parseHTML} from \"./parsehtml.js\";\nimport {handleAvatarError} from \"./ui/avatar\";\nimport {MediaDevicesWrapper} from \"./dom/MediaDevices\";\nimport {DOMWebRTC} from \"./dom/WebRTC\";\nimport {ThemeLoader} from \"./theming/ThemeLoader\";\nimport {TimeFormatter} from \"./dom/TimeFormatter\";\nimport {copyPlaintext} from \"./dom/utils\";\n\nfunction addScript(src) {\n return new Promise(function (resolve, reject) {\n var s = document.createElement(\"script\");\n s.setAttribute(\"src\", src );\n s.onload=resolve;\n s.onerror=reject;\n document.body.appendChild(s);\n });\n}\n\nasync function loadOlm(olmPaths) {\n // make crypto.getRandomValues available without\n // a prefix on IE11, needed by olm to work\n if (window.msCrypto && !window.crypto) {\n window.crypto = window.msCrypto;\n }\n if (olmPaths) {\n if (window.WebAssembly) {\n await addScript(olmPaths.wasmBundle);\n await window.Olm.init({locateFile: () => olmPaths.wasm});\n } else {\n await addScript(olmPaths.legacyBundle);\n await window.Olm.init();\n }\n return window.Olm;\n }\n return null;\n}\n// turn asset path to absolute path if it isn't already\n// so it can be loaded independent of base\nfunction assetAbsPath(assetPath) {\n if (!assetPath.startsWith(\"/\")) {\n return new URL(assetPath, document.location.href).pathname;\n }\n return assetPath;\n}\n\nasync function loadOlmWorker(assetPaths) {\n const workerPool = new WorkerPool(assetPaths.worker, 4);\n await workerPool.init();\n await workerPool.sendAll({\n type: \"load_olm\",\n path: assetAbsPath(assetPaths.olm.legacyBundle)\n });\n const olmWorker = new OlmWorker(workerPool);\n return olmWorker;\n}\n\n// needed for mobile Safari which shifts the layout viewport up without resizing it\n// when the keyboard shows (see https://bugs.webkit.org/show_bug.cgi?id=141832)\nfunction adaptUIOnVisualViewportResize(container) {\n if (!window.visualViewport) {\n return;\n }\n const handler = () => {\n const sessionView = container.querySelector('.SessionView');\n if (!sessionView) {\n return;\n }\n\n const scrollable = container.querySelector('.bottom-aligned-scroll');\n let scrollTopBefore, heightBefore, heightAfter;\n\n if (scrollable) {\n scrollTopBefore = scrollable.scrollTop;\n heightBefore = scrollable.offsetHeight;\n }\n\n // Ideally we'd use window.visualViewport.offsetTop but that seems to occasionally lag\n // behind (last tested on iOS 14.4 simulator) so we have to compute the offset manually\n const offsetTop = sessionView.offsetTop + sessionView.offsetHeight - window.visualViewport.height;\n\n container.style.setProperty('--ios-viewport-height', window.visualViewport.height.toString() + 'px');\n container.style.setProperty('--ios-viewport-top', offsetTop.toString() + 'px');\n\n if (scrollable) {\n heightAfter = scrollable.offsetHeight;\n scrollable.scrollTop = scrollTopBefore + heightBefore - heightAfter;\n }\n };\n window.visualViewport.addEventListener('resize', handler);\n return () => {\n window.visualViewport.removeEventListener('resize', handler);\n };\n}\n\nexport class Platform {\n constructor({ container, assetPaths, config, configURL, logger, options = null, cryptoExtras = null }) {\n this._container = container;\n this._assetPaths = assetPaths;\n this._config = config;\n this._configURL = configURL;\n this.settingsStorage = new SettingsStorage(\"hydrogen_setting_v1_\");\n this.clock = new Clock();\n this.encoding = new Encoding();\n this.random = Math.random;\n this.logger = logger ?? this._createLogger(options?.development);\n this.history = new History();\n this.onlineStatus = new OnlineStatus();\n this.timeFormatter = new TimeFormatter();\n this._serviceWorkerHandler = null;\n this.sessionInfoStorage = new SessionInfoStorage(\n \"hydrogen_sessions_v1\"\n );\n if (assetPaths.serviceWorker && \"serviceWorker\" in navigator) {\n this._serviceWorkerHandler = new ServiceWorkerHandler(\n this.sessionInfoStorage\n );\n this._serviceWorkerHandler.registerAndStart(assetPaths.serviceWorker);\n }\n this.notificationService = undefined;\n // Only try to use crypto when olm is provided\n if(this._assetPaths.olm) {\n this.crypto = new Crypto(cryptoExtras);\n }\n this.storageFactory = new StorageFactory(this._serviceWorkerHandler);\n this.estimateStorageUsage = estimateStorageUsage;\n if (typeof fetch === \"function\") {\n this.request = createFetchRequest(this.clock.createTimeout, this._serviceWorkerHandler);\n } else {\n this.request = xhrRequest;\n }\n const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;\n this.isIE11 = isIE11;\n // From https://stackoverflow.com/questions/9038625/detect-if-device-is-ios/9039885\n const isIOS = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) && !window.MSStream;\n this.isIOS = isIOS;\n this._disposables = new Disposables();\n this._olmPromise = undefined;\n this._workerPromise = undefined;\n this.mediaDevices = new MediaDevicesWrapper(navigator.mediaDevices);\n this.webRTC = new DOMWebRTC();\n this._themeLoader = import.meta.env.DEV? null: new ThemeLoader(this);\n }\n\n async init() {\n try {\n await this.logger.run(\"Platform init\", async (log) => {\n if (!this._config) {\n if (!this._configURL) {\n throw new Error(\"Neither config nor configURL was provided!\");\n }\n const {status, body}= await this.request(this._configURL, {method: \"GET\", format: \"json\", cache: true}).response();\n if (status === 404) {\n throw new Error(`Could not find ${this._configURL}. Did you copy over config.sample.json?`);\n } else if (status >= 400) {\n throw new Error(`Got status ${status} while trying to fetch ${this._configURL}`);\n }\n this._config = body;\n }\n this.notificationService = new NotificationService(\n this._serviceWorkerHandler,\n this._config.push\n );\n if (this._themeLoader) {\n const manifests = this.config[\"themeManifests\"];\n await this._themeLoader?.init(manifests, log);\n const { themeName, themeVariant } = await this._themeLoader.getActiveTheme();\n log.log({ l: \"Active theme\", name: themeName, variant: themeVariant });\n await this._themeLoader.setTheme(themeName, themeVariant, log);\n }\n });\n } catch (err) {\n this._container.innerText = err.message;\n throw err;\n }\n }\n\n _createLogger(isDevelopment) {\n const logger = new Logger({platform: this});\n // Make sure that loginToken does not end up in the logs\n const transformer = (item) => {\n if (item.e?.stack) {\n item.e.stack = item.e.stack.replace(/\\/\\?loginToken=(.+)/, \"?loginToken=\");\n }\n return item;\n };\n const logPersister = new IDBLogPersister({name: \"hydrogen_logs\", platform: this, serializedTransformer: transformer});\n logger.addReporter(logPersister);\n if (isDevelopment) {\n logger.addReporter(new ConsoleReporter());\n }\n return logger;\n }\n\n get updateService() {\n return this._serviceWorkerHandler;\n }\n\n loadOlm() {\n if (!this._olmPromise) {\n this._olmPromise = loadOlm(this._assetPaths.olm);\n }\n return this._olmPromise;\n }\n\n get config() {\n return this._config;\n }\n\n async loadOlmWorker() {\n if (!window.WebAssembly) {\n if (!this._workerPromise) {\n this._workerPromise = loadOlmWorker(this._assetPaths);\n }\n return this._workerPromise;\n }\n }\n\n createAndMountRootView(vm) {\n if (this.isIE11) {\n this._container.className += \" legacy\";\n }\n if (this.isIOS) {\n this._container.className += \" ios\";\n const disposable = adaptUIOnVisualViewportResize(this._container);\n if (disposable) {\n this._disposables.track(disposable);\n }\n }\n this._container.addEventListener(\"error\", handleAvatarError, true);\n this._disposables.track(() => this._container.removeEventListener(\"error\", handleAvatarError, true));\n window.__hydrogenViewModel = vm;\n const view = new RootView(vm);\n this._container.appendChild(view.mount());\n }\n\n setNavigation(navigation) {\n this._serviceWorkerHandler?.setNavigation(navigation);\n }\n\n createBlob(buffer, mimetype) {\n return BlobHandle.fromBuffer(buffer, mimetype);\n }\n\n saveFileAs(blobHandle, filename) {\n if (navigator.msSaveBlob) {\n navigator.msSaveBlob(blobHandle.nativeBlob, filename);\n } else {\n downloadInIframe(this._container, this._assetPaths.downloadSandbox, blobHandle, filename, this.isIOS);\n }\n }\n\n async copyPlaintext(text) {\n return await copyPlaintext(text);\n }\n\n restart() {\n document.location.reload();\n }\n\n openFile(mimeType = null) {\n const input = document.createElement(\"input\");\n input.setAttribute(\"type\", \"file\");\n input.className = \"hidden\";\n if (mimeType) {\n input.setAttribute(\"accept\", mimeType);\n }\n const promise = new Promise(resolve => {\n const checkFile = () => {\n input.removeEventListener(\"change\", checkFile, true);\n const file = input.files[0];\n this._container.removeChild(input);\n if (file) {\n // ok to not filter mimetypes as these are local files\n resolve({name: file.name, blob: BlobHandle.fromBlobUnsafe(file)});\n } else {\n resolve();\n }\n }\n input.addEventListener(\"change\", checkFile, true);\n });\n // IE11 needs the input to be attached to the document\n this._container.appendChild(input);\n input.click();\n return promise;\n }\n\n openUrl(url) {\n location.href = url;\n }\n\n parseHTML(html) {\n return parseHTML(html);\n }\n\n async loadImage(blob) {\n return ImageHandle.fromBlob(blob);\n }\n\n async loadVideo(blob) {\n return VideoHandle.fromBlob(blob);\n }\n\n hasReadPixelPermission() {\n return hasReadPixelPermission();\n }\n\n get devicePixelRatio() {\n return window.devicePixelRatio || 1;\n }\n\n get version() {\n return DEFINE_VERSION;\n }\n\n get themeLoader() {\n return this._themeLoader;\n }\n\n async replaceStylesheet(newPath, log) {\n const error = await this.logger.wrapOrRun(log, { l: \"replaceStylesheet\", location: newPath, }, async (l) => {\n let error;\n const head = document.querySelector(\"head\");\n // remove default theme \n document.querySelectorAll(\".theme\").forEach(e => e.remove());\n // add new theme\n const styleTag = document.createElement(\"link\");\n styleTag.href = newPath;\n styleTag.rel = \"stylesheet\";\n styleTag.type = \"text/css\";\n styleTag.className = \"theme\";\n const promise = new Promise(resolve => {\n styleTag.onerror = () => {\n error = new Error(`Failed to load stylesheet from ${newPath}`);\n l.catch(error);\n resolve();\n };\n styleTag.onload = () => {\n resolve();\n };\n });\n head.appendChild(styleTag);\n await promise;\n return error;\n });\n if (error) {\n throw error;\n }\n }\n\n get description() {\n return \"web-\" + (navigator.userAgent ?? \"\");\n }\n\n dispose() {\n this._disposables.dispose();\n }\n}\n\nimport {LogItem} from \"../../logging/LogItem\";\nexport function tests() {\n return {\n \"loginToken should not be in logs\": (assert) => {\n const logPersister = Object.create(IDBLogPersister.prototype);\n logPersister._queuedItems = [];\n logPersister.options = {\n serializedTransformer: (item) => {\n if (item.e?.stack) {\n item.e.stack = item.e.stack.replace(/(?<=\\/\\?loginToken=).+/, \"\");\n }\n return item;\n }\n };\n const logger = { _now() {return 5;} };\n const logItem = new LogItem(\"test\", 1, logger);\n logItem.error = new Error();\n logItem.error.stack = \"main http://localhost:3000/src/main.js:55\\n http://localhost:3000/?loginToken=secret:26\"\n logPersister.reportItem(logItem, null, false);\n const item = logPersister._queuedItems.pop();\n assert.strictEqual(item.json.search(\"secret\"), -1);\n }\n };\n}\n","export default \"__VITE_ASSET__e1b1bc02__\"","export default \"__VITE_ASSET__48a866e9__\"","export default \"__VITE_ASSET__bdb9a925__\"","export default \"__VITE_ASSET__3fc8dbfe__\"","export default \"__VITE_ASSET__cf9a793b__\"","export default \"__VITE_ASSET__bc22f405__\"","// @ts-ignore\nimport _downloadSandboxPath from \"../../assets/download-sandbox.html?url\";\n// @ts-ignore\nimport _workerPath from \"../../worker/main.js?url\";\n// @ts-ignore\nimport olmWasmPath from \"@matrix-org/olm/olm.wasm?url\";\n// @ts-ignore\nimport olmJsPath from \"@matrix-org/olm/olm.js?url\";\n// @ts-ignore\nimport olmLegacyJsPath from \"@matrix-org/olm/olm_legacy.js?url\";\n\nexport default {\n downloadSandbox: _downloadSandboxPath,\n worker: _workerPath,\n olm: {\n wasm: olmWasmPath,\n legacyBundle: olmLegacyJsPath,\n wasmBundle: olmJsPath,\n }\n};\n","\n import {main} from \"./main\";\n import {Platform} from \"./Platform\";\n import configURL from \"./assets/config.json?url\";\n import assetPaths from \"./sdk/paths/vite\";\n assetPaths.serviceWorker = \"sw.js\";\n const platform = new Platform({\n container: document.body,\n assetPaths,\n configURL, \n options: {development: import.meta.env.DEV}\n });\n main(platform);\n "],"names":["Request","stringify","DecryptionError","anotherjson","EVENT_TYPE","Range","encodeKey","decodeKey","require$$0","require$$2","MEMBER_EVENT_TYPE","NullLoggerInstance","EVENT_ENCRYPTED_TYPE","POWERLEVELS_EVENT_TYPE","Session","Decryption","DecryptionChanges","Encryption","DecryptionPreparation","Curve25519.Algorithm","Curve25519.BackupEncryption","OlmDecryption","OlmEncryption","MegOlmKeyLoader","MegOlmEncryption","MegOlmDecryption","ssssKeyFromCredential","ssssWriteKey","ssssRemoveKey","E2EEAccount","ssssReadKey","createSSSSKeyFromDehydratedDeviceKey","Status","tileClassForEntry","defaultTileClassForEntry","RequestResult","base64","text","ErrorView","disableTargetCallback","DOMPurify","offColorModule","pkg.offColor","pkg.default"],"mappings":"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"} \ No newline at end of file diff --git a/hydrogen/assets/main.bdb9a925.js b/hydrogen/assets/main.bdb9a925.js new file mode 100644 index 0000000..9b5560c --- /dev/null +++ b/hydrogen/assets/main.bdb9a925.js @@ -0,0 +1,177 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function asErrorMessage(err) { + return { + type: "error", + message: err.message, + stack: err.stack + }; +} + +function asSuccessMessage(payload) { + return { + type: "success", + payload + }; +} + +class MessageHandler { + constructor() { + this._olm = null; + this._randomValues = self.crypto ? null : []; + } + + _feedRandomValues(randomValues) { + if (this._randomValues) { + this._randomValues.push(...randomValues); + } + } + + _checkRandomValuesUsed() { + if (this._randomValues && this._randomValues.length !== 0) { + throw new Error(`${this._randomValues.length} random values left`); + } + } + + _getRandomValues(typedArray) { + if (!(typedArray instanceof Uint8Array)) { + throw new Error("only Uint8Array is supported: " + JSON.stringify({ + Int8Array: typedArray instanceof Int8Array, + Uint8Array: typedArray instanceof Uint8Array, + Int16Array: typedArray instanceof Int16Array, + Uint16Array: typedArray instanceof Uint16Array, + Int32Array: typedArray instanceof Int32Array, + Uint32Array: typedArray instanceof Uint32Array, + })); + } + if (this._randomValues.length === 0) { + throw new Error("no more random values, needed one of length " + typedArray.length); + } + const precalculated = this._randomValues.shift(); + if (precalculated.length !== typedArray.length) { + throw new Error(`typedArray length (${typedArray.length}) does not match precalculated length (${precalculated.length})`); + } + // copy values + for (let i = 0; i < typedArray.length; ++i) { + typedArray[i] = precalculated[i]; + } + return typedArray; + } + + handleEvent(e) { + if (e.type === "message") { + this._handleMessage(e.data); + } + } + + _sendReply(refMessage, reply) { + reply.replyToId = refMessage.id; + self.postMessage(reply); + } + + _toMessage(fn) { + try { + const payload = fn(); + if (payload instanceof Promise) { + return payload.then( + payload => asSuccessMessage(payload), + err => asErrorMessage(err) + ); + } else { + return asSuccessMessage(payload); + } + } catch (err) { + return asErrorMessage(err); + } + } + + _loadOlm(path) { + return this._toMessage(async () => { + if (!self.crypto) { + self.crypto = {getRandomValues: this._getRandomValues.bind(this)}; + } + // mangle the globals enough to make olm believe it is running in a browser + self.window = self; + self.document = {}; + self.importScripts(path); + const olm = self.Olm; + await olm.init(); + this._olm = olm; + }); + } + + _megolmDecrypt(sessionKey, ciphertext) { + return this._toMessage(() => { + const session = new this._olm.InboundGroupSession(); + try { + session.import_session(sessionKey); + // returns object with plaintext and message_index + return session.decrypt(ciphertext); + } finally { + session.free(); + } + }); + } + + _olmCreateAccountAndOTKs(randomValues, otkAmount) { + return this._toMessage(() => { + this._feedRandomValues(randomValues); + const account = new this._olm.Account(); + try { + account.create(); + account.generate_one_time_keys(otkAmount); + this._checkRandomValuesUsed(); + return account.pickle(""); + } finally { + account.free(); + } + }); + } + + _olmCreateOutbound(randomValues, accountPickle, theirIdentityKey, theirOneTimeKey) { + return this._toMessage(() => { + this._feedRandomValues(randomValues); + const account = new this._olm.Account(); + const newSession = new this._olm.Session(); + try { + account.unpickle("", accountPickle); + newSession.create_outbound(account, theirIdentityKey, theirOneTimeKey); + return newSession.pickle(""); + } finally { + account.free(); + newSession.free(); + } + }); + } + + async _handleMessage(message) { + const {type} = message; + if (type === "ping") { + this._sendReply(message, {type: "success"}); + } else if (type === "load_olm") { + this._sendReply(message, await this._loadOlm(message.path)); + } else if (type === "megolm_decrypt") { + this._sendReply(message, this._megolmDecrypt(message.sessionKey, message.ciphertext)); + } else if (type === "olm_create_account_otks") { + this._sendReply(message, this._olmCreateAccountAndOTKs(message.randomValues, message.otkAmount)); + } else if (type === "olm_create_outbound") { + this._sendReply(message, this._olmCreateOutbound(message.randomValues, message.accountPickle, message.theirIdentityKey, message.theirOneTimeKey)); + } + } +} + +self.addEventListener("message", new MessageHandler()); diff --git a/hydrogen/assets/manifest.1f23c85b.json b/hydrogen/assets/manifest.1f23c85b.json new file mode 100644 index 0000000..9c0665c --- /dev/null +++ b/hydrogen/assets/manifest.1f23c85b.json @@ -0,0 +1 @@ +{"name":"Hydrogen","short_name":"Hydrogen","display":"standalone","description":"Lightweight matrix client with legacy and mobile browser support","start_url":"../index.html","icons":[{"src":"icon.8024c299.png","sizes":"384x384","type":"image/png"},{"src":"icon-maskable.965d12c4.png","sizes":"384x384","type":"image/png","purpose":"maskable"}],"theme_color":"#0DBD8B"} \ No newline at end of file diff --git a/hydrogen/assets/mic-muted-2617055184.e8d1962f.svg b/hydrogen/assets/mic-muted-2617055184.e8d1962f.svg new file mode 100644 index 0000000..fc97b49 --- /dev/null +++ b/hydrogen/assets/mic-muted-2617055184.e8d1962f.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/hydrogen/assets/mic-muted-2638557456.4d8c99b4.svg b/hydrogen/assets/mic-muted-2638557456.4d8c99b4.svg new file mode 100644 index 0000000..54c528e --- /dev/null +++ b/hydrogen/assets/mic-muted-2638557456.4d8c99b4.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/hydrogen/assets/mic-muted-3642419863.228ee86f.svg b/hydrogen/assets/mic-muted-3642419863.228ee86f.svg new file mode 100644 index 0000000..df6f739 --- /dev/null +++ b/hydrogen/assets/mic-muted-3642419863.228ee86f.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/hydrogen/assets/mic-muted-4213153786.513608a5.svg b/hydrogen/assets/mic-muted-4213153786.513608a5.svg new file mode 100644 index 0000000..e3f96aa --- /dev/null +++ b/hydrogen/assets/mic-muted-4213153786.513608a5.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/hydrogen/assets/mic-muted.56aa03b9.svg b/hydrogen/assets/mic-muted.56aa03b9.svg new file mode 100644 index 0000000..3dc5929 --- /dev/null +++ b/hydrogen/assets/mic-muted.56aa03b9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/mic-unmuted-211198830.1fde69c5.svg b/hydrogen/assets/mic-unmuted-211198830.1fde69c5.svg new file mode 100644 index 0000000..ed148ff --- /dev/null +++ b/hydrogen/assets/mic-unmuted-211198830.1fde69c5.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/hydrogen/assets/mic-unmuted-3178778883.b8f57412.svg b/hydrogen/assets/mic-unmuted-3178778883.b8f57412.svg new file mode 100644 index 0000000..145810c --- /dev/null +++ b/hydrogen/assets/mic-unmuted-3178778883.b8f57412.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/hydrogen/assets/mic-unmuted.c180f63a.svg b/hydrogen/assets/mic-unmuted.c180f63a.svg new file mode 100644 index 0000000..ca00f25 --- /dev/null +++ b/hydrogen/assets/mic-unmuted.c180f63a.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/olm.3fc8dbfe.wasm b/hydrogen/assets/olm.3fc8dbfe.wasm new file mode 100644 index 0000000..971fe9a Binary files /dev/null and b/hydrogen/assets/olm.3fc8dbfe.wasm differ diff --git a/hydrogen/assets/olm.cf9a793b.js b/hydrogen/assets/olm.cf9a793b.js new file mode 100644 index 0000000..f84c1b4 --- /dev/null +++ b/hydrogen/assets/olm.cf9a793b.js @@ -0,0 +1,162 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt Apache-2.0 +// @source: https://gitlab.matrix.org/matrix-org/olm/-/tree/3.2.15 + +var Olm = (function() { +var olm_exports = {}; +var onInitSuccess; +var onInitFail; + +var Module = (() => { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(Module) { + Module = Module || {}; + + +var a;a||(a=typeof Module !== 'undefined' ? Module : {});var aa,ca;a.ready=new Promise(function(b,c){aa=b;ca=c});var g;if("undefined"!==typeof window)g=function(b){window.crypto.getRandomValues(b)};else if(module.exports){var da=require("crypto");g=function(b){var c=da.randomBytes(b.length);b.set(c)}}else throw Error("Cannot find global to attach library to");if("undefined"!==typeof OLM_OPTIONS)for(var ea in OLM_OPTIONS)OLM_OPTIONS.hasOwnProperty(ea)&&(a[ea]=OLM_OPTIONS[ea]); +a.onRuntimeInitialized=function(){h=a._olm_error();olm_exports.PRIVATE_KEY_LENGTH=a._olm_pk_private_key_length();onInitSuccess&&onInitSuccess()};a.onAbort=function(b){onInitFail&&onInitFail(b)};var fa=Object.assign({},a),ha="object"==typeof window,l="function"==typeof importScripts,ia="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,m="",ja,ka,la,fs,ma,na; +if(ia)m=l?require("path").dirname(m)+"/":__dirname+"/",na=()=>{ma||(fs=require("fs"),ma=require("path"))},ja=function(b,c){na();b=ma.normalize(b);return fs.readFileSync(b,c?void 0:"utf8")},la=b=>{b=ja(b,!0);b.buffer||(b=new Uint8Array(b));return b},ka=(b,c,d)=>{na();b=ma.normalize(b);fs.readFile(b,function(e,f){e?d(e):c(f.buffer)})},1{var c=new XMLHttpRequest;c.open("GET",b,!1);c.send(null);return c.responseText},l&&(la=b=>{var c=new XMLHttpRequest;c.open("GET",b,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)}), +ka=(b,c,d)=>{var e=new XMLHttpRequest;e.open("GET",b,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?c(e.response):d()};e.onerror=d;e.send(null)};a.print||console.log.bind(console);var n=a.printErr||console.warn.bind(console);Object.assign(a,fa);fa=null;var q;a.wasmBinary&&(q=a.wasmBinary);var noExitRuntime=a.noExitRuntime||!0;"object"!=typeof WebAssembly&&r("no native wasm support detected"); +var oa,pa=!1,qa="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0; +function t(b,c){if(b){var d=u,e=b+c;for(c=b;d[c]&&!(c>=e);)++c;if(16f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}b=e}}else b="";return b} +function ra(b,c,d,e){if(!(0=p){var w=b.charCodeAt(++k);p=65536+((p&1023)<<10)|w&1023}if(127>=p){if(d>=e)break;c[d++]=p}else{if(2047>=p){if(d+1>=e)break;c[d++]=192|p>>6}else{if(65535>=p){if(d+2>=e)break;c[d++]=224|p>>12}else{if(d+3>=e)break;c[d++]=240|p>>18;c[d++]=128|p>>12&63}c[d++]=128|p>>6&63}c[d++]=128|p&63}}c[d]=0;return d-f}function v(b,c,d){return ra(b,u,c,d)} +function x(b){for(var c=0,d=0;d=e?c++:2047>=e?c+=2:55296<=e&&57343>=e?(c+=4,++d):c+=3}return c}var sa,y,u,ta,z,ua,va,wa;function xa(){var b=oa.buffer;sa=b;a.HEAP8=y=new Int8Array(b);a.HEAP16=ta=new Int16Array(b);a.HEAP32=z=new Int32Array(b);a.HEAPU8=u=new Uint8Array(b);a.HEAPU16=new Uint16Array(b);a.HEAPU32=ua=new Uint32Array(b);a.HEAPF32=va=new Float32Array(b);a.HEAPF64=wa=new Float64Array(b)}var za=[],Aa=[],Ba=[]; +function Ca(){var b=a.preRun.shift();za.unshift(b)}var A=0,Da=null,B=null;function r(b){if(a.onAbort)a.onAbort(b);b="Aborted("+b+")";n(b);pa=!0;b=new WebAssembly.RuntimeError(b+". Build with -sASSERTIONS for more info.");ca(b);throw b;}function Ea(){return C.startsWith("data:application/octet-stream;base64,")}var C;C="olm.wasm";if(!Ea()){var Fa=C;C=a.locateFile?a.locateFile(Fa,m):m+Fa} +function Ga(){var b=C;try{if(b==C&&q)return new Uint8Array(q);if(la)return la(b);throw"both async and sync fetching of the wasm failed";}catch(c){r(c)}} +function Ha(){if(!q&&(ha||l)){if("function"==typeof fetch&&!C.startsWith("file://"))return fetch(C,{credentials:"same-origin"}).then(function(b){if(!b.ok)throw"failed to load wasm binary file at '"+C+"'";return b.arrayBuffer()}).catch(function(){return Ga()});if(ka)return new Promise(function(b,c){ka(C,function(d){b(new Uint8Array(d))},c)})}return Promise.resolve().then(function(){return Ga()})}var Ia;function Ja(b){for(;0>0];case "i8":return y[b>>0];case "i16":return ta[b>>1];case "i32":return z[b>>2];case "i64":return z[b>>2];case "float":return va[b>>2];case "double":return wa[b>>3];case "*":return ua[b>>2];default:r("invalid type for getValue: "+c)}return null} +function D(b){var c="i8";c.endsWith("*")&&(c="*");switch(c){case "i1":y[b>>0]=0;break;case "i8":y[b>>0]=0;break;case "i16":ta[b>>1]=0;break;case "i32":z[b>>2]=0;break;case "i64":Ia=[0,0];z[b>>2]=Ia[0];z[b+4>>2]=Ia[1];break;case "float":va[b>>2]=0;break;case "double":wa[b>>3]=0;break;case "*":ua[b>>2]=0;break;default:r("invalid type for setValue: "+c)}}function La(b,c,d){for(var e=0;e>0]=b.charCodeAt(e);d||(y[c>>0]=0)} +function Ma(b,c,d){d=Array(0>>=0;if(2147483648=d;d*=2){var e=c*(1+.2/d);e=Math.min(e,b+100663296);var f=Math;e=Math.max(b,e);f=f.min.call(f,2147483648,e+(65536-e%65536)%65536);a:{try{oa.grow(f-sa.byteLength+65535>>>16);xa();var k=1;break a}catch(p){}k=void 0}if(k)return!0}return!1}}; +(function(){function b(f){a.asm=f.exports;oa=a.asm.c;xa();Aa.unshift(a.asm.d);A--;a.monitorRunDependencies&&a.monitorRunDependencies(A);0==A&&(null!==Da&&(clearInterval(Da),Da=null),B&&(f=B,B=null,f()))}function c(f){b(f.instance)}function d(f){return Ha().then(function(k){return WebAssembly.instantiate(k,e)}).then(function(k){return k}).then(f,function(k){n("failed to asynchronously prepare wasm: "+k);r(k)})}var e={a:Na};A++;a.monitorRunDependencies&&a.monitorRunDependencies(A);if(a.instantiateWasm)try{return a.instantiateWasm(e, +b)}catch(f){return n("Module.instantiateWasm callback failed with error: "+f),!1}(function(){return q||"function"!=typeof WebAssembly.instantiateStreaming||Ea()||C.startsWith("file://")||ia||"function"!=typeof fetch?d(c):fetch(C,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(c,function(k){n("wasm streaming compile failed: "+k);n("falling back to ArrayBuffer instantiation");return d(c)})})})().catch(ca);return{}})(); +a.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.d).apply(null,arguments)};a._olm_get_library_version=function(){return(a._olm_get_library_version=a.asm.f).apply(null,arguments)};a._olm_error=function(){return(a._olm_error=a.asm.g).apply(null,arguments)};a._olm_account_last_error=function(){return(a._olm_account_last_error=a.asm.h).apply(null,arguments)};a.__olm_error_to_string=function(){return(a.__olm_error_to_string=a.asm.i).apply(null,arguments)}; +a._olm_account_last_error_code=function(){return(a._olm_account_last_error_code=a.asm.j).apply(null,arguments)};a._olm_session_last_error=function(){return(a._olm_session_last_error=a.asm.k).apply(null,arguments)};a._olm_session_last_error_code=function(){return(a._olm_session_last_error_code=a.asm.l).apply(null,arguments)};a._olm_utility_last_error=function(){return(a._olm_utility_last_error=a.asm.m).apply(null,arguments)}; +a._olm_utility_last_error_code=function(){return(a._olm_utility_last_error_code=a.asm.n).apply(null,arguments)};a._olm_account_size=function(){return(a._olm_account_size=a.asm.o).apply(null,arguments)};a._olm_session_size=function(){return(a._olm_session_size=a.asm.p).apply(null,arguments)};a._olm_utility_size=function(){return(a._olm_utility_size=a.asm.q).apply(null,arguments)};a._olm_account=function(){return(a._olm_account=a.asm.r).apply(null,arguments)}; +a._olm_session=function(){return(a._olm_session=a.asm.s).apply(null,arguments)};a._olm_utility=function(){return(a._olm_utility=a.asm.t).apply(null,arguments)};a._olm_clear_account=function(){return(a._olm_clear_account=a.asm.u).apply(null,arguments)};a._olm_clear_session=function(){return(a._olm_clear_session=a.asm.v).apply(null,arguments)};a._olm_clear_utility=function(){return(a._olm_clear_utility=a.asm.w).apply(null,arguments)}; +a._olm_pickle_account_length=function(){return(a._olm_pickle_account_length=a.asm.x).apply(null,arguments)};a._olm_pickle_session_length=function(){return(a._olm_pickle_session_length=a.asm.y).apply(null,arguments)};a._olm_pickle_account=function(){return(a._olm_pickle_account=a.asm.z).apply(null,arguments)};a._olm_pickle_session=function(){return(a._olm_pickle_session=a.asm.A).apply(null,arguments)};a._olm_unpickle_account=function(){return(a._olm_unpickle_account=a.asm.B).apply(null,arguments)}; +a._olm_unpickle_session=function(){return(a._olm_unpickle_session=a.asm.C).apply(null,arguments)};a._olm_create_account_random_length=function(){return(a._olm_create_account_random_length=a.asm.D).apply(null,arguments)};a._olm_create_account=function(){return(a._olm_create_account=a.asm.E).apply(null,arguments)};a._olm_account_identity_keys_length=function(){return(a._olm_account_identity_keys_length=a.asm.F).apply(null,arguments)}; +a._olm_account_identity_keys=function(){return(a._olm_account_identity_keys=a.asm.G).apply(null,arguments)};a._olm_account_signature_length=function(){return(a._olm_account_signature_length=a.asm.H).apply(null,arguments)};a._olm_account_sign=function(){return(a._olm_account_sign=a.asm.I).apply(null,arguments)};a._olm_account_one_time_keys_length=function(){return(a._olm_account_one_time_keys_length=a.asm.J).apply(null,arguments)}; +a._olm_account_one_time_keys=function(){return(a._olm_account_one_time_keys=a.asm.K).apply(null,arguments)};a._olm_account_mark_keys_as_published=function(){return(a._olm_account_mark_keys_as_published=a.asm.L).apply(null,arguments)};a._olm_account_max_number_of_one_time_keys=function(){return(a._olm_account_max_number_of_one_time_keys=a.asm.M).apply(null,arguments)}; +a._olm_account_generate_one_time_keys_random_length=function(){return(a._olm_account_generate_one_time_keys_random_length=a.asm.N).apply(null,arguments)};a._olm_account_generate_one_time_keys=function(){return(a._olm_account_generate_one_time_keys=a.asm.O).apply(null,arguments)};a._olm_account_generate_fallback_key_random_length=function(){return(a._olm_account_generate_fallback_key_random_length=a.asm.P).apply(null,arguments)}; +a._olm_account_generate_fallback_key=function(){return(a._olm_account_generate_fallback_key=a.asm.Q).apply(null,arguments)};a._olm_account_fallback_key_length=function(){return(a._olm_account_fallback_key_length=a.asm.R).apply(null,arguments)};a._olm_account_fallback_key=function(){return(a._olm_account_fallback_key=a.asm.S).apply(null,arguments)};a._olm_account_unpublished_fallback_key_length=function(){return(a._olm_account_unpublished_fallback_key_length=a.asm.T).apply(null,arguments)}; +a._olm_account_unpublished_fallback_key=function(){return(a._olm_account_unpublished_fallback_key=a.asm.U).apply(null,arguments)};a._olm_account_forget_old_fallback_key=function(){return(a._olm_account_forget_old_fallback_key=a.asm.V).apply(null,arguments)};a._olm_create_outbound_session_random_length=function(){return(a._olm_create_outbound_session_random_length=a.asm.W).apply(null,arguments)};a._olm_create_outbound_session=function(){return(a._olm_create_outbound_session=a.asm.X).apply(null,arguments)}; +a._olm_create_inbound_session=function(){return(a._olm_create_inbound_session=a.asm.Y).apply(null,arguments)};a._olm_create_inbound_session_from=function(){return(a._olm_create_inbound_session_from=a.asm.Z).apply(null,arguments)};a._olm_session_id_length=function(){return(a._olm_session_id_length=a.asm._).apply(null,arguments)};a._olm_session_id=function(){return(a._olm_session_id=a.asm.$).apply(null,arguments)}; +a._olm_session_has_received_message=function(){return(a._olm_session_has_received_message=a.asm.aa).apply(null,arguments)};a._olm_session_describe=function(){return(a._olm_session_describe=a.asm.ba).apply(null,arguments)};a._olm_matches_inbound_session=function(){return(a._olm_matches_inbound_session=a.asm.ca).apply(null,arguments)};a._olm_matches_inbound_session_from=function(){return(a._olm_matches_inbound_session_from=a.asm.da).apply(null,arguments)}; +a._olm_remove_one_time_keys=function(){return(a._olm_remove_one_time_keys=a.asm.ea).apply(null,arguments)};a._olm_encrypt_message_type=function(){return(a._olm_encrypt_message_type=a.asm.fa).apply(null,arguments)};a._olm_encrypt_random_length=function(){return(a._olm_encrypt_random_length=a.asm.ga).apply(null,arguments)};a._olm_encrypt_message_length=function(){return(a._olm_encrypt_message_length=a.asm.ha).apply(null,arguments)}; +a._olm_encrypt=function(){return(a._olm_encrypt=a.asm.ia).apply(null,arguments)};a._olm_decrypt_max_plaintext_length=function(){return(a._olm_decrypt_max_plaintext_length=a.asm.ja).apply(null,arguments)};a._olm_decrypt=function(){return(a._olm_decrypt=a.asm.ka).apply(null,arguments)};a._olm_sha256_length=function(){return(a._olm_sha256_length=a.asm.la).apply(null,arguments)};a._olm_sha256=function(){return(a._olm_sha256=a.asm.ma).apply(null,arguments)}; +a._olm_ed25519_verify=function(){return(a._olm_ed25519_verify=a.asm.na).apply(null,arguments)};a._olm_pk_encryption_last_error=function(){return(a._olm_pk_encryption_last_error=a.asm.oa).apply(null,arguments)};a._olm_pk_encryption_last_error_code=function(){return(a._olm_pk_encryption_last_error_code=a.asm.pa).apply(null,arguments)};a._olm_pk_encryption_size=function(){return(a._olm_pk_encryption_size=a.asm.qa).apply(null,arguments)}; +a._olm_pk_encryption=function(){return(a._olm_pk_encryption=a.asm.ra).apply(null,arguments)};a._olm_clear_pk_encryption=function(){return(a._olm_clear_pk_encryption=a.asm.sa).apply(null,arguments)};a._olm_pk_encryption_set_recipient_key=function(){return(a._olm_pk_encryption_set_recipient_key=a.asm.ta).apply(null,arguments)};a._olm_pk_key_length=function(){return(a._olm_pk_key_length=a.asm.ua).apply(null,arguments)}; +a._olm_pk_ciphertext_length=function(){return(a._olm_pk_ciphertext_length=a.asm.va).apply(null,arguments)};a._olm_pk_mac_length=function(){return(a._olm_pk_mac_length=a.asm.wa).apply(null,arguments)};a._olm_pk_encrypt_random_length=function(){return(a._olm_pk_encrypt_random_length=a.asm.xa).apply(null,arguments)};a._olm_pk_encrypt=function(){return(a._olm_pk_encrypt=a.asm.ya).apply(null,arguments)}; +a._olm_pk_decryption_last_error=function(){return(a._olm_pk_decryption_last_error=a.asm.za).apply(null,arguments)};a._olm_pk_decryption_last_error_code=function(){return(a._olm_pk_decryption_last_error_code=a.asm.Aa).apply(null,arguments)};a._olm_pk_decryption_size=function(){return(a._olm_pk_decryption_size=a.asm.Ba).apply(null,arguments)};a._olm_pk_decryption=function(){return(a._olm_pk_decryption=a.asm.Ca).apply(null,arguments)}; +a._olm_clear_pk_decryption=function(){return(a._olm_clear_pk_decryption=a.asm.Da).apply(null,arguments)};a._olm_pk_private_key_length=function(){return(a._olm_pk_private_key_length=a.asm.Ea).apply(null,arguments)};a._olm_pk_generate_key_random_length=function(){return(a._olm_pk_generate_key_random_length=a.asm.Fa).apply(null,arguments)};a._olm_pk_key_from_private=function(){return(a._olm_pk_key_from_private=a.asm.Ga).apply(null,arguments)}; +a._olm_pk_generate_key=function(){return(a._olm_pk_generate_key=a.asm.Ha).apply(null,arguments)};a._olm_pickle_pk_decryption_length=function(){return(a._olm_pickle_pk_decryption_length=a.asm.Ia).apply(null,arguments)};a._olm_pickle_pk_decryption=function(){return(a._olm_pickle_pk_decryption=a.asm.Ja).apply(null,arguments)};a._olm_unpickle_pk_decryption=function(){return(a._olm_unpickle_pk_decryption=a.asm.Ka).apply(null,arguments)}; +a._olm_pk_max_plaintext_length=function(){return(a._olm_pk_max_plaintext_length=a.asm.La).apply(null,arguments)};a._olm_pk_decrypt=function(){return(a._olm_pk_decrypt=a.asm.Ma).apply(null,arguments)};a._olm_pk_get_private_key=function(){return(a._olm_pk_get_private_key=a.asm.Na).apply(null,arguments)};a._olm_pk_signing_size=function(){return(a._olm_pk_signing_size=a.asm.Oa).apply(null,arguments)};a._olm_pk_signing=function(){return(a._olm_pk_signing=a.asm.Pa).apply(null,arguments)}; +a._olm_pk_signing_last_error=function(){return(a._olm_pk_signing_last_error=a.asm.Qa).apply(null,arguments)};a._olm_pk_signing_last_error_code=function(){return(a._olm_pk_signing_last_error_code=a.asm.Ra).apply(null,arguments)};a._olm_clear_pk_signing=function(){return(a._olm_clear_pk_signing=a.asm.Sa).apply(null,arguments)};a._olm_pk_signing_seed_length=function(){return(a._olm_pk_signing_seed_length=a.asm.Ta).apply(null,arguments)}; +a._olm_pk_signing_public_key_length=function(){return(a._olm_pk_signing_public_key_length=a.asm.Ua).apply(null,arguments)};a._olm_pk_signing_key_from_seed=function(){return(a._olm_pk_signing_key_from_seed=a.asm.Va).apply(null,arguments)};a._olm_pk_signature_length=function(){return(a._olm_pk_signature_length=a.asm.Wa).apply(null,arguments)};a._olm_pk_sign=function(){return(a._olm_pk_sign=a.asm.Xa).apply(null,arguments)}; +a._olm_inbound_group_session_size=function(){return(a._olm_inbound_group_session_size=a.asm.Ya).apply(null,arguments)};a._olm_inbound_group_session=function(){return(a._olm_inbound_group_session=a.asm.Za).apply(null,arguments)};a._olm_clear_inbound_group_session=function(){return(a._olm_clear_inbound_group_session=a.asm._a).apply(null,arguments)};a._olm_inbound_group_session_last_error=function(){return(a._olm_inbound_group_session_last_error=a.asm.$a).apply(null,arguments)}; +a._olm_inbound_group_session_last_error_code=function(){return(a._olm_inbound_group_session_last_error_code=a.asm.ab).apply(null,arguments)};a._olm_init_inbound_group_session=function(){return(a._olm_init_inbound_group_session=a.asm.bb).apply(null,arguments)};a._olm_import_inbound_group_session=function(){return(a._olm_import_inbound_group_session=a.asm.cb).apply(null,arguments)}; +a._olm_pickle_inbound_group_session_length=function(){return(a._olm_pickle_inbound_group_session_length=a.asm.db).apply(null,arguments)};a._olm_pickle_inbound_group_session=function(){return(a._olm_pickle_inbound_group_session=a.asm.eb).apply(null,arguments)};a._olm_unpickle_inbound_group_session=function(){return(a._olm_unpickle_inbound_group_session=a.asm.fb).apply(null,arguments)}; +a._olm_group_decrypt_max_plaintext_length=function(){return(a._olm_group_decrypt_max_plaintext_length=a.asm.gb).apply(null,arguments)};a._olm_group_decrypt=function(){return(a._olm_group_decrypt=a.asm.hb).apply(null,arguments)};a._olm_inbound_group_session_id_length=function(){return(a._olm_inbound_group_session_id_length=a.asm.ib).apply(null,arguments)};a._olm_inbound_group_session_id=function(){return(a._olm_inbound_group_session_id=a.asm.jb).apply(null,arguments)}; +a._olm_inbound_group_session_first_known_index=function(){return(a._olm_inbound_group_session_first_known_index=a.asm.kb).apply(null,arguments)};a._olm_inbound_group_session_is_verified=function(){return(a._olm_inbound_group_session_is_verified=a.asm.lb).apply(null,arguments)};a._olm_export_inbound_group_session_length=function(){return(a._olm_export_inbound_group_session_length=a.asm.mb).apply(null,arguments)}; +a._olm_export_inbound_group_session=function(){return(a._olm_export_inbound_group_session=a.asm.nb).apply(null,arguments)};a._olm_outbound_group_session_size=function(){return(a._olm_outbound_group_session_size=a.asm.ob).apply(null,arguments)};a._olm_outbound_group_session=function(){return(a._olm_outbound_group_session=a.asm.pb).apply(null,arguments)};a._olm_clear_outbound_group_session=function(){return(a._olm_clear_outbound_group_session=a.asm.qb).apply(null,arguments)}; +a._olm_outbound_group_session_last_error=function(){return(a._olm_outbound_group_session_last_error=a.asm.rb).apply(null,arguments)};a._olm_outbound_group_session_last_error_code=function(){return(a._olm_outbound_group_session_last_error_code=a.asm.sb).apply(null,arguments)};a._olm_pickle_outbound_group_session_length=function(){return(a._olm_pickle_outbound_group_session_length=a.asm.tb).apply(null,arguments)}; +a._olm_pickle_outbound_group_session=function(){return(a._olm_pickle_outbound_group_session=a.asm.ub).apply(null,arguments)};a._olm_unpickle_outbound_group_session=function(){return(a._olm_unpickle_outbound_group_session=a.asm.vb).apply(null,arguments)};a._olm_init_outbound_group_session_random_length=function(){return(a._olm_init_outbound_group_session_random_length=a.asm.wb).apply(null,arguments)}; +a._olm_init_outbound_group_session=function(){return(a._olm_init_outbound_group_session=a.asm.xb).apply(null,arguments)};a._olm_group_encrypt_message_length=function(){return(a._olm_group_encrypt_message_length=a.asm.yb).apply(null,arguments)};a._olm_group_encrypt=function(){return(a._olm_group_encrypt=a.asm.zb).apply(null,arguments)};a._olm_outbound_group_session_id_length=function(){return(a._olm_outbound_group_session_id_length=a.asm.Ab).apply(null,arguments)}; +a._olm_outbound_group_session_id=function(){return(a._olm_outbound_group_session_id=a.asm.Bb).apply(null,arguments)};a._olm_outbound_group_session_message_index=function(){return(a._olm_outbound_group_session_message_index=a.asm.Cb).apply(null,arguments)};a._olm_outbound_group_session_key_length=function(){return(a._olm_outbound_group_session_key_length=a.asm.Db).apply(null,arguments)};a._olm_outbound_group_session_key=function(){return(a._olm_outbound_group_session_key=a.asm.Eb).apply(null,arguments)}; +a._olm_sas_last_error=function(){return(a._olm_sas_last_error=a.asm.Fb).apply(null,arguments)};a._olm_sas_last_error_code=function(){return(a._olm_sas_last_error_code=a.asm.Gb).apply(null,arguments)};a._olm_sas_size=function(){return(a._olm_sas_size=a.asm.Hb).apply(null,arguments)};a._olm_sas=function(){return(a._olm_sas=a.asm.Ib).apply(null,arguments)};a._olm_clear_sas=function(){return(a._olm_clear_sas=a.asm.Jb).apply(null,arguments)}; +a._olm_create_sas_random_length=function(){return(a._olm_create_sas_random_length=a.asm.Kb).apply(null,arguments)};a._olm_create_sas=function(){return(a._olm_create_sas=a.asm.Lb).apply(null,arguments)};a._olm_sas_pubkey_length=function(){return(a._olm_sas_pubkey_length=a.asm.Mb).apply(null,arguments)};a._olm_sas_get_pubkey=function(){return(a._olm_sas_get_pubkey=a.asm.Nb).apply(null,arguments)};a._olm_sas_set_their_key=function(){return(a._olm_sas_set_their_key=a.asm.Ob).apply(null,arguments)}; +a._olm_sas_is_their_key_set=function(){return(a._olm_sas_is_their_key_set=a.asm.Pb).apply(null,arguments)};a._olm_sas_generate_bytes=function(){return(a._olm_sas_generate_bytes=a.asm.Qb).apply(null,arguments)};a._olm_sas_mac_length=function(){return(a._olm_sas_mac_length=a.asm.Rb).apply(null,arguments)};a._olm_sas_calculate_mac_fixed_base64=function(){return(a._olm_sas_calculate_mac_fixed_base64=a.asm.Sb).apply(null,arguments)}; +a._olm_sas_calculate_mac=function(){return(a._olm_sas_calculate_mac=a.asm.Tb).apply(null,arguments)};a._olm_sas_calculate_mac_long_kdf=function(){return(a._olm_sas_calculate_mac_long_kdf=a.asm.Ub).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Vb).apply(null,arguments)};a._free=function(){return(a._free=a.asm.Wb).apply(null,arguments)}; +var Oa=a.stackSave=function(){return(Oa=a.stackSave=a.asm.Xb).apply(null,arguments)},Pa=a.stackRestore=function(){return(Pa=a.stackRestore=a.asm.Yb).apply(null,arguments)},Qa=a.stackAlloc=function(){return(Qa=a.stackAlloc=a.asm.Zb).apply(null,arguments)};a.UTF8ToString=t;a.stringToUTF8=v;a.intArrayFromString=Ma;a.writeAsciiToMemory=La;a.ALLOC_STACK=1;var Ra;B=function Sa(){Ra||Ta();Ra||(B=Sa)}; +function Ta(){function b(){if(!Ra&&(Ra=!0,a.calledRun=!0,!pa)){Ja(Aa);aa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;){var c=a.postRun.shift();Ba.unshift(c)}Ja(Ba)}}if(!(0 { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(Module) { + Module = Module || {}; + + +var a;a||(a=typeof Module !== 'undefined' ? Module : {});var aa,ba;a.ready=new Promise(function(b,c){aa=b;ba=c});var g;if("undefined"!==typeof window)g=function(b){window.crypto.getRandomValues(b)};else if(module.exports){var ca=require("crypto");g=function(b){var c=ca.randomBytes(b.length);b.set(c)}}else throw Error("Cannot find global to attach library to");if("undefined"!==typeof OLM_OPTIONS)for(var ea in OLM_OPTIONS)OLM_OPTIONS.hasOwnProperty(ea)&&(a[ea]=OLM_OPTIONS[ea]); +a.onRuntimeInitialized=function(){h=a._olm_error();olm_exports.PRIVATE_KEY_LENGTH=a._olm_pk_private_key_length();onInitSuccess&&onInitSuccess()};a.onAbort=function(b){onInitFail&&onInitFail(b)};var fa=Object.assign({},a),ha="object"==typeof window,l="function"==typeof importScripts,ia="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,m="",ja,ka,la,fs,ma,na; +if(ia)m=l?require("path").dirname(m)+"/":__dirname+"/",na=()=>{ma||(fs=require("fs"),ma=require("path"))},ja=function(b,c){var d=n(b);if(d)return c?d:d.toString();na();b=ma.normalize(b);return fs.readFileSync(b,c?void 0:"utf8")},la=b=>{b=ja(b,!0);b.buffer||(b=new Uint8Array(b));return b},ka=(b,c,d)=>{var e=n(b);e&&c(e);na();b=ma.normalize(b);fs.readFile(b,function(f,k){f?d(f):c(k.buffer)})},1{try{var c=new XMLHttpRequest;c.open("GET",b,!1);c.send(null);return c.responseText}catch(f){if(b=n(b)){c=[];for(var d=0;d{try{var c=new XMLHttpRequest;c.open("GET",b,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)}catch(d){if(b=n(b))return b;throw d;}}),ka=(b,c,d)=>{var e=new XMLHttpRequest;e.open("GET",b,!0);e.responseType="arraybuffer";e.onload=()=>{if(200==e.status||0==e.status&&e.response)c(e.response); +else{var f=n(b);f?c(f.buffer):d()}};e.onerror=d;e.send(null)};a.print||console.log.bind(console);var r=a.printErr||console.warn.bind(console);Object.assign(a,fa);fa=null;var t;a.wasmBinary&&(t=a.wasmBinary);var noExitRuntime=a.noExitRuntime||!0;function pa(){this.buffer=new ArrayBuffer(qa/65536*65536)}function ra(){this.exports=( +// EMSCRIPTEN_START_ASM +function instantiate(ea){function c(d){d.set=function(a,b){this[a]=b};d.get=function(a){return this[a]};return d}var e;var f=new Uint8Array(123);for(var a=25;a>=0;--a){f[48+a]=52+a;f[65+a]=a;f[97+a]=26+a}f[43]=62;f[47]=63;function l(m,n,o){var g,h,a=0,i=n,j=o.length,k=n+(j*3>>2)-(o[j-2]=="=")-(o[j-1]=="=");for(;a>4;if(i>2;if(i>2]=G[b+24|0]|G[b+25|0]<<8|(G[b+26|0]<<16|G[b+27|0]<<24);F[g+28>>2]=d;d=G[b+20|0]|G[b+21|0]<<8|(G[b+22|0]<<16|G[b+23|0]<<24);F[g+16>>2]=G[b+16|0]|G[b+17|0]<<8|(G[b+18|0]<<16|G[b+19|0]<<24);F[g+20>>2]=d;d=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);f=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);F[g>>2]=f;F[g+4>>2]=d;d=G[b+12|0]|G[b+13|0]<<8|(G[b+14|0]<<16|G[b+15|0]<<24);F[g+8>>2]=G[b+8|0]|G[b+9|0]<<8|(G[b+10|0]<<16|G[b+11|0]<<24);F[g+12>>2]=d;D[g|0]=f&248;D[g+31|0]=G[g+31|0]&63|64;e=G[c+3|0];b=G[c+2|0];d=b>>>16|0;F[g+112>>2]=e<<24&50331648|(G[c|0]|G[c+1|0]<<8|b<<16);F[g+116>>2]=d;b=G[c+4|0];f=b>>>24|0;e=b<<8|e;b=G[c+5|0];d=b>>>16|0;e=e|b<<16;d=d|f;n=G[c+6|0];b=n;f=b>>>8|0;h=b<<24;b=d|f;d=e|h;F[g+120>>2]=((b&3)<<30|d>>>2)&33554431;F[g+124>>2]=0;b=G[c+7|0];f=b>>>24|0;e=b<<8|n;b=G[c+8|0];d=b>>>16|0;e=e|b<<16;d=d|f;n=G[c+9|0];b=n;f=b>>>8|0;h=b<<24;b=d|f;d=e|h;F[g+128>>2]=((b&7)<<29|d>>>3)&67108863;F[g+132>>2]=0;b=G[c+10|0];f=b>>>24|0;e=b<<8|n;b=G[c+11|0];d=b>>>16|0;e=e|b<<16;d=d|f;n=G[c+12|0];b=n;f=b>>>8|0;h=b<<24;b=d|f;d=e|h;F[g+136>>2]=((b&31)<<27|d>>>5)&33554431;F[g+140>>2]=0;b=G[c+13|0];f=b>>>24|0;e=b<<8|n;b=G[c+14|0];d=b>>>16|0;e=e|b<<16;d=d|f;b=G[c+15|0];f=b>>>8|0;n=b<<24;b=d|f;f=e|n;F[g+144>>2]=(b&63)<<26|f>>>6;F[g+148>>2]=b>>>6;e=G[c+19|0];b=G[c+18|0];f=b>>>16|0;F[g+152>>2]=e<<24&16777216|(G[c+16|0]|G[c+17|0]<<8|b<<16);F[g+156>>2]=f;b=G[c+20|0];d=b>>>24|0;f=b<<8|e;b=d;e=f;f=G[c+21|0];d=f>>>16|0;f=e|f<<16;e=b|d;n=G[c+22|0];b=n;d=b>>>8|0;h=b<<24;b=d|e;d=f|h;F[g+160>>2]=((b&1)<<31|d>>>1)&67108863;F[g+164>>2]=0;b=G[c+23|0];d=b>>>24|0;e=b<<8|n;b=G[c+24|0];f=b>>>16|0;e=e|b<<16;f=d|f;n=G[c+25|0];b=n;d=b>>>8|0;h=b<<24;b=d|f;d=e|h;F[g+168>>2]=((b&7)<<29|d>>>3)&33554431;F[g+172>>2]=0;b=G[c+26|0];d=b>>>24|0;f=b<<8|n;b=d;e=f;f=G[c+27|0];d=f>>>16|0;f=e|f<<16;e=b|d;n=G[c+28|0];b=n;d=b>>>8|0;h=b<<24;b=d|e;d=f|h;F[g+176>>2]=((b&15)<<28|d>>>4)&67108863;F[g+180>>2]=0;b=G[c+29|0];d=b>>>24|0;e=b<<8|n;b=G[c+30|0];f=b>>>16|0;e=e|b<<16;f=d|f;b=G[c+31|0];d=b>>>8|0;c=b<<24|e;b=d|f;F[g+184>>2]=((b&63)<<26|c>>>6)&33554431;F[g+188>>2]=0;w=g+1152|0;qa(w,0,152);F[g+1152>>2]=1;F[g+1156>>2]=0;b=g+992|0;qa(b,0,152);F[g+992>>2]=1;F[g+996>>2]=0;c=g+832|0;qa(c,0,152);n=g+672|0;qa(n,0,152);l=g+512|0;qa(l,0,152);F[g+512>>2]=1;F[g+516>>2]=0;C=g+352|0;qa(C,0,152);U=g+192|0;qa(U,0,152);F[g+192>>2]=1;F[g+196>>2]=0;qa(g+1392|0,0,72);m=g+1312|0;ja(m,g+112|0,80);Na=g+2512|0;while(1){va=G[(g-ua|0)+31|0];xa=0;while(1){z=n;I=0-((va&128)>>>7|0)|0;n=m;f=F[n>>2];e=F[b>>2];d=I&(f^e);h=b;e=d^e;F[b>>2]=e;F[b+4>>2]=e>>31;d=d^f;F[n>>2]=d;F[n+4>>2]=d>>31;f=F[n+8>>2];e=F[b+8>>2];d=I&(f^e);e=d^e;F[b+8>>2]=e;F[b+12>>2]=e>>31;d=d^f;F[n+8>>2]=d;F[n+12>>2]=d>>31;f=F[n+16>>2];e=F[b+16>>2];d=I&(f^e);e=d^e;F[b+16>>2]=e;F[b+20>>2]=e>>31;d=d^f;F[n+16>>2]=d;F[n+20>>2]=d>>31;f=F[n+24>>2];e=F[b+24>>2];d=I&(f^e);e=d^e;F[b+24>>2]=e;F[b+28>>2]=e>>31;d=d^f;F[n+24>>2]=d;F[n+28>>2]=d>>31;f=F[n+32>>2];e=F[b+32>>2];d=I&(f^e);e=d^e;F[b+32>>2]=e;F[b+36>>2]=e>>31;d=d^f;F[n+32>>2]=d;F[n+36>>2]=d>>31;f=F[n+40>>2];e=F[b+40>>2];d=I&(f^e);e=d^e;F[b+40>>2]=e;F[b+44>>2]=e>>31;d=d^f;F[n+40>>2]=d;F[n+44>>2]=d>>31;f=F[n+48>>2];e=F[b+48>>2];d=I&(f^e);e=d^e;F[b+48>>2]=e;F[b+52>>2]=e>>31;d=d^f;F[n+48>>2]=d;F[n+52>>2]=d>>31;f=F[n+56>>2];e=F[b+56>>2];d=I&(f^e);e=d^e;F[b+56>>2]=e;F[b+60>>2]=e>>31;d=d^f;F[n+56>>2]=d;F[n+60>>2]=d>>31;f=F[n+64>>2];e=F[b+64>>2];d=I&(f^e);e=d^e;F[b+64>>2]=e;F[b+68>>2]=e>>31;d=d^f;F[n+64>>2]=d;F[n+68>>2]=d>>31;f=F[n+72>>2];e=F[b+72>>2];d=I&(f^e);e=d^e;F[b+72>>2]=e;F[b+76>>2]=e>>31;d=d^f;F[n+72>>2]=d;F[n+76>>2]=d>>31;i=w;f=F[i>>2];e=F[c>>2];d=I&(f^e);e=d^e;F[c>>2]=e;F[c+4>>2]=e>>31;d=d^f;F[i>>2]=d;F[i+4>>2]=d>>31;f=F[i+8>>2];e=F[c+8>>2];d=I&(f^e);e=d^e;F[c+8>>2]=e;F[c+12>>2]=e>>31;d=d^f;F[i+8>>2]=d;F[i+12>>2]=d>>31;f=F[i+16>>2];e=F[c+16>>2];d=I&(f^e);e=d^e;F[c+16>>2]=e;F[c+20>>2]=e>>31;d=d^f;F[i+16>>2]=d;F[i+20>>2]=d>>31;f=F[i+24>>2];e=F[c+24>>2];d=I&(f^e);e=d^e;F[c+24>>2]=e;F[c+28>>2]=e>>31;d=d^f;F[i+24>>2]=d;F[i+28>>2]=d>>31;f=F[i+32>>2];e=F[c+32>>2];d=I&(f^e);e=d^e;F[c+32>>2]=e;F[c+36>>2]=e>>31;d=d^f;F[i+32>>2]=d;F[i+36>>2]=d>>31;d=F[i+40>>2];t=F[c+40>>2];q=I&(d^t);d=d^q;F[i+40>>2]=d;F[i+44>>2]=d>>31;d=F[i+48>>2];A=F[c+48>>2];B=I&(d^A);d=d^B;F[i+48>>2]=d;F[i+52>>2]=d>>31;d=F[i+56>>2];k=c;x=F[c+56>>2];u=I&(d^x);d=d^u;F[i+56>>2]=d;F[i+60>>2]=d>>31;d=F[i+64>>2];M=F[c+64>>2];y=I&(d^M);d=d^y;F[i+64>>2]=d;F[i+68>>2]=d>>31;d=F[i+72>>2];Q=F[c+72>>2];v=I&(d^Q);d=d^v;F[i+72>>2]=d;F[i+76>>2]=d>>31;N=F[c+4>>2];O=F[b+4>>2];e=N+O|0;s=F[c>>2];w=F[b>>2];f=w;d=s+f|0;F[b>>2]=d;F[b+4>>2]=d>>>0>>0?e+1|0:e;P=F[c+12>>2];J=F[b+12>>2];e=P+J|0;c=F[c+8>>2];m=F[b+8>>2];d=m;b=c+d|0;F[h+8>>2]=b;F[h+12>>2]=b>>>0>>0?e+1|0:e;V=F[k+20>>2];E=F[h+20>>2];d=V+E|0;j=F[k+16>>2];p=F[h+16>>2];f=p;b=j+f|0;F[h+16>>2]=b;F[h+20>>2]=b>>>0>>0?d+1|0:d;Y=F[k+28>>2];X=F[h+28>>2];f=Y+X|0;o=F[k+24>>2];r=F[h+24>>2];d=r;b=o+d|0;F[h+24>>2]=b;F[h+28>>2]=b>>>0>>0?f+1|0:f;b=F[k+32>>2];W=F[k+36>>2];f=F[h+40>>2];d=q^t;q=d;e=f+d|0;S=F[h+44>>2];T=d>>31;d=S+T|0;F[h+40>>2]=e;F[h+44>>2]=e>>>0>>0?d+1|0:d;t=F[h+48>>2];e=A^B;B=e;d=t+e|0;R=F[h+52>>2];Z=e>>31;e=R+Z|0;F[h+48>>2]=d;F[h+52>>2]=d>>>0>>0?e+1|0:e;A=F[h+56>>2];e=x^u;u=e;d=A+e|0;aa=F[h+60>>2];ba=e>>31;e=aa+ba|0;F[h+56>>2]=d;F[h+60>>2]=d>>>0>>0?e+1|0:e;x=F[h+64>>2];d=y^M;y=d;e=x+d|0;K=F[h+68>>2];H=d>>31;d=K+H|0;F[h+64>>2]=e;F[h+68>>2]=e>>>0>>0?d+1|0:d;d=F[h+72>>2];e=v^Q;v=e;M=d+e|0;ca=F[h+76>>2];da=e>>31;e=ca+da|0;F[h+72>>2]=M;F[h+76>>2]=v>>>0>M>>>0?e+1|0:e;ea=F[h+36>>2];e=ea+W|0;M=F[h+32>>2];Q=M+b|0;F[h+32>>2]=Q;F[h+36>>2]=M>>>0>Q>>>0?e+1|0:e;F[k+72>>2]=d-v;F[k+76>>2]=ca-((d>>>0>>0)+da|0);F[k+64>>2]=x-y;F[k+68>>2]=K-((x>>>0>>0)+H|0);F[k+56>>2]=A-u;F[k+60>>2]=aa-((u>>>0>A>>>0)+ba|0);F[k+48>>2]=t-B;F[k+52>>2]=R-((t>>>0>>0)+Z|0);F[k+40>>2]=f-q;F[k+44>>2]=S-((f>>>0>>0)+T|0);F[k+32>>2]=M-b;F[k+36>>2]=ea-((b>>>0>M>>>0)+W|0);F[k+24>>2]=r-o;F[k+28>>2]=X-((o>>>0>r>>>0)+Y|0);F[k+16>>2]=p-j;F[k+20>>2]=E-((j>>>0>p>>>0)+V|0);F[k+8>>2]=m-c;F[k+12>>2]=J-((c>>>0>m>>>0)+P|0);F[k>>2]=w-s;F[k+4>>2]=O-((s>>>0>w>>>0)+N|0);Q=F[i+4>>2];N=F[n+4>>2];d=Q+N|0;b=F[i>>2];c=F[n>>2];f=b+c|0;F[n>>2]=f;F[n+4>>2]=c>>>0>f>>>0?d+1|0:d;O=F[i+12>>2];P=F[n+12>>2];e=O+P|0;s=F[i+8>>2];w=F[n+8>>2];f=w;d=s+f|0;F[n+8>>2]=d;F[n+12>>2]=d>>>0>>0?e+1|0:e;J=F[i+20>>2];V=F[n+20>>2];f=J+V|0;m=F[i+16>>2];j=F[n+16>>2];e=j;d=m+e|0;F[n+16>>2]=d;F[n+20>>2]=d>>>0>>0?f+1|0:f;E=F[i+28>>2];Y=F[n+28>>2];d=E+Y|0;p=F[i+24>>2];o=F[n+24>>2];e=o;f=p+e|0;F[n+24>>2]=f;F[n+28>>2]=e>>>0>f>>>0?d+1|0:d;X=F[i+36>>2];S=F[n+36>>2];e=X+S|0;r=F[i+32>>2];q=F[n+32>>2];f=q;d=r+f|0;F[n+32>>2]=d;F[n+36>>2]=d>>>0>>0?e+1|0:e;T=F[i+44>>2];R=F[n+44>>2];d=T+R|0;t=F[i+40>>2];B=F[n+40>>2];e=B;f=t+e|0;F[n+40>>2]=f;F[n+44>>2]=e>>>0>f>>>0?d+1|0:d;Z=F[i+52>>2];aa=F[n+52>>2];e=Z+aa|0;A=F[i+48>>2];u=F[n+48>>2];f=u;d=A+f|0;F[n+48>>2]=d;F[n+52>>2]=d>>>0>>0?e+1|0:e;ba=F[i+60>>2];K=F[n+60>>2];f=ba+K|0;x=F[i+56>>2];y=F[n+56>>2];e=y;d=x+e|0;F[n+56>>2]=d;F[n+60>>2]=d>>>0>>0?f+1|0:f;H=F[i+68>>2];ca=F[n+68>>2];d=H+ca|0;f=F[i+64>>2];v=F[n+64>>2];e=f+v|0;F[n+64>>2]=e;F[n+68>>2]=e>>>0>>0?d+1|0:d;da=F[i+76>>2];ea=F[n+76>>2];e=da+ea|0;d=F[i+72>>2];M=F[n+72>>2];W=d+M|0;F[n+72>>2]=W;F[n+76>>2]=M>>>0>W>>>0?e+1|0:e;F[i+72>>2]=M-d;F[i+76>>2]=ea-((d>>>0>M>>>0)+da|0);F[i+64>>2]=v-f;F[i+68>>2]=ca-((f>>>0>v>>>0)+H|0);F[i+56>>2]=y-x;F[i+60>>2]=K-((x>>>0>y>>>0)+ba|0);F[i+48>>2]=u-A;F[i+52>>2]=aa-((u>>>0>>0)+Z|0);F[i+40>>2]=B-t;F[i+44>>2]=R-((t>>>0>B>>>0)+T|0);F[i+32>>2]=q-r;F[i+36>>2]=S-((q>>>0>>0)+X|0);F[i+24>>2]=o-p;F[i+28>>2]=Y-((p>>>0>o>>>0)+E|0);F[i+16>>2]=j-m;F[i+20>>2]=V-((j>>>0>>0)+J|0);F[i+8>>2]=w-s;F[i+12>>2]=P-((s>>>0>w>>>0)+O|0);F[i>>2]=c-b;F[i+4>>2]=N-((b>>>0>c>>>0)+Q|0);ya=g+1952|0;ta(ya,n,k);ca=g+1792|0;ta(ca,h,i);Oa=F[g+2024>>2];t=F[g+2028>>2];B=F[g+2016>>2];Pa=F[g+2020>>2];da=F[g+2096>>2];ea=F[g+2100>>2];A=F[g+2008>>2];Qa=F[g+2012>>2];ha=F[g+2088>>2];ia=F[g+2092>>2];u=F[g+2e3>>2];Ra=F[g+2004>>2];ka=F[g+2080>>2];la=F[g+2084>>2];x=F[g+1992>>2];Sa=F[g+1996>>2];ma=F[g+2072>>2];ra=F[g+2076>>2];y=F[g+1984>>2];Ta=F[g+1988>>2];na=F[g+2064>>2];za=F[g+2068>>2];v=F[g+1976>>2];Ua=F[g+1980>>2];oa=F[g+2056>>2];pa=F[g+2060>>2];s=F[g+1968>>2];H=F[g+1972>>2];q=F[g+2048>>2];R=F[g+2052>>2];w=F[g+1960>>2];fa=F[g+1964>>2];Z=F[g+2040>>2];aa=F[g+2044>>2];j=F[g+1952>>2];sa=F[g+1956>>2];ba=F[g+2032>>2];K=F[g+2036>>2];F[g+2032>>2]=0;F[g+2036>>2]=0;Va=F[g+1864>>2];M=F[g+1868>>2];W=F[g+1856>>2];Wa=F[g+1860>>2];Aa=F[g+1936>>2];Ba=F[g+1940>>2];Q=F[g+1848>>2];Xa=F[g+1852>>2];Ca=F[g+1928>>2];Da=F[g+1932>>2];N=F[g+1840>>2];Ya=F[g+1844>>2];Ea=F[g+1920>>2];Fa=F[g+1924>>2];O=F[g+1832>>2];Za=F[g+1836>>2];Ga=F[g+1912>>2];Ha=F[g+1916>>2];P=F[g+1824>>2];_a=F[g+1828>>2];Ia=F[g+1904>>2];Ja=F[g+1908>>2];J=F[g+1816>>2];$a=F[g+1820>>2];Ka=F[g+1896>>2];La=F[g+1900>>2];b=F[g+1808>>2];d=F[g+1812>>2];f=F[g+1888>>2];e=F[g+1892>>2];c=F[g+1800>>2];Y=F[g+1804>>2];p=F[g+1880>>2];o=F[g+1884>>2];m=F[g+1792>>2];X=F[g+1796>>2];V=F[g+1872>>2];E=F[g+1876>>2];F[g+1872>>2]=0;F[g+1876>>2]=0;d=d+e|0;r=b+f|0;d=r>>>0>>0?d+1|0:d;f=se(f,e,18,0);b=f+r|0;e=$+d|0;S=b;r=b>>>0>>0?e+1|0:e;f=o+Y|0;b=c+p|0;f=b>>>0>>0?f+1|0:f;c=se(p,o,18,0);b=c+b|0;d=$+f|0;o=b;c=b>>>0>>0?d+1|0:d;e=E+X|0;b=m+V|0;e=b>>>0>>0?e+1|0:e;f=se(V,E,18,0);b=f+b|0;d=$+e|0;d=b>>>0>>0?d+1|0:d;V=d;m=d>>31>>>6|0;f=m+b|0;p=f;e=f>>>0>>0?d+1|0:d;E=e;d=e>>26;m=(e&67108863)<<6|f>>>26;e=m+o|0;f=c+d|0;c=e;f=e>>>0>>0?f+1|0:f;Y=f;e=f;m=e>>31>>>7|0;d=m+c|0;o=d;e=d>>>0>>0?e+1|0:e;X=e;f=e>>25;m=(e&33554431)<<7|d>>>25;e=m+S|0;d=f+r|0;f=e;d=e>>>0>>0?d+1|0:d;e=d;r=d>>31>>>6|0;m=r+f|0;Ma=m;d=m>>>0>>0?d+1|0:d;m=d;r=e;e=Ma&-67108864;d=r-((e>>>0>f>>>0)+d|0)|0;S=f-e|0;T=d;f=H+R|0;d=q+s|0;f=d>>>0>>0?f+1|0:f;s=se(q,R,18,0);d=s+d|0;e=$+f|0;H=d;R=d>>>0>>0?e+1|0:e;d=aa+fa|0;f=w+Z|0;d=f>>>0>>0?d+1|0:d;e=se(Z,aa,18,0);f=e+f|0;d=$+d|0;d=e>>>0>f>>>0?d+1|0:d;q=f;e=K+sa|0;f=j+ba|0;e=f>>>0>>0?e+1|0:e;w=se(ba,K,18,0);s=w+f|0;f=$+e|0;f=s>>>0>>0?f+1|0:f;Z=f;e=f;j=e>>31>>>6|0;w=j+s|0;r=w;e=j>>>0>r>>>0?e+1|0:e;aa=e;f=e>>26;w=(e&67108863)<<6|r>>>26;e=w+q|0;d=d+f|0;d=e>>>0>>0?d+1|0:d;w=e;ba=d;j=d>>31>>>7|0;f=j+w|0;q=f;e=f>>>0>>0?d+1|0:d;K=e;d=e>>25;e=(e&33554431)<<7|f>>>25;f=e+H|0;d=d+R|0;d=e>>>0>f>>>0?d+1|0:d;e=f;R=d>>31>>>6|0;j=R+e|0;fa=j;f=j>>>0>>0?d+1|0:d;j=f;R=fa&-67108864;H=e-R|0;sa=H+S|0;f=d-((e>>>0>>0)+f|0)|0;d=f+T|0;F[g+1968>>2]=sa;F[g+1972>>2]=H>>>0>sa>>>0?d+1|0:d;F[g+1808>>2]=H-S;F[g+1812>>2]=f-((H>>>0>>0)+T|0);f=La+$a|0;d=J+Ka|0;f=d>>>0>>0?f+1|0:f;J=se(Ka,La,18,0);e=J+d|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=e;e=m>>26;m=(m&67108863)<<6|Ma>>>26;f=f+m|0;e=d+e|0;e=f>>>0>>0?e+1|0:e;d=e;J=d>>31>>>7|0;m=f+J|0;R=m;d=m>>>0>>0?d+1|0:d;m=d;H=e;e=R&-33554432;d=H-((e>>>0>f>>>0)+d|0)|0;J=f-e|0;S=d;e=pa+Ua|0;d=v+oa|0;e=d>>>0>>0?e+1|0:e;v=se(oa,pa,18,0);f=v+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=f;f=j>>26;j=(j&67108863)<<6|fa>>>26;e=e+j|0;d=d+f|0;f=e;d=e>>>0>>0?d+1|0:d;v=d>>31>>>7|0;j=e+v|0;H=j;e=j>>>0>>0?d+1|0:d;j=e;pa=H&-33554432;T=f-pa|0;oa=T+J|0;d=d-((f>>>0>>0)+e|0)|0;f=d+S|0;F[g+1976>>2]=oa;F[g+1980>>2]=T>>>0>oa>>>0?f+1|0:f;F[g+1816>>2]=T-J;F[g+1820>>2]=d-((J>>>0>T>>>0)+S|0);e=Ja+_a|0;d=P+Ia|0;e=d>>>0

>>0?d+1|0:d;b=c;c=se(o,f,18,0);b=b+c|0;d=$+d|0;d=b>>>0>>0?d+1|0:d;o=d;p=d>>31>>>6|0;c=p+b|0;f=c>>>0

>>0?d+1|0:d;p=c;t=f;d=f>>26;f=(f&67108863)<<6|c>>>26;c=f+e|0;e=d+m|0;m=c;B=c>>>0>>0?e+1|0:e;c=q&-33554432;q=w-c|0;A=ba-((c>>>0>w>>>0)+K|0)|0;f=(j&33554431)<<7|y>>>25;d=r&-67108864;w=s-d|0;c=f+w|0;e=j>>25;d=e+(Z-((d>>>0>s>>>0)+aa|0)|0)|0;d=c>>>0>>0?d+1|0:d;f=se(f,e,18,0);c=f+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;w=d;s=d>>31>>>6|0;f=s+c|0;e=f>>>0>>0?d+1|0:d;s=f;d=q;q=(e&67108863)<<6|f>>>26;r=d+q|0;f=(e>>26)+A|0;f=q>>>0>r>>>0?f+1|0:f;A=r+m|0;q=f;d=f+B|0;F[g+1960>>2]=A;F[g+1964>>2]=r>>>0>A>>>0?d+1|0:d;f=p&-67108864;d=b-f|0;p=s&-67108864;s=c-p|0;j=d+s|0;b=o-((b>>>0>>0)+t|0)|0;c=w-((c>>>0

>>0)+e|0)|0;f=b+c|0;F[g+1952>>2]=j;F[g+1956>>2]=j>>>0>>0?f+1|0:f;F[g+1800>>2]=r-m;F[g+1804>>2]=q-((m>>>0>r>>>0)+B|0);F[g+1792>>2]=s-d;F[g+1796>>2]=c-((d>>>0>s>>>0)+b|0);X=g+1472|0;ga(X,ya);b=g+1632|0;ga(b,ca);ta(ca,b,g+112|0);m=F[g+1856>>2];S=F[g+1860>>2];y=F[g+1936>>2];v=F[g+1940>>2];j=F[g+1848>>2];T=F[g+1852>>2];M=F[g+1928>>2];W=F[g+1932>>2];p=F[g+1840>>2];R=F[g+1844>>2];Q=F[g+1920>>2];N=F[g+1924>>2];o=F[g+1832>>2];Z=F[g+1836>>2];O=F[g+1912>>2];P=F[g+1916>>2];r=F[g+1824>>2];aa=F[g+1828>>2];J=F[g+1904>>2];V=F[g+1908>>2];q=F[g+1816>>2];ba=F[g+1820>>2];E=F[g+1896>>2];Y=F[g+1900>>2];b=F[g+1808>>2];d=F[g+1812>>2];f=F[g+1888>>2];e=F[g+1892>>2];c=F[g+1800>>2];x=F[g+1804>>2];w=F[g+1880>>2];B=F[g+1884>>2];s=F[g+1792>>2];K=F[g+1796>>2];A=F[g+1872>>2];u=F[g+1876>>2];F[g+1872>>2]=0;F[g+1876>>2]=0;d=d+e|0;t=b+f|0;d=t>>>0>>0?d+1|0:d;f=se(f,e,18,0);b=f+t|0;e=$+d|0;H=b;t=b>>>0>>0?e+1|0:e;f=x+B|0;b=c+w|0;f=b>>>0>>0?f+1|0:f;c=se(w,B,18,0);b=c+b|0;d=$+f|0;w=b;c=b>>>0>>0?d+1|0:d;e=u+K|0;b=s+A|0;e=b>>>0>>0?e+1|0:e;f=se(A,u,18,0);b=f+b|0;d=$+e|0;d=b>>>0>>0?d+1|0:d;B=d;s=d>>31>>>6|0;f=s+b|0;e=f>>>0>>0?d+1|0:d;s=f;A=e;d=e>>26;u=w;w=(e&67108863)<<6|f>>>26;e=u+w|0;f=c+d|0;c=e;f=e>>>0>>0?f+1|0:f;u=f;w=f>>31>>>7|0;d=w+e|0;e=f;e=d>>>0>>0?e+1|0:e;w=d;x=e;f=e>>25;K=(e&33554431)<<7|d>>>25;e=K+H|0;d=f+t|0;f=e;d=e>>>0>>0?d+1|0:d;e=d;K=d>>31>>>6|0;t=K+f|0;d=t>>>0>>0?d+1|0:d;K=t&-67108864;F[g+1808>>2]=f-K;F[g+1812>>2]=e-((f>>>0>>0)+d|0);f=Y+ba|0;e=q+E|0;f=e>>>0>>0?f+1|0:f;E=se(E,Y,18,0);q=E+e|0;e=$+f|0;e=q>>>0>>0?e+1|0:e;t=(d&67108863)<<6|t>>>26;q=t+q|0;d=(d>>26)+e|0;f=q;d=f>>>0>>0?d+1|0:d;e=d;t=d>>31>>>7|0;q=t+f|0;d=q>>>0>>0?d+1|0:d;t=q&-33554432;F[g+1816>>2]=f-t;F[g+1820>>2]=e-((f>>>0>>0)+d|0);e=V+aa|0;f=r+J|0;e=f>>>0>>0?e+1|0:e;r=se(J,V,18,0);f=r+f|0;e=$+e|0;e=f>>>0>>0?e+1|0:e;q=(d&33554431)<<7|q>>>25;r=q+f|0;d=(d>>25)+e|0;f=r;d=q>>>0>f>>>0?d+1|0:d;e=d;q=d>>31>>>6|0;r=q+f|0;d=q>>>0>r>>>0?d+1|0:d;q=r&-67108864;F[g+1824>>2]=f-q;F[g+1828>>2]=e-((f>>>0>>0)+d|0);f=P+Z|0;e=o+O|0;f=e>>>0>>0?f+1|0:f;q=se(O,P,18,0);o=q+e|0;e=$+f|0;e=o>>>0>>0?e+1|0:e;r=(d&67108863)<<6|r>>>26;o=r+o|0;d=(d>>26)+e|0;f=o;d=f>>>0>>0?d+1|0:d;e=d;r=d>>31>>>7|0;o=r+f|0;d=o>>>0>>0?d+1|0:d;r=o&-33554432;F[g+1832>>2]=f-r;F[g+1836>>2]=e-((f>>>0>>0)+d|0);e=N+R|0;f=p+Q|0;e=f>>>0

>>0?e+1|0:e;p=se(Q,N,18,0);f=p+f|0;e=$+e|0;e=f>>>0

>>0?e+1|0:e;o=(d&33554431)<<7|o>>>25;p=o+f|0;d=(d>>25)+e|0;f=p;d=f>>>0>>0?d+1|0:d;e=d;o=d>>31>>>6|0;p=o+f|0;d=p>>>0>>0?d+1|0:d;o=p&-67108864;F[g+1840>>2]=f-o;F[g+1844>>2]=e-((f>>>0>>0)+d|0);f=T+W|0;e=j+M|0;f=e>>>0>>0?f+1|0:f;o=se(M,W,18,0);j=o+e|0;e=$+f|0;e=j>>>0>>0?e+1|0:e;p=(d&67108863)<<6|p>>>26;j=p+j|0;d=(d>>26)+e|0;f=j;d=f>>>0

>>0?d+1|0:d;e=d;p=d>>31>>>7|0;j=p+f|0;d=j>>>0

>>0?d+1|0:d;p=j&-33554432;F[g+1848>>2]=f-p;F[g+1852>>2]=e-((f>>>0

>>0)+d|0);e=v+S|0;f=m+y|0;e=f>>>0>>0?e+1|0:e;m=se(y,v,18,0);f=m+f|0;e=$+e|0;e=f>>>0>>0?e+1|0:e;j=(d&33554431)<<7|j>>>25;m=j+f|0;d=(d>>25)+e|0;f=m;d=j>>>0>f>>>0?d+1|0:d;e=d;p=d>>31>>>6|0;j=p+f|0;d=j>>>0

>>0?d+1|0:d;p=j&-67108864;F[g+1856>>2]=f-p;F[g+1860>>2]=e-((f>>>0

>>0)+d|0);e=d>>26;m=(d&67108863)<<6|j>>>26;d=m+F[g+1864>>2]|0;f=e+F[g+1868>>2]|0;f=d>>>0>>0?f+1|0:f;p=f>>31>>>7|0;j=p+d|0;e=f;e=j>>>0

>>0?e+1|0:e;p=j&-33554432;F[g+1864>>2]=d-p;F[g+1868>>2]=f-((d>>>0

>>0)+e|0);d=w&-33554432;w=c-d|0;m=u-((c>>>0>>0)+x|0)|0;d=e>>25;e=(e&33554431)<<7|j>>>25;f=s&-67108864;s=b-f|0;c=e+s|0;f=(B-((b>>>0>>0)+A|0)|0)+d|0;f=c>>>0>>0?f+1|0:f;b=c;c=se(e,d,18,0);b=b+c|0;e=$+f|0;e=b>>>0>>0?e+1|0:e;f=e;d=e;e=d>>31>>>6|0;c=e+b|0;d=c>>>0>>0?d+1|0:d;e=(d>>26)+m|0;j=(d&67108863)<<6|c>>>26;w=j+w|0;F[g+1800>>2]=w;F[g+1804>>2]=j>>>0>w>>>0?e+1|0:e;c=c&-67108864;F[g+1792>>2]=b-c;F[g+1796>>2]=f-((b>>>0>>0)+d|0);m=ja(z,X,80);w=l;E=ja(l,ca,80);c=g+2272|0;ga(c,h);Y=g+2112|0;ga(Y,k);b=C;ta(b,c,Y);j=F[b+64>>2];T=F[b+68>>2];y=F[b+144>>2];v=F[b+148>>2];p=F[b+56>>2];R=F[b+60>>2];M=F[b+136>>2];W=F[b+140>>2];o=F[b+48>>2];Z=F[b+52>>2];Q=F[b+128>>2];N=F[b+132>>2];r=F[b+40>>2];aa=F[b+44>>2];O=F[b+120>>2];P=F[b+124>>2];q=F[b+32>>2];ba=F[b+36>>2];J=F[b+112>>2];V=F[b+116>>2];z=F[b+24>>2];K=F[b+28>>2];X=F[b+104>>2];S=F[b+108>>2];c=F[b+16>>2];d=F[b+20>>2];e=F[b+96>>2];s=F[b+100>>2];f=F[b+8>>2];x=F[b+12>>2];C=F[b+88>>2];B=F[b+92>>2];l=F[b>>2];H=F[b+4>>2];A=F[b+80>>2];u=F[b+84>>2];F[b+80>>2]=0;F[b+84>>2]=0;d=d+s|0;t=c+e|0;d=t>>>0>>0?d+1|0:d;s=se(e,s,18,0);c=s+t|0;e=$+d|0;ca=c;t=c>>>0>>0?e+1|0:e;e=x+B|0;c=f+C|0;e=c>>>0>>0?e+1|0:e;f=se(C,B,18,0);c=f+c|0;d=$+e|0;x=c;C=c>>>0>>0?d+1|0:d;f=u+H|0;c=l+A|0;f=c>>>0>>0?f+1|0:f;e=se(A,u,18,0);c=e+c|0;d=$+f|0;d=c>>>0>>0?d+1|0:d;B=d;l=d>>31>>>6|0;f=l+c|0;s=f;e=f>>>0>>0?d+1|0:d;A=e;l=(e&67108863)<<6|f>>>26;f=l+x|0;e=(e>>26)+C|0;e=f>>>0>>0?e+1|0:e;l=f;u=e;f=e;e=e>>31>>>7|0;d=e+l|0;C=d;f=d>>>0>>0?f+1|0:f;x=f;e=f>>25;H=(f&33554431)<<7|d>>>25;f=H+ca|0;d=e+t|0;d=f>>>0>>0?d+1|0:d;e=d;H=d>>31>>>6|0;t=H+f|0;d=t>>>0>>0?d+1|0:d;H=t&-67108864;F[b+16>>2]=f-H;F[b+20>>2]=e-((f>>>0>>0)+d|0);e=K+S|0;f=z+X|0;e=f>>>0>>0?e+1|0:e;X=se(X,S,18,0);z=X+f|0;f=$+e|0;f=z>>>0>>0?f+1|0:f;t=(d&67108863)<<6|t>>>26;z=t+z|0;d=(d>>26)+f|0;f=z;d=t>>>0>f>>>0?d+1|0:d;e=d;t=d>>31>>>7|0;z=t+f|0;d=t>>>0>z>>>0?d+1|0:d;t=z&-33554432;F[b+24>>2]=f-t;F[b+28>>2]=e-((f>>>0>>0)+d|0);e=V+ba|0;f=q+J|0;e=f>>>0>>0?e+1|0:e;t=se(J,V,18,0);q=t+f|0;f=$+e|0;f=q>>>0>>0?f+1|0:f;z=(d&33554431)<<7|z>>>25;q=z+q|0;d=(d>>25)+f|0;f=q;d=f>>>0>>0?d+1|0:d;e=d;z=d>>31>>>6|0;q=z+f|0;d=q>>>0>>0?d+1|0:d;z=q&-67108864;F[b+32>>2]=f-z;F[b+36>>2]=e-((f>>>0>>0)+d|0);e=P+aa|0;f=r+O|0;e=f>>>0>>0?e+1|0:e;z=se(O,P,18,0);r=z+f|0;f=$+e|0;f=r>>>0>>0?f+1|0:f;q=(d&67108863)<<6|q>>>26;r=q+r|0;d=(d>>26)+f|0;f=r;d=q>>>0>f>>>0?d+1|0:d;e=d;q=d>>31>>>7|0;r=q+f|0;d=q>>>0>r>>>0?d+1|0:d;q=r&-33554432;F[b+40>>2]=f-q;F[b+44>>2]=e-((f>>>0>>0)+d|0);e=N+Z|0;f=o+Q|0;e=f>>>0>>0?e+1|0:e;q=se(Q,N,18,0);o=q+f|0;f=$+e|0;f=o>>>0>>0?f+1|0:f;r=(d&33554431)<<7|r>>>25;o=r+o|0;d=(d>>25)+f|0;f=o;d=f>>>0>>0?d+1|0:d;e=d;r=d>>31>>>6|0;o=r+f|0;d=o>>>0>>0?d+1|0:d;r=o&-67108864;F[b+48>>2]=f-r;F[b+52>>2]=e-((f>>>0>>0)+d|0);e=R+W|0;f=p+M|0;e=f>>>0

>>0?e+1|0:e;r=se(M,W,18,0);p=r+f|0;f=$+e|0;f=p>>>0>>0?f+1|0:f;o=(d&67108863)<<6|o>>>26;p=o+p|0;d=(d>>26)+f|0;f=p;d=f>>>0>>0?d+1|0:d;e=d;o=d>>31>>>7|0;p=o+f|0;d=p>>>0>>0?d+1|0:d;o=p&-33554432;F[b+56>>2]=f-o;F[b+60>>2]=e-((f>>>0>>0)+d|0);e=v+T|0;f=j+y|0;e=f>>>0>>0?e+1|0:e;o=se(y,v,18,0);j=o+f|0;f=$+e|0;f=j>>>0>>0?f+1|0:f;p=(d&33554431)<<7|p>>>25;j=p+j|0;d=(d>>25)+f|0;f=j;d=f>>>0

>>0?d+1|0:d;e=d;o=d>>31>>>6|0;p=o+f|0;d=p>>>0>>0?d+1|0:d;o=p&-67108864;F[b+64>>2]=f-o;F[b+68>>2]=e-((f>>>0>>0)+d|0);e=d>>26;j=(d&67108863)<<6|p>>>26;d=j+F[b+72>>2]|0;e=e+F[b+76>>2]|0;e=d>>>0>>0?e+1|0:e;o=e>>31>>>7|0;p=o+d|0;f=p>>>0>>0?e+1|0:e;o=p&-33554432;F[b+72>>2]=d-o;F[b+76>>2]=e-((d>>>0>>0)+f|0);d=C&-33554432;j=l-d|0;o=u-((d>>>0>l>>>0)+x|0)|0;d=f>>25;l=(f&33554431)<<7|p>>>25;e=s&-67108864;s=c-e|0;f=l+s|0;e=(B-((c>>>0>>0)+A|0)|0)+d|0;d=se(l,d,18,0);c=d+f|0;e=$+(f>>>0>>0?e+1|0:e)|0;e=c>>>0>>0?e+1|0:e;s=e;d=e;e=d>>31>>>6|0;f=e+c|0;l=f;d=e>>>0>f>>>0?d+1|0:d;p=(d&67108863)<<6|f>>>26;j=p+j|0;f=(d>>26)+o|0;F[b+8>>2]=j;F[b+12>>2]=j>>>0

>>0?f+1|0:f;f=l&-67108864;F[b>>2]=c-f;F[b+4>>2]=s-((c>>>0>>0)+d|0);j=F[g+2316>>2];H=F[g+2312>>2];d=H;f=F[g+2152>>2];c=j-(F[g+2156>>2]+(d>>>0>>0)|0)|0;X=d-f|0;p=c;F[g+2152>>2]=X;F[g+2156>>2]=c;o=F[g+2308>>2];ca=F[g+2304>>2];d=ca;f=F[g+2144>>2];c=o-(F[g+2148>>2]+(d>>>0>>0)|0)|0;S=d-f|0;r=c;F[g+2144>>2]=S;F[g+2148>>2]=c;q=F[g+2300>>2];da=F[g+2296>>2];d=da;f=F[g+2136>>2];c=q-(F[g+2140>>2]+(d>>>0>>0)|0)|0;T=d-f|0;z=c;F[g+2136>>2]=T;F[g+2140>>2]=c;d=F[g+2292>>2];f=F[g+2288>>2];l=F[g+2128>>2];e=d-(F[g+2132>>2]+(f>>>0>>0)|0)|0;C=f-l|0;F[g+2128>>2]=C;F[g+2132>>2]=e;ea=F[g+2284>>2];t=F[g+2280>>2];c=t;s=F[g+2120>>2];l=ea-(F[g+2124>>2]+(c>>>0>>0)|0)|0;O=c-s|0;F[g+2120>>2]=O;F[g+2124>>2]=l;ha=F[g+2276>>2];B=F[g+2272>>2];c=B;A=F[g+2112>>2];s=ha-(F[g+2116>>2]+(c>>>0>>0)|0)|0;P=c-A|0;F[g+2112>>2]=P;F[g+2116>>2]=s;A=F[g+2324>>2];ia=F[g+2320>>2];u=ia;x=F[g+2160>>2];c=A-(F[g+2164>>2]+(u>>>0>>0)|0)|0;R=u-x|0;u=c;F[g+2160>>2]=R;F[g+2164>>2]=c;x=F[g+2332>>2];ka=F[g+2328>>2];y=ka;v=F[g+2168>>2];c=x-(F[g+2172>>2]+(y>>>0>>0)|0)|0;Z=y-v|0;y=c;F[g+2168>>2]=Z;F[g+2172>>2]=c;v=F[g+2340>>2];la=F[g+2336>>2];M=la;W=F[g+2176>>2];c=v-(F[g+2180>>2]+(M>>>0>>0)|0)|0;aa=M-W|0;M=c;F[g+2176>>2]=aa;F[g+2180>>2]=c;W=F[g+2348>>2];ma=F[g+2344>>2];Q=ma;N=F[g+2184>>2];c=W-(F[g+2188>>2]+(Q>>>0>>0)|0)|0;ba=Q-N|0;Q=c;F[g+2184>>2]=ba;F[g+2188>>2]=c;qa(Na,0,72);N=d;V=se(C,e,121665,0);K=$;l=se(O,l,121665,0);C=$;c=se(P,s,121665,0);d=$;ra=d;s=d>>31>>>6|0;e=s+c|0;d=e>>>0>>0?d+1|0:d;s=e;O=d;e=d>>26;P=l;l=(d&67108863)<<6|s>>>26;d=P+l|0;e=e+C|0;e=d>>>0>>0?e+1|0:e;l=d;P=e;d=e;C=d>>31>>>7|0;e=C+l|0;d=e>>>0>>0?d+1|0:d;C=e;J=d;fa=f;e=d>>25;f=V;V=(d&33554431)<<7|C>>>25;d=f+V|0;f=e+K|0;f=d>>>0>>0?f+1|0:f;V=fa+d|0;e=f+N|0;e=d>>>0>V>>>0?e+1|0:e;N=V;na=f>>31>>>6|0;K=na+d|0;d=f;d=K>>>0>>0?d+1|0:d;f=K&-67108864;F[g+2448>>2]=N-f;F[g+2452>>2]=e-((f>>>0>N>>>0)+d|0);f=d;d=d>>26;N=(f&67108863)<<6|K>>>26;e=se(T,z,121665,0)+N|0;f=d+$|0;d=e;z=d+da|0;f=d>>>0>>0?f+1|0:f;e=f+q|0;q=z;z=d>>>0>q>>>0?e+1|0:e;e=f;f=e>>31>>>7|0;d=f+d|0;e=d>>>0>>0?e+1|0:e;f=d;d=d&-33554432;F[g+2456>>2]=q-d;F[g+2460>>2]=z-((d>>>0>q>>>0)+e|0);d=e;e=d>>25;q=(d&33554431)<<7|f>>>25;d=se(S,r,121665,0)+q|0;f=e+$|0;e=d;r=d+ca|0;f=d>>>0>>0?f+1|0:f;d=f+o|0;d=e>>>0>r>>>0?d+1|0:d;o=r;z=f>>31>>>6|0;q=z+e|0;e=f;e=q>>>0>>0?e+1|0:e;f=q;q=f&-67108864;F[g+2464>>2]=o-q;F[g+2468>>2]=d-((o>>>0>>0)+e|0);d=e;e=d>>26;o=(d&67108863)<<6|f>>>26;d=se(X,p,121665,0)+o|0;f=e+$|0;f=d>>>0>>0?f+1|0:f;p=d+H|0;e=f+j|0;e=d>>>0>p>>>0?e+1|0:e;j=p;r=f>>31>>>7|0;o=r+d|0;d=f;d=o>>>0>>0?d+1|0:d;f=o&-33554432;F[g+2472>>2]=j-f;F[g+2476>>2]=e-((f>>>0>j>>>0)+d|0);f=d;d=d>>25;p=(f&33554431)<<7|o>>>25;e=se(R,u,121665,0)+p|0;f=d+$|0;d=e;j=d+ia|0;f=d>>>0

>>0?f+1|0:f;e=f+A|0;e=d>>>0>j>>>0?e+1|0:e;p=e;e=f;f=e>>31>>>6|0;d=f+d|0;e=d>>>0>>0?e+1|0:e;f=d;d=d&-67108864;F[g+2480>>2]=j-d;F[g+2484>>2]=p-((d>>>0>j>>>0)+e|0);d=e;e=d>>26;p=(d&67108863)<<6|f>>>26;d=se(Z,y,121665,0)+p|0;f=e+$|0;e=d;j=d+ka|0;f=d>>>0

>>0?f+1|0:f;d=f+x|0;d=e>>>0>j>>>0?d+1|0:d;r=f>>31>>>7|0;o=r+e|0;e=f;e=o>>>0>>0?e+1|0:e;f=o;o=f&-33554432;F[g+2488>>2]=j-o;F[g+2492>>2]=d-((j>>>0>>0)+e|0);d=e;e=d>>25;p=(d&33554431)<<7|f>>>25;d=se(aa,M,121665,0)+p|0;f=e+$|0;f=d>>>0

>>0?f+1|0:f;j=d+la|0;e=f+v|0;e=d>>>0>j>>>0?e+1|0:e;r=f>>31>>>6|0;o=r+d|0;d=f;d=o>>>0>>0?d+1|0:d;f=o&-67108864;F[g+2496>>2]=j-f;F[g+2500>>2]=e-((f>>>0>j>>>0)+d|0);f=d;d=d>>26;p=(f&67108863)<<6|o>>>26;e=se(ba,Q,121665,0)+p|0;f=d+$|0;d=e;j=d+ma|0;f=d>>>0

>>0?f+1|0:f;e=f+W|0;e=d>>>0>j>>>0?e+1|0:e;p=e;e=f;f=e>>31>>>7|0;d=f+d|0;e=d>>>0>>0?e+1|0:e;f=d&-33554432;F[g+2504>>2]=j-f;F[g+2508>>2]=p-((f>>>0>j>>>0)+e|0);f=P+ea|0;l=l+t|0;f=l>>>0>>0?f+1|0:f;C=C&-33554432;j=l-C|0;p=f-((l>>>0>>0)+J|0)|0;f=e>>25;l=(e&33554431)<<7|d>>>25;d=s&-67108864;s=c-d|0;e=l+s|0;d=(ra-((c>>>0>>0)+O|0)|0)+f|0;f=se(l,f,18,0);c=f+e|0;d=$+(e>>>0>>0?d+1|0:d)|0;d=c>>>0>>0?d+1|0:d;l=d>>31>>>6|0;e=l+c|0;f=e>>>0>>0?d+1|0:d;l=e;e=(f>>26)+p|0;o=(f&67108863)<<6|l>>>26;j=o+j|0;F[g+2440>>2]=j;F[g+2444>>2]=j>>>0>>0?e+1|0:e;d=d+ha|0;c=c+B|0;d=c>>>0>>0?d+1|0:d;e=l&-67108864;F[g+2432>>2]=c-e;F[g+2436>>2]=d-((c>>>0>>0)+f|0);c=U;ta(c,Y,g+2432|0);j=F[c+64>>2];S=F[c+68>>2];y=F[c+144>>2];v=F[c+148>>2];p=F[c+56>>2];T=F[c+60>>2];M=F[c+136>>2];W=F[c+140>>2];o=F[c+48>>2];R=F[c+52>>2];Q=F[c+128>>2];N=F[c+132>>2];r=F[c+40>>2];Z=F[c+44>>2];O=F[c+120>>2];P=F[c+124>>2];q=F[c+32>>2];aa=F[c+36>>2];J=F[c+112>>2];V=F[c+116>>2];z=F[c+24>>2];ba=F[c+28>>2];Y=F[c+104>>2];X=F[c+108>>2];d=F[c+16>>2];f=F[c+20>>2];e=F[c+96>>2];C=F[c+100>>2];l=F[c+8>>2];x=F[c+12>>2];U=F[c+88>>2];B=F[c+92>>2];s=F[c>>2];K=F[c+4>>2];A=F[c+80>>2];u=F[c+84>>2];F[c+80>>2]=0;F[c+84>>2]=0;f=f+C|0;t=d+e|0;f=t>>>0>>0?f+1|0:f;C=se(e,C,18,0);d=C+t|0;e=$+f|0;H=d;t=d>>>0>>0?e+1|0:e;d=x+B|0;f=l+U|0;d=f>>>0>>0?d+1|0:d;e=se(U,B,18,0);f=e+f|0;d=$+d|0;d=e>>>0>f>>>0?d+1|0:d;U=f;e=u+K|0;f=s+A|0;e=f>>>0>>0?e+1|0:e;s=se(A,u,18,0);l=s+f|0;f=$+e|0;f=l>>>0>>0?f+1|0:f;B=f;C=f>>31>>>6|0;s=C+l|0;e=f;e=s>>>0>>0?e+1|0:e;C=s;A=e;f=e>>26;s=(e&67108863)<<6|s>>>26;e=s+U|0;d=d+f|0;d=e>>>0>>0?d+1|0:d;s=e;u=d;U=d>>31>>>7|0;f=U+e|0;e=f>>>0>>0?d+1|0:d;U=f;x=e;d=e>>25;e=(e&33554431)<<7|f>>>25;f=e+H|0;d=d+t|0;d=e>>>0>f>>>0?d+1|0:d;e=f;K=d>>31>>>6|0;t=K+e|0;f=t>>>0>>0?d+1|0:d;K=t&-67108864;F[c+16>>2]=e-K;F[c+20>>2]=d-((e>>>0>>0)+f|0);d=X+ba|0;e=z+Y|0;d=e>>>0>>0?d+1|0:d;Y=se(Y,X,18,0);z=Y+e|0;e=$+d|0;e=z>>>0>>0?e+1|0:e;t=(f&67108863)<<6|t>>>26;z=t+z|0;f=(f>>26)+e|0;e=z;f=t>>>0>e>>>0?f+1|0:f;d=f;t=d>>31>>>7|0;z=t+e|0;d=t>>>0>z>>>0?d+1|0:d;t=z&-33554432;F[c+24>>2]=e-t;F[c+28>>2]=f-((e>>>0>>0)+d|0);e=V+aa|0;f=q+J|0;e=f>>>0>>0?e+1|0:e;q=se(J,V,18,0);f=q+f|0;e=$+e|0;e=f>>>0>>0?e+1|0:e;H=f;f=d;d=d>>25;q=(f&33554431)<<7|z>>>25;f=H+q|0;d=d+e|0;d=f>>>0>>0?d+1|0:d;e=f;z=d>>31>>>6|0;q=z+e|0;f=q>>>0>>0?d+1|0:d;z=q&-67108864;F[c+32>>2]=e-z;F[c+36>>2]=d-((e>>>0>>0)+f|0);d=P+Z|0;e=r+O|0;d=e>>>0>>0?d+1|0:d;z=se(O,P,18,0);r=z+e|0;e=$+d|0;e=r>>>0>>0?e+1|0:e;q=(f&67108863)<<6|q>>>26;r=q+r|0;f=(f>>26)+e|0;e=r;f=q>>>0>e>>>0?f+1|0:f;d=f;q=d>>31>>>7|0;r=q+e|0;d=q>>>0>r>>>0?d+1|0:d;q=r&-33554432;F[c+40>>2]=e-q;F[c+44>>2]=f-((e>>>0>>0)+d|0);e=N+R|0;f=o+Q|0;e=f>>>0>>0?e+1|0:e;o=se(Q,N,18,0);f=o+f|0;e=$+e|0;e=f>>>0>>0?e+1|0:e;q=f;f=d;d=d>>25;o=(f&33554431)<<7|r>>>25;f=q+o|0;d=d+e|0;d=f>>>0>>0?d+1|0:d;e=f;r=d>>31>>>6|0;o=r+e|0;f=o>>>0>>0?d+1|0:d;r=o&-67108864;F[c+48>>2]=e-r;F[c+52>>2]=d-((e>>>0>>0)+f|0);d=T+W|0;e=p+M|0;d=e>>>0

>>0?d+1|0:d;r=se(M,W,18,0);p=r+e|0;e=$+d|0;e=p>>>0>>0?e+1|0:e;o=(f&67108863)<<6|o>>>26;p=o+p|0;f=(f>>26)+e|0;e=p;f=e>>>0>>0?f+1|0:f;d=f;o=d>>31>>>7|0;p=o+e|0;d=p>>>0>>0?d+1|0:d;o=p&-33554432;F[c+56>>2]=e-o;F[c+60>>2]=f-((e>>>0>>0)+d|0);e=v+S|0;f=j+y|0;e=f>>>0>>0?e+1|0:e;j=se(y,v,18,0);f=j+f|0;e=$+e|0;e=f>>>0>>0?e+1|0:e;q=f;f=d;d=d>>25;j=(f&33554431)<<7|p>>>25;f=q+j|0;d=d+e|0;d=f>>>0>>0?d+1|0:d;e=c;j=f;o=d>>31>>>6|0;p=o+f|0;f=p>>>0>>0?d+1|0:d;o=p&-67108864;F[e+64>>2]=j-o;F[e+68>>2]=d-((j>>>0>>0)+f|0);e=f>>26;j=(f&67108863)<<6|p>>>26;f=j+F[c+72>>2]|0;d=e+F[c+76>>2]|0;d=f>>>0>>0?d+1|0:d;o=d>>31>>>7|0;p=o+f|0;e=p>>>0>>0?d+1|0:d;o=p&-33554432;F[c+72>>2]=f-o;F[c+76>>2]=d-((f>>>0>>0)+e|0);d=U&-33554432;U=s-d|0;j=u-((d>>>0>s>>>0)+x|0)|0;d=e>>25;s=(e&33554431)<<7|p>>>25;C=C&-67108864;p=l-C|0;e=s+p|0;f=d;d=d+(B-((l>>>0>>0)+A|0)|0)|0;l=se(s,f,18,0);f=l+e|0;e=$+(e>>>0

>>0?d+1|0:d)|0;e=f>>>0>>0?e+1|0:e;s=e;d=e;l=d>>31>>>6|0;e=l+f|0;d=e>>>0>>0?d+1|0:d;l=e;e=(d>>26)+j|0;p=(d&67108863)<<6|l>>>26;U=p+U|0;F[c+8>>2]=U;F[c+12>>2]=p>>>0>U>>>0?e+1|0:e;e=l&-67108864;F[c>>2]=f-e;F[c+4>>2]=s-((e>>>0>f>>>0)+d|0);f=F[m>>2];e=F[b>>2];d=I&(f^e);e=d^e;F[b>>2]=e;F[b+4>>2]=e>>31;d=d^f;F[m>>2]=d;F[m+4>>2]=d>>31;f=F[m+8>>2];e=F[b+8>>2];d=I&(f^e);e=d^e;F[b+8>>2]=e;F[b+12>>2]=e>>31;d=d^f;F[m+8>>2]=d;F[m+12>>2]=d>>31;f=F[m+16>>2];e=F[b+16>>2];d=I&(f^e);e=d^e;F[b+16>>2]=e;F[b+20>>2]=e>>31;d=d^f;F[m+16>>2]=d;F[m+20>>2]=d>>31;f=F[m+24>>2];e=F[b+24>>2];d=I&(f^e);e=d^e;F[b+24>>2]=e;F[b+28>>2]=e>>31;d=d^f;F[m+24>>2]=d;F[m+28>>2]=d>>31;f=F[m+32>>2];e=F[b+32>>2];d=I&(f^e);e=d^e;F[b+32>>2]=e;F[b+36>>2]=e>>31;d=d^f;F[m+32>>2]=d;F[m+36>>2]=d>>31;f=F[m+40>>2];e=F[b+40>>2];d=I&(f^e);e=d^e;F[b+40>>2]=e;F[b+44>>2]=e>>31;d=d^f;F[m+40>>2]=d;F[m+44>>2]=d>>31;f=F[m+48>>2];e=F[b+48>>2];d=I&(f^e);e=d^e;F[b+48>>2]=e;F[b+52>>2]=e>>31;d=d^f;F[m+48>>2]=d;F[m+52>>2]=d>>31;f=F[m+56>>2];e=F[b+56>>2];d=I&(f^e);e=d^e;F[b+56>>2]=e;F[b+60>>2]=e>>31;d=d^f;F[m+56>>2]=d;F[m+60>>2]=d>>31;f=F[m+64>>2];e=F[b+64>>2];d=I&(f^e);e=d^e;F[b+64>>2]=e;F[b+68>>2]=e>>31;d=d^f;F[m+64>>2]=d;F[m+68>>2]=d>>31;f=F[m+72>>2];e=F[b+72>>2];d=I&(f^e);e=d^e;F[b+72>>2]=e;F[b+76>>2]=e>>31;d=d^f;F[m+72>>2]=d;F[m+76>>2]=d>>31;f=F[E>>2];e=F[c>>2];d=I&(f^e);e=d^e;F[c>>2]=e;F[c+4>>2]=e>>31;d=d^f;F[E>>2]=d;F[E+4>>2]=d>>31;f=F[E+8>>2];e=F[c+8>>2];d=I&(f^e);e=d^e;F[c+8>>2]=e;F[c+12>>2]=e>>31;d=d^f;F[E+8>>2]=d;F[E+12>>2]=d>>31;f=F[E+16>>2];e=F[c+16>>2];d=I&(f^e);e=d^e;F[c+16>>2]=e;F[c+20>>2]=e>>31;d=d^f;F[E+16>>2]=d;F[E+20>>2]=d>>31;f=F[E+24>>2];e=F[c+24>>2];d=I&(f^e);e=d^e;F[c+24>>2]=e;F[c+28>>2]=e>>31;d=d^f;F[E+24>>2]=d;F[E+28>>2]=d>>31;f=F[E+32>>2];e=F[c+32>>2];d=I&(f^e);e=d^e;F[c+32>>2]=e;F[c+36>>2]=e>>31;d=d^f;F[E+32>>2]=d;F[E+36>>2]=d>>31;f=F[E+40>>2];e=F[c+40>>2];d=I&(f^e);e=d^e;F[c+40>>2]=e;F[c+44>>2]=e>>31;d=d^f;F[E+40>>2]=d;F[E+44>>2]=d>>31;f=F[E+48>>2];e=F[c+48>>2];d=I&(f^e);e=d^e;F[c+48>>2]=e;F[c+52>>2]=e>>31;d=d^f;F[E+48>>2]=d;F[E+52>>2]=d>>31;f=F[E+56>>2];e=F[c+56>>2];d=I&(f^e);e=d^e;F[c+56>>2]=e;F[c+60>>2]=e>>31;d=d^f;F[E+56>>2]=d;F[E+60>>2]=d>>31;f=F[E+64>>2];e=F[c+64>>2];d=I&(f^e);e=d^e;F[c+64>>2]=e;F[c+68>>2]=e>>31;d=d^f;F[E+64>>2]=d;F[E+68>>2]=d>>31;f=F[E+72>>2];e=F[c+72>>2];d=I&(f^e);e=d^e;F[c+72>>2]=e;F[c+76>>2]=e>>31;d=d^f;F[E+72>>2]=d;F[E+76>>2]=d>>31;va=va<<1;U=k;C=h;l=i;xa=xa+1|0;if((xa|0)!=8){continue}break}ua=ua+1|0;if((ua|0)!=32){continue}break}ja(g+32|0,b,80);d=g+2272|0;ja(d,c,80);h=g+2112|0;ga(h,d);c=g+672|0;ga(c,h);b=g+832|0;ga(b,c);n=g+2432|0;ta(n,b,d);e=F[g+2576>>2];i=F[g+2496>>2];d=e+i|0;k=F[g+2580>>2];f=k+F[g+2500>>2]|0;f=d>>>0>>0?f+1|0:f;i=se(e,k,18,0);d=i+d|0;e=$+f|0;F[g+2496>>2]=d;F[g+2500>>2]=d>>>0>>0?e+1|0:e;e=F[g+2568>>2];i=F[g+2488>>2];f=e+i|0;k=F[g+2572>>2];d=k+F[g+2492>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);f=i+f|0;e=$+d|0;F[g+2488>>2]=f;F[g+2492>>2]=f>>>0>>0?e+1|0:e;e=F[g+2560>>2];i=F[g+2480>>2];f=e+i|0;k=F[g+2564>>2];d=k+F[g+2484>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);e=i+f|0;f=$+d|0;F[g+2480>>2]=e;F[g+2484>>2]=e>>>0>>0?f+1|0:f;f=F[g+2552>>2];i=F[g+2472>>2];d=f+i|0;k=F[g+2556>>2];e=k+F[g+2476>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2472>>2]=f;F[g+2476>>2]=f>>>0>>0?d+1|0:d;f=F[g+2544>>2];i=F[g+2464>>2];d=f+i|0;k=F[g+2548>>2];e=k+F[g+2468>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2464>>2]=f;F[g+2468>>2]=f>>>0>>0?d+1|0:d;e=F[g+2536>>2];i=F[g+2456>>2];d=e+i|0;k=F[g+2540>>2];f=k+F[g+2460>>2]|0;f=d>>>0>>0?f+1|0:f;i=se(e,k,18,0);d=i+d|0;e=$+f|0;F[g+2456>>2]=d;F[g+2460>>2]=d>>>0>>0?e+1|0:e;e=F[g+2528>>2];i=F[g+2448>>2];f=e+i|0;k=F[g+2532>>2];d=k+F[g+2452>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);f=i+f|0;e=$+d|0;F[g+2448>>2]=f;F[g+2452>>2]=f>>>0>>0?e+1|0:e;e=F[g+2520>>2];i=F[g+2440>>2];f=e+i|0;k=F[g+2524>>2];d=k+F[g+2444>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);e=i+f|0;f=$+d|0;F[g+2440>>2]=e;F[g+2444>>2]=e>>>0>>0?f+1|0:f;f=F[g+2512>>2];i=F[g+2432>>2];d=f+i|0;k=F[g+2516>>2];e=k+F[g+2436>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2432>>2]=f;F[g+2436>>2]=f>>>0>>0?d+1|0:d;wa(n);i=g+1952|0;ja(i,n,80);ta(n,i,h);f=F[g+2576>>2];h=F[g+2496>>2];d=f+h|0;k=F[g+2580>>2];e=k+F[g+2500>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,k,18,0);f=h+d|0;d=$+e|0;F[g+2496>>2]=f;F[g+2500>>2]=f>>>0>>0?d+1|0:d;e=F[g+2568>>2];h=F[g+2488>>2];d=e+h|0;k=F[g+2572>>2];f=k+F[g+2492>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,k,18,0);d=h+d|0;e=$+f|0;F[g+2488>>2]=d;F[g+2492>>2]=d>>>0>>0?e+1|0:e;e=F[g+2560>>2];h=F[g+2480>>2];f=e+h|0;k=F[g+2564>>2];d=k+F[g+2484>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,k,18,0);f=h+f|0;e=$+d|0;F[g+2480>>2]=f;F[g+2484>>2]=f>>>0>>0?e+1|0:e;e=F[g+2552>>2];h=F[g+2472>>2];f=e+h|0;k=F[g+2556>>2];d=k+F[g+2476>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,k,18,0);e=h+f|0;f=$+d|0;F[g+2472>>2]=e;F[g+2476>>2]=e>>>0>>0?f+1|0:f;f=F[g+2544>>2];h=F[g+2464>>2];d=f+h|0;k=F[g+2548>>2];e=k+F[g+2468>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,k,18,0);f=h+d|0;d=$+e|0;F[g+2464>>2]=f;F[g+2468>>2]=f>>>0>>0?d+1|0:d;f=F[g+2536>>2];h=F[g+2456>>2];d=f+h|0;k=F[g+2540>>2];e=k+F[g+2460>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,k,18,0);f=h+d|0;d=$+e|0;F[g+2456>>2]=f;F[g+2460>>2]=f>>>0>>0?d+1|0:d;e=F[g+2528>>2];h=F[g+2448>>2];d=e+h|0;k=F[g+2532>>2];f=k+F[g+2452>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,k,18,0);d=h+d|0;e=$+f|0;F[g+2448>>2]=d;F[g+2452>>2]=d>>>0>>0?e+1|0:e;e=F[g+2520>>2];h=F[g+2440>>2];f=e+h|0;k=F[g+2524>>2];d=k+F[g+2444>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,k,18,0);f=h+f|0;e=$+d|0;F[g+2440>>2]=f;F[g+2444>>2]=f>>>0>>0?e+1|0:e;e=F[g+2512>>2];h=F[g+2432>>2];f=e+h|0;k=F[g+2516>>2];d=k+F[g+2436>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,k,18,0);e=h+f|0;f=$+d|0;F[g+2432>>2]=e;F[g+2436>>2]=e>>>0>>0?f+1|0:f;wa(n);d=g+1792|0;ja(d,n,80);ga(b,d);ta(n,b,i);f=F[g+2576>>2];h=F[g+2496>>2];d=f+h|0;i=F[g+2580>>2];e=i+F[g+2500>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2496>>2]=f;F[g+2500>>2]=f>>>0>>0?d+1|0:d;f=F[g+2568>>2];h=F[g+2488>>2];d=f+h|0;i=F[g+2572>>2];e=i+F[g+2492>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2488>>2]=f;F[g+2492>>2]=f>>>0>>0?d+1|0:d;e=F[g+2560>>2];h=F[g+2480>>2];d=e+h|0;i=F[g+2564>>2];f=i+F[g+2484>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2480>>2]=d;F[g+2484>>2]=d>>>0>>0?e+1|0:e;e=F[g+2552>>2];h=F[g+2472>>2];f=e+h|0;i=F[g+2556>>2];d=i+F[g+2476>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2472>>2]=f;F[g+2476>>2]=f>>>0>>0?e+1|0:e;e=F[g+2544>>2];h=F[g+2464>>2];f=e+h|0;i=F[g+2548>>2];d=i+F[g+2468>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2464>>2]=e;F[g+2468>>2]=e>>>0>>0?f+1|0:f;f=F[g+2536>>2];h=F[g+2456>>2];d=f+h|0;i=F[g+2540>>2];e=i+F[g+2460>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2456>>2]=f;F[g+2460>>2]=f>>>0>>0?d+1|0:d;f=F[g+2528>>2];h=F[g+2448>>2];d=f+h|0;i=F[g+2532>>2];e=i+F[g+2452>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2448>>2]=f;F[g+2452>>2]=f>>>0>>0?d+1|0:d;e=F[g+2520>>2];h=F[g+2440>>2];d=e+h|0;i=F[g+2524>>2];f=i+F[g+2444>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2440>>2]=d;F[g+2444>>2]=d>>>0>>0?e+1|0:e;e=F[g+2512>>2];h=F[g+2432>>2];f=e+h|0;i=F[g+2516>>2];d=i+F[g+2436>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2432>>2]=f;F[g+2436>>2]=f>>>0>>0?e+1|0:e;wa(n);d=g+1632|0;ja(d,n,80);ga(b,d);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ta(n,b,d);e=F[g+2576>>2];h=F[g+2496>>2];f=e+h|0;i=F[g+2580>>2];d=i+F[g+2500>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2496>>2]=e;F[g+2500>>2]=e>>>0>>0?f+1|0:f;f=F[g+2568>>2];h=F[g+2488>>2];d=f+h|0;i=F[g+2572>>2];e=i+F[g+2492>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2488>>2]=f;F[g+2492>>2]=f>>>0>>0?d+1|0:d;f=F[g+2560>>2];h=F[g+2480>>2];d=f+h|0;i=F[g+2564>>2];e=i+F[g+2484>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2480>>2]=f;F[g+2484>>2]=f>>>0>>0?d+1|0:d;e=F[g+2552>>2];h=F[g+2472>>2];d=e+h|0;i=F[g+2556>>2];f=i+F[g+2476>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2472>>2]=d;F[g+2476>>2]=d>>>0>>0?e+1|0:e;e=F[g+2544>>2];h=F[g+2464>>2];f=e+h|0;i=F[g+2548>>2];d=i+F[g+2468>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2464>>2]=f;F[g+2468>>2]=f>>>0>>0?e+1|0:e;e=F[g+2536>>2];h=F[g+2456>>2];f=e+h|0;i=F[g+2540>>2];d=i+F[g+2460>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2456>>2]=e;F[g+2460>>2]=e>>>0>>0?f+1|0:f;f=F[g+2528>>2];h=F[g+2448>>2];d=f+h|0;i=F[g+2532>>2];e=i+F[g+2452>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2448>>2]=f;F[g+2452>>2]=f>>>0>>0?d+1|0:d;f=F[g+2520>>2];h=F[g+2440>>2];d=f+h|0;i=F[g+2524>>2];e=i+F[g+2444>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2440>>2]=f;F[g+2444>>2]=f>>>0>>0?d+1|0:d;e=F[g+2512>>2];h=F[g+2432>>2];d=e+h|0;i=F[g+2516>>2];f=i+F[g+2436>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2432>>2]=d;F[g+2436>>2]=d>>>0>>0?e+1|0:e;wa(n);h=g+1472|0;ja(h,n,80);ga(b,h);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ta(n,c,h);e=F[g+2576>>2];i=F[g+2496>>2];f=e+i|0;k=F[g+2580>>2];d=k+F[g+2500>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);f=i+f|0;e=$+d|0;F[g+2496>>2]=f;F[g+2500>>2]=f>>>0>>0?e+1|0:e;e=F[g+2568>>2];i=F[g+2488>>2];f=e+i|0;k=F[g+2572>>2];d=k+F[g+2492>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);e=i+f|0;f=$+d|0;F[g+2488>>2]=e;F[g+2492>>2]=e>>>0>>0?f+1|0:f;f=F[g+2560>>2];i=F[g+2480>>2];d=f+i|0;k=F[g+2564>>2];e=k+F[g+2484>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2480>>2]=f;F[g+2484>>2]=f>>>0>>0?d+1|0:d;f=F[g+2552>>2];i=F[g+2472>>2];d=f+i|0;k=F[g+2556>>2];e=k+F[g+2476>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2472>>2]=f;F[g+2476>>2]=f>>>0>>0?d+1|0:d;e=F[g+2544>>2];i=F[g+2464>>2];d=e+i|0;k=F[g+2548>>2];f=k+F[g+2468>>2]|0;f=d>>>0>>0?f+1|0:f;i=se(e,k,18,0);d=i+d|0;e=$+f|0;F[g+2464>>2]=d;F[g+2468>>2]=d>>>0>>0?e+1|0:e;e=F[g+2536>>2];i=F[g+2456>>2];f=e+i|0;k=F[g+2540>>2];d=k+F[g+2460>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);f=i+f|0;e=$+d|0;F[g+2456>>2]=f;F[g+2460>>2]=f>>>0>>0?e+1|0:e;e=F[g+2528>>2];i=F[g+2448>>2];f=e+i|0;k=F[g+2532>>2];d=k+F[g+2452>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);e=i+f|0;f=$+d|0;F[g+2448>>2]=e;F[g+2452>>2]=e>>>0>>0?f+1|0:f;f=F[g+2520>>2];i=F[g+2440>>2];d=f+i|0;k=F[g+2524>>2];e=k+F[g+2444>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2440>>2]=f;F[g+2444>>2]=f>>>0>>0?d+1|0:d;f=F[g+2512>>2];i=F[g+2432>>2];d=f+i|0;k=F[g+2516>>2];e=k+F[g+2436>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2432>>2]=f;F[g+2436>>2]=f>>>0>>0?d+1|0:d;wa(n);d=g+1312|0;ja(d,n,80);ga(b,d);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ta(n,c,d);e=F[g+2576>>2];i=F[g+2496>>2];d=e+i|0;k=F[g+2580>>2];f=k+F[g+2500>>2]|0;f=d>>>0>>0?f+1|0:f;i=se(e,k,18,0);d=i+d|0;e=$+f|0;F[g+2496>>2]=d;F[g+2500>>2]=d>>>0>>0?e+1|0:e;e=F[g+2568>>2];i=F[g+2488>>2];f=e+i|0;k=F[g+2572>>2];d=k+F[g+2492>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);f=i+f|0;e=$+d|0;F[g+2488>>2]=f;F[g+2492>>2]=f>>>0>>0?e+1|0:e;e=F[g+2560>>2];i=F[g+2480>>2];f=e+i|0;k=F[g+2564>>2];d=k+F[g+2484>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);e=i+f|0;f=$+d|0;F[g+2480>>2]=e;F[g+2484>>2]=e>>>0>>0?f+1|0:f;f=F[g+2552>>2];i=F[g+2472>>2];d=f+i|0;k=F[g+2556>>2];e=k+F[g+2476>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2472>>2]=f;F[g+2476>>2]=f>>>0>>0?d+1|0:d;f=F[g+2544>>2];i=F[g+2464>>2];d=f+i|0;k=F[g+2548>>2];e=k+F[g+2468>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2464>>2]=f;F[g+2468>>2]=f>>>0>>0?d+1|0:d;e=F[g+2536>>2];i=F[g+2456>>2];d=e+i|0;k=F[g+2540>>2];f=k+F[g+2460>>2]|0;f=d>>>0>>0?f+1|0:f;i=se(e,k,18,0);d=i+d|0;e=$+f|0;F[g+2456>>2]=d;F[g+2460>>2]=d>>>0>>0?e+1|0:e;e=F[g+2528>>2];i=F[g+2448>>2];f=e+i|0;k=F[g+2532>>2];d=k+F[g+2452>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);f=i+f|0;e=$+d|0;F[g+2448>>2]=f;F[g+2452>>2]=f>>>0>>0?e+1|0:e;e=F[g+2520>>2];i=F[g+2440>>2];f=e+i|0;k=F[g+2524>>2];d=k+F[g+2444>>2]|0;d=f>>>0>>0?d+1|0:d;i=se(e,k,18,0);e=i+f|0;f=$+d|0;F[g+2440>>2]=e;F[g+2444>>2]=e>>>0>>0?f+1|0:f;f=F[g+2512>>2];i=F[g+2432>>2];d=f+i|0;k=F[g+2516>>2];e=k+F[g+2436>>2]|0;e=d>>>0>>0?e+1|0:e;i=se(f,k,18,0);f=i+d|0;d=$+e|0;F[g+2432>>2]=f;F[g+2436>>2]=f>>>0>>0?d+1|0:d;wa(n);ja(b,n,80);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ta(n,b,h);f=F[g+2576>>2];h=F[g+2496>>2];d=f+h|0;i=F[g+2580>>2];e=i+F[g+2500>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2496>>2]=f;F[g+2500>>2]=f>>>0>>0?d+1|0:d;e=F[g+2568>>2];h=F[g+2488>>2];d=e+h|0;i=F[g+2572>>2];f=i+F[g+2492>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2488>>2]=d;F[g+2492>>2]=d>>>0>>0?e+1|0:e;e=F[g+2560>>2];h=F[g+2480>>2];f=e+h|0;i=F[g+2564>>2];d=i+F[g+2484>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2480>>2]=f;F[g+2484>>2]=f>>>0>>0?e+1|0:e;e=F[g+2552>>2];h=F[g+2472>>2];f=e+h|0;i=F[g+2556>>2];d=i+F[g+2476>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2472>>2]=e;F[g+2476>>2]=e>>>0>>0?f+1|0:f;f=F[g+2544>>2];h=F[g+2464>>2];d=f+h|0;i=F[g+2548>>2];e=i+F[g+2468>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2464>>2]=f;F[g+2468>>2]=f>>>0>>0?d+1|0:d;f=F[g+2536>>2];h=F[g+2456>>2];d=f+h|0;i=F[g+2540>>2];e=i+F[g+2460>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2456>>2]=f;F[g+2460>>2]=f>>>0>>0?d+1|0:d;e=F[g+2528>>2];h=F[g+2448>>2];d=e+h|0;i=F[g+2532>>2];f=i+F[g+2452>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2448>>2]=d;F[g+2452>>2]=d>>>0>>0?e+1|0:e;e=F[g+2520>>2];h=F[g+2440>>2];f=e+h|0;i=F[g+2524>>2];d=i+F[g+2444>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2440>>2]=f;F[g+2444>>2]=f>>>0>>0?e+1|0:e;e=F[g+2512>>2];h=F[g+2432>>2];f=e+h|0;i=F[g+2516>>2];d=i+F[g+2436>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2432>>2]=e;F[g+2436>>2]=e>>>0>>0?f+1|0:f;wa(n);d=g+1152|0;ja(d,n,80);ga(b,d);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ta(n,c,d);f=F[g+2576>>2];h=F[g+2496>>2];d=f+h|0;i=F[g+2580>>2];e=i+F[g+2500>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2496>>2]=f;F[g+2500>>2]=f>>>0>>0?d+1|0:d;f=F[g+2568>>2];h=F[g+2488>>2];d=f+h|0;i=F[g+2572>>2];e=i+F[g+2492>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2488>>2]=f;F[g+2492>>2]=f>>>0>>0?d+1|0:d;e=F[g+2560>>2];h=F[g+2480>>2];d=e+h|0;i=F[g+2564>>2];f=i+F[g+2484>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2480>>2]=d;F[g+2484>>2]=d>>>0>>0?e+1|0:e;e=F[g+2552>>2];h=F[g+2472>>2];f=e+h|0;i=F[g+2556>>2];d=i+F[g+2476>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2472>>2]=f;F[g+2476>>2]=f>>>0>>0?e+1|0:e;e=F[g+2544>>2];h=F[g+2464>>2];f=e+h|0;i=F[g+2548>>2];d=i+F[g+2468>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2464>>2]=e;F[g+2468>>2]=e>>>0>>0?f+1|0:f;f=F[g+2536>>2];h=F[g+2456>>2];d=f+h|0;i=F[g+2540>>2];e=i+F[g+2460>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2456>>2]=f;F[g+2460>>2]=f>>>0>>0?d+1|0:d;f=F[g+2528>>2];h=F[g+2448>>2];d=f+h|0;i=F[g+2532>>2];e=i+F[g+2452>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2448>>2]=f;F[g+2452>>2]=f>>>0>>0?d+1|0:d;e=F[g+2520>>2];h=F[g+2440>>2];d=e+h|0;i=F[g+2524>>2];f=i+F[g+2444>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2440>>2]=d;F[g+2444>>2]=d>>>0>>0?e+1|0:e;e=F[g+2512>>2];h=F[g+2432>>2];f=e+h|0;i=F[g+2516>>2];d=i+F[g+2436>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2432>>2]=f;F[g+2436>>2]=f>>>0>>0?e+1|0:e;wa(n);d=g+992|0;ja(d,n,80);ga(c,d);ga(b,c);c=2;while(1){b=c>>>0<98;d=g+672|0;f=g+832|0;ga(d,f);ga(f,d);c=c+2|0;if(b){continue}break}n=g+2432|0;c=g+832|0;ta(n,c,g+992|0);f=F[g+2576>>2];e=F[g+2496>>2];b=f+e|0;h=F[g+2580>>2];d=h+F[g+2500>>2]|0;d=b>>>0>>0?d+1|0:d;e=se(f,h,18,0);b=e+b|0;f=$+d|0;F[g+2496>>2]=b;F[g+2500>>2]=b>>>0>>0?f+1|0:f;d=F[g+2568>>2];f=F[g+2488>>2];b=d+f|0;h=F[g+2572>>2];e=h+F[g+2492>>2]|0;e=b>>>0>>0?e+1|0:e;f=se(d,h,18,0);b=f+b|0;d=$+e|0;F[g+2488>>2]=b;F[g+2492>>2]=b>>>0>>0?d+1|0:d;d=F[g+2560>>2];f=F[g+2480>>2];b=d+f|0;h=F[g+2564>>2];e=h+F[g+2484>>2]|0;e=b>>>0>>0?e+1|0:e;f=se(d,h,18,0);b=f+b|0;d=$+e|0;F[g+2480>>2]=b;F[g+2484>>2]=b>>>0>>0?d+1|0:d;d=F[g+2552>>2];e=F[g+2472>>2];b=d+e|0;h=F[g+2556>>2];f=h+F[g+2476>>2]|0;f=b>>>0>>0?f+1|0:f;d=se(d,h,18,0);b=d+b|0;e=$+f|0;F[g+2472>>2]=b;F[g+2476>>2]=b>>>0>>0?e+1|0:e;f=F[g+2544>>2];e=F[g+2464>>2];b=f+e|0;h=F[g+2548>>2];d=h+F[g+2468>>2]|0;d=b>>>0>>0?d+1|0:d;f=se(f,h,18,0);b=f+b|0;e=$+d|0;F[g+2464>>2]=b;F[g+2468>>2]=b>>>0>>0?e+1|0:e;f=F[g+2536>>2];e=F[g+2456>>2];b=f+e|0;h=F[g+2540>>2];d=h+F[g+2460>>2]|0;d=b>>>0>>0?d+1|0:d;e=se(f,h,18,0);b=e+b|0;f=$+d|0;F[g+2456>>2]=b;F[g+2460>>2]=b>>>0>>0?f+1|0:f;d=F[g+2528>>2];f=F[g+2448>>2];b=d+f|0;h=F[g+2532>>2];e=h+F[g+2452>>2]|0;e=b>>>0>>0?e+1|0:e;f=se(d,h,18,0);b=f+b|0;d=$+e|0;F[g+2448>>2]=b;F[g+2452>>2]=b>>>0>>0?d+1|0:d;d=F[g+2520>>2];f=F[g+2440>>2];b=d+f|0;h=F[g+2524>>2];e=h+F[g+2444>>2]|0;e=b>>>0>>0?e+1|0:e;f=se(d,h,18,0);b=f+b|0;d=$+e|0;F[g+2440>>2]=b;F[g+2444>>2]=b>>>0>>0?d+1|0:d;d=F[g+2512>>2];e=F[g+2432>>2];b=d+e|0;h=F[g+2516>>2];f=h+F[g+2436>>2]|0;f=b>>>0>>0?f+1|0:f;d=se(d,h,18,0);b=d+b|0;e=$+f|0;F[g+2432>>2]=b;F[g+2436>>2]=b>>>0>>0?e+1|0:e;wa(n);b=g+672|0;ja(b,n,80);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ta(n,b,g+1152|0);e=F[g+2576>>2];h=F[g+2496>>2];f=e+h|0;i=F[g+2580>>2];d=i+F[g+2500>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2496>>2]=f;F[g+2500>>2]=f>>>0>>0?e+1|0:e;e=F[g+2568>>2];h=F[g+2488>>2];f=e+h|0;i=F[g+2572>>2];d=i+F[g+2492>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2488>>2]=e;F[g+2492>>2]=e>>>0>>0?f+1|0:f;f=F[g+2560>>2];h=F[g+2480>>2];d=f+h|0;i=F[g+2564>>2];e=i+F[g+2484>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2480>>2]=f;F[g+2484>>2]=f>>>0>>0?d+1|0:d;f=F[g+2552>>2];h=F[g+2472>>2];d=f+h|0;i=F[g+2556>>2];e=i+F[g+2476>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2472>>2]=f;F[g+2476>>2]=f>>>0>>0?d+1|0:d;e=F[g+2544>>2];h=F[g+2464>>2];d=e+h|0;i=F[g+2548>>2];f=i+F[g+2468>>2]|0;f=d>>>0>>0?f+1|0:f;h=se(e,i,18,0);d=h+d|0;e=$+f|0;F[g+2464>>2]=d;F[g+2468>>2]=d>>>0>>0?e+1|0:e;e=F[g+2536>>2];h=F[g+2456>>2];f=e+h|0;i=F[g+2540>>2];d=i+F[g+2460>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);f=h+f|0;e=$+d|0;F[g+2456>>2]=f;F[g+2460>>2]=f>>>0>>0?e+1|0:e;e=F[g+2528>>2];h=F[g+2448>>2];f=e+h|0;i=F[g+2532>>2];d=i+F[g+2452>>2]|0;d=f>>>0>>0?d+1|0:d;h=se(e,i,18,0);e=h+f|0;f=$+d|0;F[g+2448>>2]=e;F[g+2452>>2]=e>>>0>>0?f+1|0:f;f=F[g+2520>>2];h=F[g+2440>>2];d=f+h|0;i=F[g+2524>>2];e=i+F[g+2444>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2440>>2]=f;F[g+2444>>2]=f>>>0>>0?d+1|0:d;f=F[g+2512>>2];h=F[g+2432>>2];d=f+h|0;i=F[g+2516>>2];e=i+F[g+2436>>2]|0;e=d>>>0>>0?e+1|0:e;h=se(f,i,18,0);f=h+d|0;d=$+e|0;F[g+2432>>2]=f;F[g+2436>>2]=f>>>0>>0?d+1|0:d;wa(n);ja(c,n,80);ga(b,c);ga(c,b);ga(b,c);ga(c,b);ga(b,c);ta(n,b,g+1792|0);c=F[g+2576>>2];d=F[g+2496>>2];b=c+d|0;e=F[g+2580>>2];f=e+F[g+2500>>2]|0;f=b>>>0>>0?f+1|0:f;c=se(c,e,18,0);b=c+b|0;e=$+f|0;F[g+2496>>2]=b;F[g+2500>>2]=b>>>0>>0?e+1|0:e;c=F[g+2568>>2];f=F[g+2488>>2];b=c+f|0;e=F[g+2572>>2];d=e+F[g+2492>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;e=$+d|0;F[g+2488>>2]=b;F[g+2492>>2]=b>>>0>>0?e+1|0:e;c=F[g+2560>>2];f=F[g+2480>>2];b=c+f|0;e=F[g+2564>>2];d=e+F[g+2484>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;f=$+d|0;F[g+2480>>2]=b;F[g+2484>>2]=b>>>0>>0?f+1|0:f;c=F[g+2552>>2];d=F[g+2472>>2];b=c+d|0;f=F[g+2556>>2];e=f+F[g+2476>>2]|0;e=b>>>0>>0?e+1|0:e;c=se(c,f,18,0);b=c+b|0;d=$+e|0;F[g+2472>>2]=b;F[g+2476>>2]=b>>>0>>0?d+1|0:d;c=F[g+2544>>2];d=F[g+2464>>2];b=c+d|0;f=F[g+2548>>2];e=f+F[g+2468>>2]|0;e=b>>>0>>0?e+1|0:e;c=se(c,f,18,0);b=c+b|0;d=$+e|0;F[g+2464>>2]=b;F[g+2468>>2]=b>>>0>>0?d+1|0:d;c=F[g+2536>>2];d=F[g+2456>>2];b=c+d|0;e=F[g+2540>>2];f=e+F[g+2460>>2]|0;f=b>>>0>>0?f+1|0:f;c=se(c,e,18,0);b=c+b|0;e=$+f|0;F[g+2456>>2]=b;F[g+2460>>2]=b>>>0>>0?e+1|0:e;c=F[g+2528>>2];f=F[g+2448>>2];b=c+f|0;e=F[g+2532>>2];d=e+F[g+2452>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;e=$+d|0;F[g+2448>>2]=b;F[g+2452>>2]=b>>>0>>0?e+1|0:e;c=F[g+2520>>2];f=F[g+2440>>2];b=c+f|0;e=F[g+2524>>2];d=e+F[g+2444>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;f=$+d|0;F[g+2440>>2]=b;F[g+2444>>2]=b>>>0>>0?f+1|0:f;c=F[g+2512>>2];d=F[g+2432>>2];b=c+d|0;f=F[g+2516>>2];e=f+F[g+2436>>2]|0;e=b>>>0>>0?e+1|0:e;c=se(c,f,18,0);b=c+b|0;d=$+e|0;F[g+2432>>2]=b;F[g+2436>>2]=b>>>0>>0?d+1|0:d;wa(n);b=g+512|0;ja(b,n,80);ta(n,g+32|0,b);c=F[g+2576>>2];d=F[g+2496>>2];b=c+d|0;f=F[g+2580>>2];e=f+F[g+2500>>2]|0;e=b>>>0>>0?e+1|0:e;c=se(c,f,18,0);b=c+b|0;d=$+e|0;F[g+2496>>2]=b;F[g+2500>>2]=b>>>0>>0?d+1|0:d;c=F[g+2568>>2];d=F[g+2488>>2];b=c+d|0;e=F[g+2572>>2];f=e+F[g+2492>>2]|0;f=b>>>0>>0?f+1|0:f;c=se(c,e,18,0);b=c+b|0;e=$+f|0;F[g+2488>>2]=b;F[g+2492>>2]=b>>>0>>0?e+1|0:e;c=F[g+2560>>2];f=F[g+2480>>2];b=c+f|0;e=F[g+2564>>2];d=e+F[g+2484>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;e=$+d|0;F[g+2480>>2]=b;F[g+2484>>2]=b>>>0>>0?e+1|0:e;c=F[g+2552>>2];f=F[g+2472>>2];b=c+f|0;e=F[g+2556>>2];d=e+F[g+2476>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;f=$+d|0;F[g+2472>>2]=b;F[g+2476>>2]=b>>>0>>0?f+1|0:f;c=F[g+2544>>2];d=F[g+2464>>2];b=c+d|0;f=F[g+2548>>2];e=f+F[g+2468>>2]|0;e=b>>>0>>0?e+1|0:e;c=se(c,f,18,0);b=c+b|0;d=$+e|0;F[g+2464>>2]=b;F[g+2468>>2]=b>>>0>>0?d+1|0:d;c=F[g+2536>>2];d=F[g+2456>>2];b=c+d|0;f=F[g+2540>>2];e=f+F[g+2460>>2]|0;e=b>>>0>>0?e+1|0:e;c=se(c,f,18,0);b=c+b|0;d=$+e|0;F[g+2456>>2]=b;F[g+2460>>2]=b>>>0>>0?d+1|0:d;c=F[g+2528>>2];d=F[g+2448>>2];b=c+d|0;e=F[g+2532>>2];f=e+F[g+2452>>2]|0;f=b>>>0>>0?f+1|0:f;c=se(c,e,18,0);b=c+b|0;e=$+f|0;F[g+2448>>2]=b;F[g+2452>>2]=b>>>0>>0?e+1|0:e;c=F[g+2520>>2];f=F[g+2440>>2];b=c+f|0;e=F[g+2524>>2];d=e+F[g+2444>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;e=$+d|0;F[g+2440>>2]=b;F[g+2444>>2]=b>>>0>>0?e+1|0:e;c=F[g+2512>>2];f=F[g+2432>>2];b=c+f|0;e=F[g+2516>>2];d=e+F[g+2436>>2]|0;d=b>>>0>>0?d+1|0:d;c=se(c,e,18,0);b=c+b|0;f=$+d|0;F[g+2432>>2]=b;F[g+2436>>2]=b>>>0>>0?f+1|0:f;wa(n);ja(g+2272|0,n,80);b=F[g+2272>>2];s=b>>31&b;c=F[g+2280>>2]+(s>>26)|0;w=c>>31&c;d=F[g+2288>>2]+(w>>25)|0;C=d>>31&d;f=F[g+2296>>2]+(C>>26)|0;U=f>>31&f;e=F[g+2304>>2]+(U>>25)|0;m=e>>31&e;n=F[g+2312>>2]+(m>>26)|0;j=n>>31&n;h=F[g+2320>>2]+(j>>25)|0;p=h>>31&h;i=F[g+2328>>2]+(p>>26)|0;o=i>>31&i;k=F[g+2336>>2]+(o>>25)|0;r=k>>31&k;l=F[g+2344>>2]+(r>>26)|0;q=l>>31&l;b=L(q>>25,19)+(b-(s&-67108864)|0)|0;z=b>>31&b;c=(z>>26)+(c-(w&-33554432)|0)|0;s=c>>31&c;u=c-(s&-33554432)|0;y=b-(z&-67108864)|0;q=l-(q&-33554432)|0;b=(d-(C&-67108864)|0)+(s>>25)|0;l=b>>31&b;c=(f-(U&-33554432)|0)+(l>>26)|0;s=c>>31&c;d=(e-(m&-67108864)|0)+(s>>25)|0;w=d>>31&d;f=(n-(j&-33554432)|0)+(w>>26)|0;C=f>>31&f;e=(h-(p&-67108864)|0)+(C>>25)|0;U=e>>31&e;n=(i-(o&-33554432)|0)+(U>>26)|0;m=n>>31&n;h=(k-(r&-67108864)|0)+(m>>25)|0;j=h>>31&h;i=q+(j>>26)|0;p=i>>31&i;k=y+L(p>>25,19)|0;o=k>>31&k;k=k-(o&-67108864)|0;o=(u+(o>>26)|0)+(k>>26)|0;b=(o>>25)+(b-(l&-67108864)|0)|0;l=(b>>26)+(c-(s&-33554432)|0)|0;s=(l>>25)+(d-(w&-67108864)|0)|0;w=(s>>26)+(f-(C&-33554432)|0)|0;C=(w>>25)+(e-(U&-67108864)|0)|0;n=(C>>26)+(n-(m&-33554432)|0)|0;h=(n>>25)+(h-(j&-67108864)|0)|0;i=(h>>26)+(i-(p&-33554432)|0)|0;U=L(i>>25,19)+(k&67108863)|0;c=(U>>26)+(o&33554431)|0;d=(c>>25)+(b&67108863)|0;f=(d>>26)+(l&33554431)|0;e=(f>>25)+(s&67108863)|0;b=(e>>26)+(w&33554431)|0;j=b&33554431;m=i&33554431;p=h&67108863;q=n&33554431;n=(C&67108863)+(b>>25)|0;h=q+(n>>26)|0;i=p+(h>>25)|0;k=m+(i>>26)|0;l=k<<16&(k|-33554432);l=l<<8&l;l=l<<4&l;l=l<<2&l;m=l<<1&l;l=(i|-67108864)&i<<16;l=l<<8&l;l=l<<4&l;l=l<<2&l;m=(m&(l<<1&l))>>31;w=L(k>>25,19)+(U&67108863)|0;l=(c|-33554432)&c<<16;l=l<<8&l;l=l<<4&l;l=l<<2&l;p=(w-67108845>>31^-1)&(l<<1&l)>>31;l=(d|-67108864)&d<<16;l=l<<8&l;l=l<<4&l;l=l<<2&l;p=p&(l<<1&l)>>31;l=(f|-33554432)&f<<16;l=l<<8&l;l=l<<4&l;l=l<<2&l;p=p&(l<<1&l)>>31;l=(e|-67108864)&e<<16;l=l<<8&l;l=l<<4&l;l=l<<2&l;b=(b|-33554432)&b<<16;b=b<<8&b;b=b<<4&b;b=b<<2&b;p=p&(l<<1&l)>>31&(b<<1&b)>>31;b=(n|-67108864)&n<<16;b=b<<8&b;b=b<<4&b;b=b<<2&b;p=p&(b<<1&b)>>31;b=(h|-33554432)&h<<16;b=b<<8&b;b=b<<4&b;b=b<<2&b;l=m&(p&(b<<1&b)>>31);b=l&33554431;s=j-b|0;D[a+16|0]=s;e=e-l|0;D[a+15|0]=e>>>18;D[a+14|0]=e>>>10;D[a+13|0]=e>>>2;w=w-(l&67108845)|0;D[a|0]=w;k=(k&33554431)-b|0;D[a+31|0]=k>>>18;D[a+30|0]=k>>>10;D[a+29|0]=k>>>2;l=l&67108863;i=(i&67108863)-l|0;D[a+27|0]=i>>>12;D[a+26|0]=i>>>4;h=(h&33554431)-b|0;D[a+24|0]=h>>>13;D[a+23|0]=h>>>5;n=(n&67108863)-l|0;D[a+21|0]=n>>>15;D[a+20|0]=n>>>7;D[a+18|0]=s>>>16;D[a+17|0]=s>>>8;f=(f&33554431)-b|0;D[a+11|0]=f>>>11;D[a+10|0]=f>>>3;d=(d&67108863)-l|0;D[a+8|0]=d>>>13;D[a+7|0]=d>>>5;b=(c&33554431)-b|0;D[a+5|0]=b>>>14;D[a+4|0]=b>>>6;D[a+2|0]=w>>>16;D[a+1|0]=w>>>8;D[a+28|0]=k<<6|i>>>20;D[a+25|0]=i<<4|h>>>21;D[a+22|0]=h<<3|n>>>23;D[a+19|0]=n<<1|s>>>24;D[a+12|0]=e<<6|f>>>19;D[a+9|0]=f<<5|d>>>21;D[a+6|0]=d<<3|b>>>22;D[a+3|0]=b<<2|w>>>24;_=g+2592|0}function bb(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,E=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,eb=0,fb=0,gb=0,hb=0;h=_-624|0;_=h;F[h+352>>2]=327033209;F[h+356>>2]=1541459225;F[h+344>>2]=-79577749;F[h+348>>2]=528734635;F[h+336>>2]=725511199;F[h+340>>2]=-1694144372;F[h+328>>2]=-1377402159;F[h+332>>2]=1359893119;F[h+320>>2]=1595750129;F[h+324>>2]=-1521486534;F[h+312>>2]=-23791573;F[h+316>>2]=1013904242;F[h+304>>2]=-2067093701;F[h+308>>2]=-1150833019;F[h+360>>2]=0;F[h+296>>2]=-205731576;F[h+300>>2]=1779033703;F[h+288>>2]=0;F[h+292>>2]=0;q=a+32|0;D[h+364|0]=G[q+32|0];D[h+365|0]=G[q+33|0];D[h+366|0]=G[q+34|0];o=h+364|0;D[(o+F[h+360>>2]|0)+3|0]=G[q+35|0];D[(F[h+360>>2]+o|0)+4|0]=G[q+36|0];D[(F[h+360>>2]+o|0)+5|0]=G[q+37|0];D[(F[h+360>>2]+o|0)+6|0]=G[q+38|0];D[(F[h+360>>2]+o|0)+7|0]=G[q+39|0];D[(F[h+360>>2]+o|0)+8|0]=G[q+40|0];D[(F[h+360>>2]+o|0)+9|0]=G[q+41|0];D[(F[h+360>>2]+o|0)+10|0]=G[q+42|0];D[(F[h+360>>2]+o|0)+11|0]=G[q+43|0];D[(F[h+360>>2]+o|0)+12|0]=G[q+44|0];D[(F[h+360>>2]+o|0)+13|0]=G[q+45|0];D[(F[h+360>>2]+o|0)+14|0]=G[q+46|0];D[(F[h+360>>2]+o|0)+15|0]=G[q+47|0];D[(F[h+360>>2]+o|0)+16|0]=G[q+48|0];D[(F[h+360>>2]+o|0)+17|0]=G[q+49|0];D[(F[h+360>>2]+o|0)+18|0]=G[q+50|0];D[(F[h+360>>2]+o|0)+19|0]=G[q+51|0];D[(F[h+360>>2]+o|0)+20|0]=G[q+52|0];D[(F[h+360>>2]+o|0)+21|0]=G[q+53|0];D[(F[h+360>>2]+o|0)+22|0]=G[q+54|0];D[(F[h+360>>2]+o|0)+23|0]=G[q+55|0];D[(F[h+360>>2]+o|0)+24|0]=G[q+56|0];D[(F[h+360>>2]+o|0)+25|0]=G[q+57|0];D[(F[h+360>>2]+o|0)+26|0]=G[q+58|0];D[(F[h+360>>2]+o|0)+27|0]=G[q+59|0];D[(F[h+360>>2]+o|0)+28|0]=G[q+60|0];D[(F[h+360>>2]+o|0)+29|0]=G[q+61|0];D[(F[h+360>>2]+o|0)+30|0]=G[q+62|0];D[(F[h+360>>2]+o|0)+31|0]=G[q+63|0];e=F[h+360>>2]+32|0;F[h+360>>2]=e;if((e|0)==128){ua(h+288|0,o);F[h+360>>2]=0;e=F[h+292>>2];f=F[h+288>>2]+1024|0;e=f>>>0<1024?e+1|0:e;F[h+288>>2]=f;F[h+292>>2]=e}a:{if(!b|!c){break a}i=F[h+360>>2];if(i>>>0>128){break a}g=c;k=b;while(1){b:{if(!(g>>>0<128|i)){ua(h+288|0,k);e=F[h+292>>2];f=F[h+288>>2]+1024|0;e=f>>>0<1024?e+1|0:e;F[h+288>>2]=f;F[h+292>>2]=e;g=g-128|0;k=k+128|0;break b}e=128-i|0;r=e>>>0>g>>>0?g:e;c:{if(!r){break c}l=r&3;n=0;d:{if(r-1>>>0<3){p=0;break d}f=r&-4;p=0;m=0;while(1){e=i+p|0;i=h+364|0;D[e+i|0]=G[k+p|0];e=p|1;D[i+(e+F[h+360>>2]|0)|0]=G[e+k|0];e=p|2;D[i+(e+F[h+360>>2]|0)|0]=G[e+k|0];e=p|3;D[i+(e+F[h+360>>2]|0)|0]=G[e+k|0];p=p+4|0;i=F[h+360>>2];m=m+4|0;if((f|0)!=(m|0)){continue}break}}if(!l){break c}while(1){D[((i+p|0)+h|0)+364|0]=G[k+p|0];p=p+1|0;i=F[h+360>>2];n=n+1|0;if((l|0)!=(n|0)){continue}break}}g=g-r|0;k=k+r|0;e=i+r|0;F[h+360>>2]=e;if((e|0)!=128){break b}ua(h+288|0,o);F[h+360>>2]=0;f=F[h+292>>2];e=F[h+288>>2]+1024|0;f=e>>>0<1024?f+1|0:f;F[h+288>>2]=e;F[h+292>>2]=f}if(!g){break a}i=F[h+360>>2];continue}}e=h+160|0;db(h+288|0,e);mb(e);Nb(h,e);g=h+224|0;nb(g,h+80|0);f=h+544|0;ha(f,h,g);e=h+496|0;ha(e,h+40|0,g);Ga(d,e);Ga(h+592|0,f);D[d+31|0]=G[d+31|0]^G[h+592|0]<<7;F[h+352>>2]=327033209;F[h+356>>2]=1541459225;F[h+344>>2]=-79577749;F[h+348>>2]=528734635;F[h+336>>2]=725511199;F[h+340>>2]=-1694144372;F[h+328>>2]=-1377402159;F[h+332>>2]=1359893119;F[h+320>>2]=1595750129;F[h+324>>2]=-1521486534;F[h+312>>2]=-23791573;F[h+316>>2]=1013904242;F[h+304>>2]=-2067093701;F[h+308>>2]=-1150833019;F[h+296>>2]=-205731576;F[h+300>>2]=1779033703;F[h+288>>2]=0;F[h+292>>2]=0;F[h+360>>2]=0;D[h+364|0]=G[d|0];D[h+365|0]=G[d+1|0];D[h+366|0]=G[d+2|0];D[h+367|0]=G[d+3|0];e=h+364|0;D[(e+F[h+360>>2]|0)+4|0]=G[d+4|0];D[(e+F[h+360>>2]|0)+5|0]=G[d+5|0];D[(e+F[h+360>>2]|0)+6|0]=G[d+6|0];D[(e+F[h+360>>2]|0)+7|0]=G[d+7|0];D[(e+F[h+360>>2]|0)+8|0]=G[d+8|0];D[(e+F[h+360>>2]|0)+9|0]=G[d+9|0];D[(e+F[h+360>>2]|0)+10|0]=G[d+10|0];D[(e+F[h+360>>2]|0)+11|0]=G[d+11|0];D[(e+F[h+360>>2]|0)+12|0]=G[d+12|0];D[(e+F[h+360>>2]|0)+13|0]=G[d+13|0];D[(e+F[h+360>>2]|0)+14|0]=G[d+14|0];D[(e+F[h+360>>2]|0)+15|0]=G[d+15|0];D[(e+F[h+360>>2]|0)+16|0]=G[d+16|0];D[(e+F[h+360>>2]|0)+17|0]=G[d+17|0];D[(e+F[h+360>>2]|0)+18|0]=G[d+18|0];D[(e+F[h+360>>2]|0)+19|0]=G[d+19|0];D[(e+F[h+360>>2]|0)+20|0]=G[d+20|0];D[(e+F[h+360>>2]|0)+21|0]=G[d+21|0];D[(e+F[h+360>>2]|0)+22|0]=G[d+22|0];D[(e+F[h+360>>2]|0)+23|0]=G[d+23|0];D[(e+F[h+360>>2]|0)+24|0]=G[d+24|0];D[(e+F[h+360>>2]|0)+25|0]=G[d+25|0];D[(e+F[h+360>>2]|0)+26|0]=G[d+26|0];D[(e+F[h+360>>2]|0)+27|0]=G[d+27|0];D[(e+F[h+360>>2]|0)+28|0]=G[d+28|0];D[(e+F[h+360>>2]|0)+29|0]=G[d+29|0];D[(e+F[h+360>>2]|0)+30|0]=G[d+30|0];D[(e+F[h+360>>2]|0)+31|0]=G[d+31|0];g=32;e=F[h+360>>2]+32|0;F[h+360>>2]=e;if((e|0)==128){ua(h+288|0,o);F[h+360>>2]=0;e=F[h+292>>2];f=F[h+288>>2]+1024|0;e=f>>>0<1024?e+1|0:e;F[h+288>>2]=f;F[h+292>>2]=e}e:{if(!a){break e}k=F[h+360>>2];if(k>>>0>128){break e}while(1){f:{if(!(g>>>0<128|k)){ua(h+288|0,a);e=F[h+292>>2];f=F[h+288>>2]+1024|0;e=f>>>0<1024?e+1|0:e;F[h+288>>2]=f;F[h+292>>2]=e;g=g-128|0;a=a+128|0;break f}e=128-k|0;i=e>>>0>g>>>0?g:e;g:{if(!i){break g}m=i&3;l=0;h:{if(i-1>>>0<3){p=0;break h}f=i&-4;p=0;n=0;while(1){e=k+p|0;k=h+364|0;D[e+k|0]=G[a+p|0];e=p|1;D[k+(e+F[h+360>>2]|0)|0]=G[a+e|0];e=p|2;D[k+(e+F[h+360>>2]|0)|0]=G[a+e|0];e=p|3;D[k+(e+F[h+360>>2]|0)|0]=G[a+e|0];p=p+4|0;k=F[h+360>>2];n=n+4|0;if((f|0)!=(n|0)){continue}break}}if(!m){break g}while(1){D[((k+p|0)+h|0)+364|0]=G[a+p|0];p=p+1|0;k=F[h+360>>2];l=l+1|0;if((m|0)!=(l|0)){continue}break}}g=g-i|0;a=a+i|0;e=i+k|0;F[h+360>>2]=e;if((e|0)!=128){break f}ua(h+288|0,o);F[h+360>>2]=0;f=F[h+292>>2];e=F[h+288>>2]+1024|0;f=e>>>0<1024?f+1|0:f;F[h+288>>2]=e;F[h+292>>2]=f}if(!g){break e}k=F[h+360>>2];continue}}i:{if(!b|!c){break i}a=F[h+360>>2];if(a>>>0>128){break i}while(1){j:{if(!(c>>>0<128|a)){ua(h+288|0,b);e=F[h+292>>2];a=F[h+288>>2]+1024|0;e=a>>>0<1024?e+1|0:e;F[h+288>>2]=a;F[h+292>>2]=e;c=c-128|0;b=b+128|0;break j}e=128-a|0;k=c>>>0>>0?c:e;k:{if(!k){break k}f=k&3;i=0;l:{if(k-1>>>0<3){p=0;break l}e=k&-4;p=0;l=0;while(1){g=h+364|0;D[g+(a+p|0)|0]=G[b+p|0];a=p|1;D[g+(a+F[h+360>>2]|0)|0]=G[a+b|0];a=p|2;D[g+(a+F[h+360>>2]|0)|0]=G[a+b|0];a=p|3;D[g+(a+F[h+360>>2]|0)|0]=G[a+b|0];p=p+4|0;a=F[h+360>>2];l=l+4|0;if((e|0)!=(l|0)){continue}break}}if(!f){break k}while(1){D[((a+p|0)+h|0)+364|0]=G[b+p|0];p=p+1|0;a=F[h+360>>2];i=i+1|0;if((f|0)!=(i|0)){continue}break}}c=c-k|0;b=b+k|0;a=a+k|0;F[h+360>>2]=a;if((a|0)!=128){break j}ua(h+288|0,o);F[h+360>>2]=0;e=F[h+292>>2];a=F[h+288>>2]+1024|0;e=a>>>0<1024?e+1|0:e;F[h+288>>2]=a;F[h+292>>2]=e}if(!c){break i}a=F[h+360>>2];continue}}t=h+224|0;db(h+288|0,t);mb(t);b=G[q+24|0];a=b>>>24|0;f=G[q+23|0];c=f|b<<8;b=a;e=c;c=G[q+25|0];a=c>>>16|0;g=e|c<<16;e=a|b;r=G[q+26|0];c=r;a=c>>>8|0;c=c<<24;e=a|e;a=c|g;L=((e&31)<<27|a>>>5)&2097151;c=G[t+27|0];a=c>>>24|0;g=G[t+26|0];c=g|c<<8;i=G[t+28|0];b=i;e=b>>>16|0;b=b<<16;e=a|e;a=b|c;N=((e&3)<<30|a>>>2)&2097151;l=se(L,0,N,0);m=$;c=0;x=c;O=f<<16&2031616|(G[q+21|0]|G[q+22|0]<<8);k=O;b=G[t+29|0];a=b>>>24|0;e=i|b<<8;b=a;c=e;e=G[t+30|0];a=e>>>16|0;f=c|e<<16;e=a|b;b=G[t+31|0];a=b>>>8|0;b=b<<24;c=a|e;a=b|f;P=(c&127)<<25|a>>>7;Q=c>>>7|0;a=se(k,x,P,Q);b=a+l|0;f=$+m|0;n=b;b=a>>>0>b>>>0?f+1|0:f;a=G[q+27|0];f=a>>>24|0;i=G[q+28|0];c=i;e=c>>>16|0;c=r|a<<8|c<<16;e=e|f;R=((e&3)<<30|c>>>2)&2097151;l=R;e=0;a=G[t+24|0];f=a>>>24|0;k=G[t+23|0];m=k|a<<8;c=G[t+25|0];a=c>>>16|0;m=m|c<<16;c=a|f|g>>>8;S=((c&31)<<27|(g<<24|m)>>>5)&2097151;a=se(l,e,S,0);c=a+n|0;e=$+b|0;m=c;g=a>>>0>c>>>0?e+1|0:e;a=G[q+29|0];e=a>>>24|0;b=i|a<<8;a=e;c=b;b=G[q+30|0];e=b>>>16|0;c=c|b<<16;b=a|e;a=G[q+31|0];e=a>>>8|0;a=a<<24|c;b=b|e;f=b>>>7|0;c=(b&127)<<25|a>>>7;b=f;T=k<<16&2031616|(G[t+21|0]|G[t+22|0]<<8);e=se(c,f,T,0);f=e+m|0;a=$+g|0;l=f;m=e>>>0>f>>>0?a+1|0:a;f=se(O,x,N,x);k=$;a=G[q+19|0];e=a>>>24|0;p=G[q+18|0];g=p|a<<8;a=e;n=f;f=G[q+20|0];e=f>>>16|0;f=f<<16;i=a|e;e=f|g;U=(i&7)<<29|e>>>3;H=i>>>3|0;e=se(U,H,P,Q);f=n+e|0;a=$+k|0;a=e>>>0>f>>>0?a+1|0:a;e=se(L,x,S,j);g=e+f|0;f=$+a|0;f=e>>>0>g>>>0?f+1|0:f;a=se(R,j,T,j);g=a+g|0;e=$+f|0;f=g;g=a>>>0>f>>>0?e+1|0:e;e=G[t+19|0];a=e>>>24|0;o=G[t+18|0];k=o|e<<8;i=f;e=G[t+20|0];f=e>>>16|0;e=e<<16;f=a|f;a=e|k;V=(f&7)<<29|a>>>3;W=f>>>3|0;a=se(c,b,V,W);f=i+a|0;e=$+g|0;k=f;e=a>>>0>f>>>0?e+1|0:e;r=e;n=e-((f>>>0<4293918720)-1|0)|0;e=n>>21;u=f- -1048576|0;a=(n&2097151)<<11|u>>>21;g=a+l|0;f=e+m|0;f=a>>>0>g>>>0?f+1|0:f;i=f;l=f-((g>>>0<4293918720)-1|0)|0;e=l>>21;s=g- -1048576|0;z=(l&2097151)<<11|s>>>21;m=e;a=se(N,x,R,j);e=$;f=a;a=se(L,x,P,Q);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(S,j,c,b);v=a+f|0;a=$+e|0;a=f>>>0>v>>>0?a+1|0:a;f=z;e=v;w=e- -1048576|0;v=w&-2097152;z=e-v|0;y=f+z|0;f=a-((e>>>0<4293918720)-1|0)|0;e=(a-((f&2147483647)+(e>>>0>>0)|0)|0)+m|0;Da=y;e=y>>>0>>0?e+1|0:e;Ea=e;y=se(y,e,470296,0);v=$;e=se(N,x,c,b);a=$;m=e;e=se(P,Q,R,j);m=m+e|0;a=$+a|0;a=e>>>0>m>>>0?a+1|0:a;e=m;m=(f&2097151)<<11|w>>>21;z=e+m|0;f=(f>>>21|0)+a|0;e=z;Fa=e- -1048576|0;f=m>>>0>e>>>0?f+1|0:f;z=f-((e>>>0<4293918720)-1|0)|0;I=z;a=s&-2097152;m=i-((a>>>0>g>>>0)+l|0)|0;ya=g-a|0;Ha=m;a=f;f=Fa&-2097152;a=a-((z&2147483647)+(f>>>0>e>>>0)|0)|0;za=e-f|0;Ia=a;e=se(za,a,666643,0);f=e+y|0;a=$+v|0;a=e>>>0>f>>>0?a+1|0:a;e=f;f=se(ya,m,654183,0);g=e+f|0;e=$+a|0;y=g;i=f>>>0>g>>>0?e+1|0:e;a=u&-2097152;u=k-a|0;s=r-((a>>>0>k>>>0)+n|0)|0;l=se(N,x,U,H);k=$;a=G[q+16|0];e=a>>>24|0;m=G[q+15|0];g=m|a<<8;f=G[q+17|0];a=f>>>16|0;g=g|f<<16;e=a|e|p>>>8;X=((e&63)<<26|(p<<24|g)>>>6)&2097151;e=se(X,0,P,Q);f=e+l|0;a=$+k|0;a=e>>>0>f>>>0?a+1|0:a;e=se(O,x,S,j);g=e+f|0;f=$+a|0;f=e>>>0>g>>>0?f+1|0:f;e=se(L,x,T,j);g=e+g|0;a=$+f|0;a=e>>>0>g>>>0?a+1|0:a;f=se(R,j,V,W);g=f+g|0;e=$+a|0;n=g;g=f>>>0>g>>>0?e+1|0:e;a=G[t+16|0];f=a>>>24|0;l=G[t+15|0];k=l|a<<8;e=G[t+17|0];a=e>>>16|0;k=k|e<<16;e=a|f|o>>>8;Y=((e&63)<<26|(o<<24|k)>>>6)&2097151;a=se(c,b,Y,0);f=a+n|0;e=$+g|0;o=f;k=a>>>0>f>>>0?e+1|0:e;a=se(N,x,X,j);r=$;n=a;e=G[q+14|0];f=e>>>24|0;g=G[q+13|0];a=g|e<<8|m<<16;e=m>>>16|f;Z=((e&1)<<31|a>>>1)&2097151;e=se(Z,0,P,Q);f=n+e|0;a=$+r|0;a=e>>>0>f>>>0?a+1|0:a;e=se(S,j,U,H);f=e+f|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=se(O,x,T,j);m=e+f|0;f=$+a|0;f=e>>>0>m>>>0?f+1|0:f;a=se(L,x,V,W);m=a+m|0;e=$+f|0;e=a>>>0>m>>>0?e+1|0:e;a=se(R,j,Y,j);f=a+m|0;e=$+e|0;r=f;a=a>>>0>f>>>0?e+1|0:e;e=G[t+14|0];f=e>>>24|0;m=G[t+13|0];n=m|e<<8;e=l>>>16|0;l=l<<16;f=e|f;e=l|n;aa=((f&1)<<31|e>>>1)&2097151;e=se(c,b,aa,0);f=e+r|0;a=$+a|0;r=f;a=e>>>0>f>>>0?a+1|0:a;l=a;B=a-((f>>>0<4293918720)-1|0)|0;C=f- -1048576|0;a=C;a=(B&2097151)<<11|a>>>21;n=a+o|0;f=(B>>21)+k|0;f=a>>>0>n>>>0?f+1|0:f;v=f;z=f-((n>>>0<4293918720)-1|0)|0;e=z>>21;A=n- -1048576|0;f=(z&2097151)<<11|A>>>21;k=f+u|0;a=e+s|0;Ja=k;a=f>>>0>k>>>0?a+1|0:a;Ka=a;e=se(k,a,-997805,-1);f=e+y|0;a=$+i|0;w=f;o=e>>>0>f>>>0?a+1|0:a;a=G[q+3|0];e=a>>>24|0;f=G[q+2|0];i=f|a<<8;k=G[q+4|0];a=k>>>16|0;p=i|k<<16;i=a|e;k=G[q+5|0];a=k;e=a>>>8|0;a=a<<24|p;e=e|i;ba=((e&31)<<27|a>>>5)&2097151;a=se(ba,0,T,j);e=$;i=a;ca=f<<16&2031616|(G[q|0]|G[q+1|0]<<8);a=se(ca,0,S,j);i=i+a|0;f=$+e|0;f=a>>>0>i>>>0?f+1|0:f;a=i;e=f;i=G[q+6|0];f=i>>>24|0;p=k|i<<8;s=a;i=G[q+7|0];k=i;a=k>>>16|0;k=k<<16;f=a|f;a=k|p;da=((f&3)<<30|a>>>2)&2097151;a=se(da,0,V,W);f=s+a|0;e=$+e|0;k=f;f=a>>>0>f>>>0?e+1|0:e;a=G[q+8|0];e=a>>>24|0;s=i|a<<8;i=G[q+9|0];a=i>>>16|0;p=s|i<<16;i=a|e;s=k;k=G[q+10|0];a=k;e=a>>>8|0;a=a<<24|p;e=e|i;ea=((e&127)<<25|a>>>7)&2097151;a=se(ea,0,Y,j);i=s+a|0;e=$+f|0;p=i;f=a>>>0>i>>>0?e+1|0:e;a=G[q+11|0];e=a>>>24|0;k=k|a<<8;a=e;i=k;k=G[q+12|0];e=k>>>16|0;i=i|k<<16;k=a|e;e=g<<24;g=g>>>8|k;a=e|i;fa=((g&15)<<28|a>>>4)&2097151;a=se(fa,0,aa,j);e=a+p|0;f=$+f|0;s=e;k=a>>>0>e>>>0?f+1|0:f;a=G[t+11|0];e=a>>>24|0;i=G[t+10|0];f=i|a<<8;p=G[t+12|0];a=p>>>16|0;p=f|p<<16;e=a|e|m>>>8;ga=((e&15)<<28|(m<<24|p)>>>4)&2097151;e=se(Z,j,ga,0);f=e+s|0;a=$+k|0;s=f;m=e>>>0>f>>>0?a+1|0:a;f=G[t+8|0];e=f>>>24|0;k=G[t+7|0];a=k|f<<8;p=G[t+9|0];f=p>>>16|0;p=a|p<<16;f=e|f|i>>>8;a=i<<24|p;ia=((f&127)<<25|a>>>7)&2097151;a=se(X,j,ia,0);f=a+s|0;e=$+m|0;g=a>>>0>f>>>0?e+1|0:e;a=G[t+6|0];e=a>>>24|0;i=G[t+5|0];m=i|a<<8;e=k>>>16|e;a=k<<16|m;ja=((e&3)<<30|a>>>2)&2097151;e=se(U,H,ja,0);f=e+f|0;a=$+g|0;u=f;m=e>>>0>f>>>0?a+1|0:a;e=G[t+3|0];a=e>>>24|0;g=G[t+2|0];f=g|e<<8;p=G[t+4|0];e=p>>>16|0;s=f|p<<16;f=a|e|i>>>8;a=i<<24|s;ka=((f&31)<<27|a>>>5)&2097151;a=se(O,x,ka,0);e=a+u|0;f=$+m|0;f=a>>>0>e>>>0?f+1|0:f;la=g<<16&2031616|(G[t|0]|G[t+1|0]<<8);a=se(L,x,la,0);g=a+e|0;e=$+f|0;i=g;f=a>>>0>g>>>0?e+1|0:e;e=G[h+184|0];a=e>>>24|0;g=G[h+183|0];k=g|e<<8;e=a;m=k;k=G[h+185|0];a=k>>>16|0;m=m|k<<16;k=a|e;La=G[h+186|0];e=La;a=e>>>8|0;e=e<<24;k=a|k;a=e|m;a=((k&31)<<27|a>>>5)&2097151;k=a+i|0;e=f;m=k;k=a>>>0>k>>>0?e+1|0:e;f=G[h+181|0]|G[h+182|0]<<8;a=se(V,W,ba,j);e=$;s=f;f=a;a=se(T,j,ca,j);i=f+a|0;f=$+e|0;f=a>>>0>i>>>0?f+1|0:f;e=se(da,j,Y,j);i=e+i|0;a=$+f|0;a=e>>>0>i>>>0?a+1|0:a;f=se(aa,j,ea,j);i=f+i|0;e=$+a|0;e=f>>>0>i>>>0?e+1|0:e;f=se(fa,j,ga,j);i=f+i|0;a=$+e|0;a=f>>>0>i>>>0?a+1|0:a;f=se(Z,j,ia,j);i=f+i|0;e=$+a|0;e=f>>>0>i>>>0?e+1|0:e;a=se(X,j,ja,j);i=a+i|0;f=$+e|0;f=a>>>0>i>>>0?f+1|0:f;e=se(U,H,ka,j);i=e+i|0;a=$+f|0;a=e>>>0>i>>>0?a+1|0:a;f=se(O,x,la,j);i=f+i|0;e=$+a|0;e=f>>>0>i>>>0?e+1|0:e;f=i;i=s+f|0;a=f>>>0>i>>>0?e+1|0:e;f=g<<16&2031616;g=f+i|0;e=a;e=f>>>0>g>>>0?e+1|0:e;f=e;u=e-((g>>>0<4293918720)-1|0)|0;e=u>>>21|0;a=m;y=g- -1048576|0;m=(u&2097151)<<11|y>>>21;i=a+m|0;a=e+k|0;a=i>>>0>>0?a+1|0:a;m=i;k=i;i=i+w|0;e=a;a=e+o|0;a=i>>>0>>0?a+1|0:a;k=e;e=m;m=k-((e>>>0<4293918720)-1|0)|0;Ma=e- -1048576|0;e=i;k=Ma&-2097152;E=e-k|0;ma=a-((e>>>0>>0)+m|0)|0;s=g;p=f;a=se(ya,Ha,470296,0);e=$;f=a;a=se(Da,Ea,666643,0);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(Ja,Ka,654183,0);g=a+f|0;a=$+e|0;J=g;o=f>>>0>g>>>0?a+1|0:a;a=se(Y,j,ba,j);e=$;f=a;a=se(V,W,ca,j);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(da,j,aa,j);g=a+f|0;a=$+e|0;a=f>>>0>g>>>0?a+1|0:a;e=se(ga,j,ea,j);g=e+g|0;f=$+a|0;f=e>>>0>g>>>0?f+1|0:f;a=se(ia,j,fa,j);g=a+g|0;e=$+f|0;e=a>>>0>g>>>0?e+1|0:e;f=se(Z,j,ja,j);g=f+g|0;a=$+e|0;a=f>>>0>g>>>0?a+1|0:a;f=se(X,j,ka,j);g=f+g|0;e=$+a|0;e=f>>>0>g>>>0?e+1|0:e;f=se(U,H,la,j);g=f+g|0;a=$+e|0;e=g;f=f>>>0>e>>>0?a+1|0:a;g=G[h+179|0];a=g>>>24|0;i=G[h+178|0];k=i|g<<8;t=e;g=G[h+180|0];e=g>>>16|0;g=g<<16;w=a|e;e=g|k;e=(w&7)<<29|e>>>3;g=t+e|0;f=(w>>>3|0)+f|0;q=g;k=e>>>0>g>>>0?f+1|0:f;a=se(aa,j,ba,j);e=$;f=a;a=se(Y,j,ca,j);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=se(da,j,ga,j);f=a+f|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(ia,j,ea,j);g=a+f|0;a=$+e|0;a=f>>>0>g>>>0?a+1|0:a;e=se(fa,j,ja,j);f=e+g|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=se(Z,j,ka,j);g=e+f|0;f=$+a|0;f=e>>>0>g>>>0?f+1|0:f;a=se(X,j,la,j);g=a+g|0;e=$+f|0;t=g;g=a>>>0>g>>>0?e+1|0:e;e=G[h+176|0];a=e>>>24|0;ra=G[h+175|0];w=ra|e<<8;e=G[h+177|0];f=e>>>16|0;w=w|e<<16;e=a|f|i>>>8;a=((e&63)<<26|(i<<24|w)>>>6)&2097151;f=a+t|0;e=g;t=f;e=a>>>0>f>>>0?e+1|0:e;i=e;na=e-((f>>>0<4293918720)-1|0)|0;e=na>>>21|0;Xa=f- -1048576|0;a=(na&2097151)<<11|Xa>>>21;g=a+q|0;f=e+k|0;w=g;f=a>>>0>g>>>0?f+1|0:f;wa=f;pa=f-((g>>>0<4293918720)-1|0)|0;e=pa>>>21|0;Na=g- -1048576|0;a=(pa&2097151)<<11|Na>>>21;f=a+J|0;e=e+o|0;e=a>>>0>f>>>0?e+1|0:e;g=f+s|0;a=e+p|0;e=g;f=f>>>0>e>>>0?a+1|0:a;a=y&-2097152;k=f-((a>>>0>e>>>0)+u|0)|0;y=e-a|0;Ya=y- -1048576|0;a=Ya;M=k-((y>>>0<4293918720)-1|0)|0;e=M>>21;a=(M&2097151)<<11|a>>>21;f=a+E|0;e=e+ma|0;p=f;e=a>>>0>f>>>0?e+1|0:e;g=e;Oa=e-((f>>>0<4293918720)-1|0)|0;e=Oa>>21;Za=f- -1048576|0;K=(Oa&2097151)<<11|Za>>>21;s=e;a=A&-2097152;xa=n-a|0;sa=v-((a>>>0>n>>>0)+z|0)|0;o=se(P,Q,c,b);a=$;qa=a;v=a-((o>>>0<4293918720)-1|0)|0;Aa=o- -1048576|0;a=Aa;Ba=(v&2097151)<<11|a>>>21;e=v>>>21|0;Pa=e;e=se(Ba,e,-683901,-1);f=e+r|0;a=$+l|0;a=e>>>0>f>>>0?a+1|0:a;e=C&-2097152;z=f-e|0;u=a-((e>>>0>f>>>0)+B|0)|0;a=se(N,x,Z,j);e=$;f=a;a=se(P,Q,fa,j);l=f+a|0;f=$+e|0;f=a>>>0>l>>>0?f+1|0:f;a=se(S,j,X,j);l=a+l|0;e=$+f|0;e=a>>>0>l>>>0?e+1|0:e;f=se(T,j,U,H);l=f+l|0;a=$+e|0;a=f>>>0>l>>>0?a+1|0:a;e=se(O,x,V,W);f=e+l|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=f;f=se(L,x,Y,j);l=e+f|0;e=$+a|0;e=f>>>0>l>>>0?e+1|0:e;a=se(R,j,aa,j);l=a+l|0;f=$+e|0;f=a>>>0>l>>>0?f+1|0:f;a=se(c,b,ga,j);l=a+l|0;e=$+f|0;n=l;l=a>>>0>l>>>0?e+1|0:e;e=se(N,x,fa,j);a=$;f=e;e=se(P,Q,ea,j);f=f+e|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=se(S,j,Z,j);f=e+f|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=f;f=se(T,j,X,j);r=e+f|0;e=$+a|0;e=f>>>0>r>>>0?e+1|0:e;a=se(U,H,V,W);r=a+r|0;f=$+e|0;f=a>>>0>r>>>0?f+1|0:f;a=se(O,x,Y,j);r=a+r|0;e=$+f|0;e=a>>>0>r>>>0?e+1|0:e;f=se(L,x,aa,j);r=f+r|0;a=$+e|0;a=f>>>0>r>>>0?a+1|0:a;e=se(R,j,ga,j);f=e+r|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=f;f=se(c,b,ia,j);r=e+f|0;e=$+a|0;ta=r;e=f>>>0>r>>>0?e+1|0:e;ma=e;a=r;J=e-((a>>>0<4293918720)-1|0)|0;va=a- -1048576|0;e=va;f=(J&2097151)<<11|e>>>21;n=f+n|0;e=(J>>21)+l|0;r=n;e=f>>>0>n>>>0?e+1|0:e;q=e;C=e-((n>>>0<4293918720)-1|0)|0;oa=n- -1048576|0;e=oa;f=(C&2097151)<<11|e>>>21;l=f+z|0;e=(C>>21)+u|0;n=l;e=f>>>0>l>>>0?e+1|0:e;A=e;B=e-((l>>>0<4293918720)-1|0)|0;E=l- -1048576|0;e=E;f=(B&2097151)<<11|e>>>21;l=f+xa|0;e=(B>>21)+sa|0;Qa=l;e=f>>>0>l>>>0?e+1|0:e;Ra=e;e=se(l,e,-683901,-1);f=e+K|0;a=$+s|0;K=f;z=e>>>0>f>>>0?a+1|0:a;a=se(S,j,ba,j);e=$;f=a;a=se(N,x,ca,j);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=se(T,j,da,j);l=a+f|0;f=$+e|0;f=a>>>0>l>>>0?f+1|0:f;e=se(V,W,ea,j);l=e+l|0;a=$+f|0;a=e>>>0>l>>>0?a+1|0:a;f=se(Y,j,fa,j);l=f+l|0;e=$+a|0;e=f>>>0>l>>>0?e+1|0:e;f=se(Z,j,aa,j);l=f+l|0;a=$+e|0;a=f>>>0>l>>>0?a+1|0:a;f=se(X,j,ga,j);l=f+l|0;e=$+a|0;e=f>>>0>l>>>0?e+1|0:e;a=se(U,H,ia,j);l=a+l|0;f=$+e|0;f=a>>>0>l>>>0?f+1|0:f;e=se(O,x,ja,j);l=e+l|0;a=$+f|0;a=e>>>0>l>>>0?a+1|0:a;f=se(L,x,ka,j);l=f+l|0;e=$+a|0;e=f>>>0>l>>>0?e+1|0:e;f=se(R,j,la,j);l=f+l|0;a=$+e|0;e=l;f=f>>>0>e>>>0?a+1|0:a;l=G[h+187|0];a=l>>>24|0;s=La|l<<8;u=e;ab=G[h+188|0];l=ab;e=l>>>16|0;l=l<<16;e=a|e;a=l|s;a=((e&3)<<30|a>>>2)&2097151;l=u+a|0;e=f;e=a>>>0>l>>>0?e+1|0:e;u=l;s=e;xa=se(za,Ia,470296,0);sa=$;e=Aa&-2097152;a=o-e|0;o=qa-((v&2147483647)+(e>>>0>o>>>0)|0)|0;f=(I&2097151)<<11|Fa>>>21;v=f+a|0;a=(I>>>21|0)+o|0;Sa=v;a=f>>>0>v>>>0?a+1|0:a;Ta=a;a=se(v,a,666643,0);f=a+xa|0;e=$+sa|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(Da,Ea,654183,0);o=a+f|0;a=$+e|0;a=f>>>0>o>>>0?a+1|0:a;e=se(ya,Ha,-997805,-1);o=e+o|0;f=$+a|0;f=e>>>0>o>>>0?f+1|0:f;a=se(Ja,Ka,136657,0);o=a+o|0;e=$+f|0;e=a>>>0>o>>>0?e+1|0:e;bb=l- -1048576|0;f=s-((l>>>0<4293918720)-1|0)|0;l=f;a=m>>>21|0;m=(m&2097151)<<11|Ma>>>21;o=o+m|0;a=a+e|0;a=m>>>0>o>>>0?a+1|0:a;m=o;o=m+u|0;e=a+s|0;e=m>>>0>o>>>0?e+1|0:e;a=bb&-2097152;m=o-a|0;s=m+K|0;e=e-((a>>>0>o>>>0)+f|0)|0;a=e+z|0;a=m>>>0>s>>>0?a+1|0:a;f=s;s=e;e=m;m=s-((e>>>0<4293918720)-1|0)|0;cb=e- -1048576|0;e=f;f=cb&-2097152;a=a-((e>>>0>>0)+m|0)|0;v=e-f|0;qa=v;K=a;o=g;a=E&-2097152;E=n-a|0;I=A-((a>>>0>n>>>0)+B|0)|0;e=se(Sa,Ta,-683901,-1);a=$;f=e;e=se(Ba,Pa,136657,0);f=f+e|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;f=f+r|0;e=a+q|0;e=f>>>0>>0?e+1|0:e;a=oa&-2097152;A=f-a|0;B=e-((a>>>0>f>>>0)+C|0)|0;a=se(Ba,Pa,-997805,-1);f=a+ta|0;e=$+ma|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(Sa,Ta,136657,0);g=a+f|0;a=$+e|0;a=f>>>0>g>>>0?a+1|0:a;f=se(za,Ia,-683901,-1);g=f+g|0;e=$+a|0;e=f>>>0>g>>>0?e+1|0:e;f=g;a=va&-2097152;s=f-a|0;r=e-((a>>>0>f>>>0)+J|0)|0;a=se(N,x,ea,j);e=$;f=a;a=se(P,Q,da,j);g=f+a|0;f=$+e|0;f=a>>>0>g>>>0?f+1|0:f;e=se(S,j,fa,j);g=e+g|0;a=$+f|0;a=e>>>0>g>>>0?a+1|0:a;f=se(T,j,Z,j);g=f+g|0;e=$+a|0;e=f>>>0>g>>>0?e+1|0:e;a=se(X,j,V,W);f=a+g|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(U,H,Y,j);g=a+f|0;a=$+e|0;a=f>>>0>g>>>0?a+1|0:a;e=se(O,x,aa,j);g=e+g|0;f=$+a|0;f=e>>>0>g>>>0?f+1|0:f;e=se(L,x,ga,j);g=e+g|0;a=$+f|0;a=e>>>0>g>>>0?a+1|0:a;f=se(R,j,ia,j);g=f+g|0;e=$+a|0;e=f>>>0>g>>>0?e+1|0:e;a=se(c,b,ja,j);f=a+g|0;e=$+e|0;n=f;g=a>>>0>f>>>0?e+1|0:e;e=se(N,x,da,j);a=$;f=e;e=se(P,Q,ba,j);f=f+e|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=se(S,j,ea,j);u=e+f|0;f=$+a|0;f=e>>>0>u>>>0?f+1|0:f;e=se(T,j,fa,j);u=e+u|0;a=$+f|0;a=e>>>0>u>>>0?a+1|0:a;f=se(V,W,Z,j);u=f+u|0;e=$+a|0;e=f>>>0>u>>>0?e+1|0:e;a=se(X,j,Y,j);f=a+u|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(U,H,aa,j);u=a+f|0;a=$+e|0;a=f>>>0>u>>>0?a+1|0:a;e=se(O,x,ga,j);u=e+u|0;f=$+a|0;f=e>>>0>u>>>0?f+1|0:f;e=se(L,x,ia,j);u=e+u|0;a=$+f|0;a=e>>>0>u>>>0?a+1|0:a;f=se(R,j,ja,j);u=f+u|0;e=$+a|0;e=f>>>0>u>>>0?e+1|0:e;a=se(c,b,ka,j);f=a+u|0;e=$+e|0;z=f;e=a>>>0>f>>>0?e+1|0:e;xa=e;sa=e-((f>>>0<4293918720)-1|0)|0;e=sa>>21;eb=f- -1048576|0;a=(sa&2097151)<<11|eb>>>21;n=a+n|0;f=e+g|0;u=n;f=a>>>0>n>>>0?f+1|0:f;Aa=f;ta=f-((n>>>0<4293918720)-1|0)|0;e=ta>>21;fb=n- -1048576|0;a=(ta&2097151)<<11|fb>>>21;f=a+s|0;e=e+r|0;s=f;e=a>>>0>f>>>0?e+1|0:e;va=e;oa=e-((f>>>0<4293918720)-1|0)|0;e=oa>>21;Fa=f- -1048576|0;a=(oa&2097151)<<11|Fa>>>21;g=a+A|0;f=e+B|0;f=a>>>0>g>>>0?f+1|0:f;r=f;n=f-((g>>>0<4293918720)-1|0)|0;e=n>>21;A=g- -1048576|0;a=(n&2097151)<<11|A>>>21;f=a+E|0;e=e+I|0;Ua=f;e=a>>>0>f>>>0?e+1|0:e;Va=e;e=se(f,e,-683901,-1);a=$;f=e;e=se(Qa,Ra,136657,0);f=f+e|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=f;p=e+p|0;f=a+o|0;gb=p;E=e>>>0>p>>>0?f+1|0:f;I=y;B=k;f=se(Ua,Va,136657,0);k=$;a=A&-2097152;e=r-((a>>>0>g>>>0)+n|0)|0;Ca=g-a|0;Wa=e;a=f;f=se(Qa,Ra,-997805,-1);g=a+f|0;a=$+k|0;a=f>>>0>g>>>0?a+1|0:a;f=se(Ca,e,-683901,-1);g=f+g|0;e=$+a|0;hb=g;y=f>>>0>g>>>0?e+1|0:e;a=se(Ja,Ka,470296,0);e=$;f=a;a=se(ya,Ha,666643,0);g=f+a|0;f=$+e|0;e=g+w|0;a=wa+(a>>>0>g>>>0?f+1|0:f)|0;a=e>>>0>>0?a+1|0:a;f=e;e=Na&-2097152;_a=f-e|0;$a=a-((e>>>0>f>>>0)+pa|0)|0;C=se(Ja,Ka,666643,0);A=$;a=se(ba,j,ga,j);e=$;f=a;a=se(aa,j,ca,j);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=se(da,j,ia,j);g=a+f|0;f=$+e|0;f=a>>>0>g>>>0?f+1|0:f;e=se(ea,j,ja,j);g=e+g|0;a=$+f|0;a=e>>>0>g>>>0?a+1|0:a;f=se(fa,j,ka,j);g=f+g|0;e=$+a|0;e=f>>>0>g>>>0?e+1|0:e;f=se(Z,j,la,j);g=f+g|0;a=$+e|0;a=f>>>0>g>>>0?a+1|0:a;f=a;e=G[h+174|0];a=e>>>24|0;k=G[h+173|0];n=k|e<<8;e=ra>>>16|a;a=ra<<16|n;a=((e&1)<<31|a>>>1)&2097151;g=a+g|0;e=f;w=g;g=a>>>0>g>>>0?e+1|0:e;a=se(ia,j,ba,j);e=$;f=a;a=se(ca,j,ga,j);n=f+a|0;f=$+e|0;f=a>>>0>n>>>0?f+1|0:f;e=se(da,j,ja,j);n=e+n|0;a=$+f|0;a=e>>>0>n>>>0?a+1|0:a;f=se(ea,j,ka,j);n=f+n|0;e=$+a|0;e=f>>>0>n>>>0?e+1|0:e;f=se(fa,j,la,j);n=f+n|0;a=$+e|0;o=n;f=f>>>0>o>>>0?a+1|0:a;e=G[h+171|0];a=e>>>24|0;ra=G[h+170|0];r=ra|e<<8;n=G[h+172|0];e=n>>>16|0;r=r|n<<16;n=a|e;e=k<<24;k=k>>>8|n;a=e|r;a=((k&15)<<28|a>>>4)&2097151;k=a+o|0;e=f;p=k;e=a>>>0>k>>>0?e+1|0:e;k=e;wa=e-((p>>>0<4293918720)-1|0)|0;Ma=p- -1048576|0;e=Ma;f=(wa&2097151)<<11|e>>>21;n=f+w|0;e=(wa>>>21|0)+g|0;o=n;e=f>>>0>o>>>0?e+1|0:e;pa=e;ma=e-((o>>>0<4293918720)-1|0)|0;La=o- -1048576|0;e=La;f=(ma&2097151)<<11|e>>>21;g=f+C|0;e=(ma>>>21|0)+A|0;e=f>>>0>g>>>0?e+1|0:e;a=g;g=a+t|0;f=e+i|0;e=g;f=a>>>0>e>>>0?f+1|0:f;a=Xa&-2097152;J=f-((a>>>0>e>>>0)+na|0)|0;r=e-a|0;Na=r- -1048576|0;e=Na;q=J-((r>>>0<4293918720)-1|0)|0;a=q>>21;f=(q&2097151)<<11|e>>>21;g=f+_a|0;e=a+$a|0;n=g;e=f>>>0>g>>>0?e+1|0:e;C=e;A=e-((g>>>0<4293918720)-1|0)|0;na=g- -1048576|0;e=na;f=(A&2097151)<<11|e>>>21;g=f+hb|0;e=(A>>21)+y|0;e=f>>>0>g>>>0?e+1|0:e;f=g;g=f+I|0;a=e+B|0;e=g;f=f>>>0>e>>>0?a+1|0:a;a=Ya&-2097152;B=f-((a>>>0>e>>>0)+M|0)|0;i=e-a|0;M=i- -1048576|0;e=M;t=B-((i>>>0<4293918720)-1|0)|0;a=t>>21;f=(t&2097151)<<11|e>>>21;g=f+gb|0;e=a+E|0;e=f>>>0>g>>>0?e+1|0:e;f=g;a=Za&-2097152;w=e-((a>>>0>f>>>0)+Oa|0)|0;e=f-a|0;g=K-((v>>>0<4293918720)-1|0)|0;_a=v- -1048576|0;y=w-((e>>>0<4293918720)-1|0)|0;f=y>>21;I=e- -1048576|0;v=(y&2097151)<<11|I>>>21;E=v+qa|0;a=f+K|0;a=v>>>0>E>>>0?a+1|0:a;v=E;f=_a&-2097152;$a=v-f|0;Xa=a-((f>>>0>v>>>0)+g|0)|0;a=I&-2097152;Ya=e-a|0;Za=w-((a>>>0>e>>>0)+y|0)|0;a=M&-2097152;Oa=i-a|0;qa=B-((a>>>0>i>>>0)+t|0)|0;a=se(Ua,Va,-997805,-1);e=$;f=a;a=se(Qa,Ra,654183,0);i=f+a|0;f=$+e|0;f=a>>>0>i>>>0?f+1|0:f;a=se(Ca,Wa,136657,0);i=a+i|0;e=$+f|0;e=a>>>0>i>>>0?e+1|0:e;a=i+n|0;e=e+C|0;e=a>>>0>>0?e+1|0:e;f=a;a=na&-2097152;K=f-a|0;E=e-((a>>>0>f>>>0)+A|0)|0;a=Fa&-2097152;I=s-a|0;C=va-((a>>>0>s>>>0)+oa|0)|0;a=se(Sa,Ta,-997805,-1);e=$;f=a;a=se(Ba,Pa,654183,0);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=se(za,Ia,136657,0);i=a+f|0;f=$+e|0;f=a>>>0>i>>>0?f+1|0:f;e=se(Da,Ea,-683901,-1);i=e+i|0;a=$+f|0;f=i+u|0;e=Aa+(e>>>0>i>>>0?a+1|0:a)|0;e=f>>>0>>0?e+1|0:e;a=fb&-2097152;t=f-a|0;w=e-((a>>>0>f>>>0)+ta|0)|0;a=se(Sa,Ta,654183,0);e=$;f=a;a=se(Ba,Pa,470296,0);f=f+a|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(za,Ia,-997805,-1);i=a+f|0;a=$+e|0;a=f>>>0>i>>>0?a+1|0:a;f=i+z|0;e=a+xa|0;a=se(Da,Ea,136657,0);i=a+f|0;f=$+(f>>>0>>0?e+1|0:e)|0;f=a>>>0>i>>>0?f+1|0:f;e=se(ya,Ha,-683901,-1);i=e+i|0;a=$+f|0;a=e>>>0>i>>>0?a+1|0:a;f=i;e=eb&-2097152;s=f-e|0;n=a-((e>>>0>f>>>0)+sa|0)|0;e=se(N,x,ba,j);a=$;f=e;e=se(P,Q,ca,j);f=f+e|0;a=$+a|0;a=e>>>0>f>>>0?a+1|0:a;e=se(S,j,da,j);i=e+f|0;f=$+a|0;f=e>>>0>i>>>0?f+1|0:f;e=se(T,j,ea,j);i=e+i|0;a=$+f|0;a=e>>>0>i>>>0?a+1|0:a;f=se(V,W,fa,j);i=f+i|0;e=$+a|0;e=f>>>0>i>>>0?e+1|0:e;a=se(Y,j,Z,j);f=a+i|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=f;f=se(X,j,aa,j);i=a+f|0;a=$+e|0;a=f>>>0>i>>>0?a+1|0:a;e=se(U,H,ga,j);i=e+i|0;f=$+a|0;f=e>>>0>i>>>0?f+1|0:f;e=se(O,x,ia,j);i=e+i|0;a=$+f|0;a=e>>>0>i>>>0?a+1|0:a;f=se(L,x,ja,j);i=f+i|0;e=$+a|0;e=f>>>0>i>>>0?e+1|0:e;a=se(R,j,ka,j);f=a+i|0;e=$+e|0;b=se(c,b,la,j);c=b+f|0;a=$+(a>>>0>f>>>0?e+1|0:e)|0;i=c;b=b>>>0>c>>>0?a+1|0:a;c=G[h+189|0];a=c>>>24|0;f=ab|c<<8;c=G[h+190|0];e=c>>>16|0;f=f|c<<16;e=a|e;v=i;c=G[h+191|0];a=c>>>8|0;c=c<<24;i=a|e;a=c|f;a=(i&127)<<25|a>>>7;c=v+a|0;f=(i>>>7|0)+b|0;f=a>>>0>c>>>0?f+1|0:f;b=(l&2097151)<<11|bb>>>21;c=b+c|0;a=(l>>>21|0)+f|0;i=c;a=b>>>0>c>>>0?a+1|0:a;y=a;v=a-((c>>>0<4293918720)-1|0)|0;A=c- -1048576|0;a=A;a=(v&2097151)<<11|a>>>21;b=a+s|0;e=(v>>21)+n|0;l=b;e=a>>>0>b>>>0?e+1|0:e;z=e;u=e-((b>>>0<4293918720)-1|0)|0;e=u>>21;B=b- -1048576|0;b=(u&2097151)<<11|B>>>21;c=b+t|0;a=e+w|0;a=b>>>0>c>>>0?a+1|0:a;b=c;s=a;c=a-((b>>>0<4293918720)-1|0)|0;a=b- -1048576|0;e=(c>>21)+C|0;f=(c&2097151)<<11|a>>>21;n=f+I|0;na=n;e=f>>>0>n>>>0?e+1|0:e;oa=e;e=se(n,e,-683901,-1);n=e+K|0;f=$+E|0;w=n;n=e>>>0>n>>>0?f+1|0:f;f=se(Ua,Va,654183,0);e=$;a=a&-2097152;c=s-((a>>>0>b>>>0)+c|0)|0;M=b-a|0;E=c;b=se(Qa,Ra,470296,0);f=b+f|0;a=$+e|0;a=b>>>0>f>>>0?a+1|0:a;b=se(Ca,Wa,-997805,-1);e=b+f|0;a=$+a|0;a=b>>>0>e>>>0?a+1|0:a;b=e+r|0;e=a+J|0;e=b>>>0>>0?e+1|0:e;a=se(na,oa,136657,0);f=b;b=Na&-2097152;r=a+(f-b|0)|0;f=$+(e-((b>>>0>f>>>0)+q|0)|0)|0;f=a>>>0>r>>>0?f+1|0:f;a=se(M,c,-683901,-1);b=a+r|0;e=$+f|0;c=b;e=a>>>0>b>>>0?e+1|0:e;s=e;r=e-((b>>>0<4293918720)-1|0)|0;a=r>>21;t=b- -1048576|0;b=(r&2097151)<<11|t>>>21;e=b+w|0;f=a+n|0;f=b>>>0>e>>>0?f+1|0:f;b=e;n=f;f=f-((e>>>0<4293918720)-1|0)|0;a=f>>21;w=e- -1048576|0;H=(f&2097151)<<11|w>>>21;C=H+Oa|0;e=a+qa|0;xa=C;H=C>>>0>>0?e+1|0:e;a=w&-2097152;sa=b-a|0;Aa=n-((a>>>0>b>>>0)+f|0)|0;a=t&-2097152;ta=c-a|0;va=s-((a>>>0>c>>>0)+r|0)|0;b=se(Ua,Va,470296,0);a=$;c=b;b=se(Qa,Ra,666643,0);c=c+b|0;a=$+a|0;a=b>>>0>c>>>0?a+1|0:a;b=se(Ca,Wa,654183,0);c=b+c|0;a=$+a|0;a=b>>>0>c>>>0?a+1|0:a;b=c+o|0;e=a+pa|0;e=b>>>0>>0?e+1|0:e;a=La&-2097152;s=b-a|0;o=e-((a>>>0>b>>>0)+ma|0)|0;a=B&-2097152;r=l-a|0;n=z-((a>>>0>l>>>0)+u|0)|0;b=se(Sa,Ta,470296,0);a=$;c=b;b=se(Ba,Pa,666643,0);c=c+b|0;a=$+a|0;a=b>>>0>c>>>0?a+1|0:a;b=se(za,Ia,654183,0);c=b+c|0;a=$+a|0;a=b>>>0>c>>>0?a+1|0:a;b=se(Da,Ea,-997805,-1);c=b+c|0;e=$+a|0;e=b>>>0>c>>>0?e+1|0:e;a=se(ya,Ha,136657,0);b=a+c|0;e=$+e|0;e=a>>>0>b>>>0?e+1|0:e;a=se(Ja,Ka,-683901,-1);b=a+b|0;f=$+e|0;f=a>>>0>b>>>0?f+1|0:f;b=b+i|0;a=f+y|0;a=b>>>0>>0?a+1|0:a;e=b;c=A&-2097152;b=(m&2097151)<<11|cb>>>21;f=(e-c|0)+b|0;e=(a-((c>>>0>e>>>0)+v|0)|0)+(m>>21)|0;l=f;e=b>>>0>f>>>0?e+1|0:e;t=e;u=e-((f>>>0<4293918720)-1|0)|0;a=u>>21;C=f- -1048576|0;b=(u&2097151)<<11|C>>>21;c=b+r|0;e=a+n|0;qa=c;e=b>>>0>c>>>0?e+1|0:e;I=e;b=se(c,e,-683901,-1);c=b+s|0;a=$+o|0;a=b>>>0>c>>>0?a+1|0:a;b=se(na,oa,-997805,-1);c=b+c|0;e=$+a|0;e=b>>>0>c>>>0?e+1|0:e;a=se(M,E,136657,0);b=a+c|0;f=$+e|0;z=b;s=a>>>0>b>>>0?f+1|0:f;n=p;i=k;b=se(ba,j,ja,j);a=$;c=b;b=se(ca,j,ia,j);c=c+b|0;a=$+a|0;a=b>>>0>c>>>0?a+1|0:a;b=se(da,j,ka,j);c=b+c|0;e=$+a|0;e=b>>>0>c>>>0?e+1|0:e;b=se(ea,j,la,j);c=b+c|0;a=$+e|0;m=c;b=b>>>0>c>>>0?a+1|0:a;c=G[h+168|0];a=c>>>24|0;k=G[h+167|0];f=k|c<<8;c=G[h+169|0];e=c>>>16|0;f=f|c<<16;e=a|e|ra>>>8;a=ra<<24|f;a=((e&127)<<25|a>>>7)&2097151;c=a+m|0;e=b;r=c;c=a>>>0>c>>>0?e+1|0:e;a=se(ba,j,ka,j);b=$;e=a;a=se(ca,j,ja,j);e=e+a|0;f=$+b|0;f=a>>>0>e>>>0?f+1|0:f;a=se(da,j,la,j);b=a+e|0;e=$+f|0;f=b;b=a>>>0>f>>>0?e+1|0:e;a=G[h+166|0];e=a>>>24|0;w=G[h+165|0];m=w|a<<8;e=k>>>16|e;a=k<<16|m;e=((e&3)<<30|a>>>2)&2097151;f=e+f|0;a=b;m=f;a=e>>>0>f>>>0?a+1|0:a;b=a;y=a-((f>>>0<4293918720)-1|0)|0;ma=f- -1048576|0;a=ma;a=(y&2097151)<<11|a>>>21;f=a+r|0;e=(y>>>21|0)+c|0;k=f;e=a>>>0>f>>>0?e+1|0:e;v=e;p=e-((f>>>0<4293918720)-1|0)|0;e=p>>>21|0;J=f- -1048576|0;c=(p&2097151)<<11|J>>>21;f=c+n|0;a=e+i|0;a=c>>>0>f>>>0?a+1|0:a;c=se(Ua,Va,666643,0);e=Ma&-2097152;i=c+(f-e|0)|0;e=$+(a-((e>>>0>f>>>0)+wa|0)|0)|0;e=c>>>0>i>>>0?e+1|0:e;a=se(Ca,Wa,470296,0);c=a+i|0;e=$+e|0;e=a>>>0>c>>>0?e+1|0:e;a=c;c=se(qa,I,136657,0);f=a+c|0;a=$+e|0;a=c>>>0>f>>>0?a+1|0:a;c=se(na,oa,654183,0);e=c+f|0;f=$+a|0;f=c>>>0>e>>>0?f+1|0:f;c=se(M,E,-997805,-1);e=c+e|0;a=$+f|0;q=e;a=c>>>0>e>>>0?a+1|0:a;o=a;r=o-((e>>>0<4293918720)-1|0)|0;A=e- -1048576|0;a=A;a=(r&2097151)<<11|a>>>21;c=a+z|0;e=(r>>21)+s|0;e=a>>>0>c>>>0?e+1|0:e;B=c- -1048576|0;a=B;n=e-((c>>>0<4293918720)-1|0)|0;f=n>>21;i=(n&2097151)<<11|a>>>21;s=i+ta|0;a=f+va|0;ta=s;z=i>>>0>s>>>0?a+1|0:a;i=c;f=e;c=C&-2097152;a=l-c|0;e=t-((c>>>0>l>>>0)+u|0)|0;l=a;a=g>>21;c=(g&2097151)<<11|_a>>>21;g=l+c|0;e=a+e|0;e=c>>>0>g>>>0?e+1|0:e;u=e;s=e-((g>>>0<4293918720)-1|0)|0;a=s>>21;C=g- -1048576|0;K=(s&2097151)<<11|C>>>21;pa=a;c=se(K,a,-683901,-1);e=c+i|0;a=$+f|0;a=c>>>0>e>>>0?a+1|0:a;c=B&-2097152;va=e-c|0;ra=a-((c>>>0>e>>>0)+n|0)|0;a=se(K,pa,136657,0);c=a+q|0;e=$+o|0;e=a>>>0>c>>>0?e+1|0:e;a=A&-2097152;wa=c-a|0;q=e-((a>>>0>c>>>0)+r|0)|0;a=se(Ca,Wa,666643,0);c=J&-2097152;f=a+(k-c|0)|0;e=$+(v-((c>>>0>k>>>0)+p|0)|0)|0;e=a>>>0>f>>>0?e+1|0:e;a=se(qa,I,-997805,-1);c=a+f|0;f=$+e|0;f=a>>>0>c>>>0?f+1|0:f;a=c;c=se(na,oa,470296,0);e=a+c|0;a=$+f|0;a=c>>>0>e>>>0?a+1|0:a;c=se(M,E,654183,0);f=c+e|0;e=$+a|0;v=f;i=c>>>0>f>>>0?e+1|0:e;k=b;b=se(ba,j,la,j);a=$;c=b;b=se(ca,j,ka,j);c=c+b|0;a=$+a|0;n=c;f=b>>>0>c>>>0?a+1|0:a;b=se(ca,j,la,j);l=G[h+162|0];a=l;a=a<<16&2031616|(G[h+160|0]|G[h+161|0]<<8);c=b+a|0;e=$;e=a>>>0>c>>>0?e+1|0:e;p=e;o=e-((c>>>0<4293918720)-1|0)|0;a=o>>>21|0;A=c- -1048576|0;b=(o&2097151)<<11|A>>>21;e=b+n|0;a=a+f|0;n=e;e=b>>>0>e>>>0?a+1|0:a;b=G[h+163|0];a=b>>>24|0;f=l|b<<8;b=a;l=f;f=G[h+164|0];a=f>>>16|0;l=l|f<<16;b=a|b|w>>>8;a=((b&31)<<27|(w<<24|l)>>>5)&2097151;b=a+n|0;e=a>>>0>b>>>0?e+1|0:e;r=e;n=e-((b>>>0<4293918720)-1|0)|0;f=n>>>21|0;B=b- -1048576|0;e=(n&2097151)<<11|B>>>21;m=e+m|0;a=f+k|0;a=e>>>0>m>>>0?a+1|0:a;f=se(qa,I,654183,0);k=m;e=ma&-2097152;m=f+(k-e|0)|0;e=$+(a-((e>>>0>k>>>0)+y|0)|0)|0;a=se(na,oa,666643,0);k=a+m|0;f=$+(f>>>0>m>>>0?e+1|0:e)|0;f=a>>>0>k>>>0?f+1|0:f;e=se(M,E,470296,0);k=e+k|0;a=$+f|0;t=k;a=e>>>0>k>>>0?a+1|0:a;l=a;a=k;m=l-((a>>>0<4293918720)-1|0)|0;w=a- -1048576|0;a=w;e=(m&2097151)<<11|a>>>21;k=e+v|0;a=(m>>21)+i|0;y=k;a=e>>>0>k>>>0?a+1|0:a;e=a;a=k;k=e-((a>>>0<4293918720)-1|0)|0;v=a- -1048576|0;a=v;i=(k&2097151)<<11|a>>>21;J=i+wa|0;a=(k>>21)+q|0;ma=J;i=i>>>0>J>>>0?a+1|0:a;a=se(K,pa,-997805,-1);f=a+y|0;e=$+e|0;e=a>>>0>f>>>0?e+1|0:e;a=v&-2097152;J=f-a|0;q=e-((a>>>0>f>>>0)+k|0)|0;a=se(K,pa,654183,0);f=a+t|0;e=$+l|0;e=a>>>0>f>>>0?e+1|0:e;a=w&-2097152;y=f-a|0;v=e-((a>>>0>f>>>0)+m|0)|0;e=se(qa,I,470296,0);a=B&-2097152;f=e+(b-a|0)|0;a=$+(r-((a>>>0>b>>>0)+n|0)|0)|0;a=e>>>0>f>>>0?a+1|0:a;b=se(M,E,666643,0);e=b+f|0;f=$+a|0;f=b>>>0>e>>>0?f+1|0:f;k=e;a=se(qa,I,666643,0);b=A&-2097152;m=a+(c-b|0)|0;e=$+(p-((o&4095)+(b>>>0>c>>>0)|0)|0)|0;b=m;e=a>>>0>b>>>0?e+1|0:e;l=e;m=e-((b>>>0<4293918720)-1|0)|0;a=m>>21;o=b- -1048576|0;c=(m&2097151)<<11|o>>>21;e=c+k|0;f=a+f|0;f=c>>>0>e>>>0?f+1|0:f;k=f;a=e;f=f-((e>>>0<4293918720)-1|0)|0;n=e- -1048576|0;c=n;c=(f&2097151)<<11|c>>>21;p=c+y|0;e=(f>>21)+v|0;e=c>>>0>p>>>0?e+1|0:e;c=e;e=se(K,pa,470296,0);r=e+a|0;a=$+k|0;a=e>>>0>r>>>0?a+1|0:a;k=n&-2097152;e=r-k|0;f=a-((k>>>0>r>>>0)+f|0)|0;n=e;a=se(K,pa,666643,0);e=o&-2097152;k=a+(b-e|0)|0;e=$+(l-((b>>>0>>0)+m|0)|0)|0;m=k;b=k;e=a>>>0>b>>>0?e+1|0:e;a=e>>21;b=(e&2097151)<<11|b>>>21;e=n+b|0;a=a+f|0;a=b>>>0>e>>>0?a+1|0:a;k=e;b=e;e=a>>21;a=(a&2097151)<<11|b>>>21;b=a+p|0;f=c+e|0;f=a>>>0>b>>>0?f+1|0:f;t=b;b=(f&2097151)<<11|b>>>21;c=b+J|0;e=(f>>21)+q|0;w=c;a=c;e=b>>>0>a>>>0?e+1|0:e;b=(e&2097151)<<11|a>>>21;c=b+ma|0;a=(e>>21)+i|0;a=b>>>0>c>>>0?a+1|0:a;y=c;b=c;e=a>>21;a=(a&2097151)<<11|b>>>21;b=a+va|0;e=e+ra|0;e=a>>>0>b>>>0?e+1|0:e;v=b;b=(e&2097151)<<11|b>>>21;c=b+ta|0;a=(e>>21)+z|0;a=b>>>0>c>>>0?a+1|0:a;z=c;b=c;e=a>>21;a=(a&2097151)<<11|b>>>21;b=a+sa|0;f=e+Aa|0;f=a>>>0>b>>>0?f+1|0:f;p=b;b=(f&2097151)<<11|b>>>21;c=b+xa|0;e=(f>>21)+H|0;o=c;a=c;e=b>>>0>a>>>0?e+1|0:e;b=(e&2097151)<<11|a>>>21;c=b+Ya|0;a=(e>>21)+Za|0;a=b>>>0>c>>>0?a+1|0:a;r=c;b=c;e=a>>21;a=(a&2097151)<<11|b>>>21;b=a+$a|0;e=e+Xa|0;e=a>>>0>b>>>0?e+1|0:e;n=b;a=e>>21;e=(e&2097151)<<11|b>>>21;c=C&-2097152;b=g-c|0;e=e+b|0;f=(u-((c>>>0>g>>>0)+s|0)|0)+a|0;i=e;f=b>>>0>e>>>0?f+1|0:f;s=(f&2097151)<<11|e>>>21;e=f>>21;l=e;a=m&2097151;b=se(s,e,666643,0)+a|0;e=$;m=b;e=a>>>0>b>>>0?e+1|0:e;b=e;D[d+32|0]=m;D[d+33|0]=(e&255)<<24|m>>>8;c=k&2097151;e=se(s,l,470296,0)+c|0;a=$;a=c>>>0>e>>>0?a+1|0:a;c=(b&2097151)<<11|m>>>21;g=c+e|0;f=(b>>21)+a|0;k=g;a=g;f=c>>>0>a>>>0?f+1|0:f;D[d+36|0]=(f&2047)<<21|a>>>11;D[d+35|0]=(f&7)<<29|a>>>3;a=t&2097151;c=se(s,l,654183,0)+a|0;e=$;e=a>>>0>c>>>0?e+1|0:e;a=e;e=f>>21;t=c;c=(f&2097151)<<11|g>>>21;f=t+c|0;a=a+e|0;g=f;a=c>>>0>f>>>0?a+1|0:a;c=a;D[d+38|0]=(a&63)<<26|f>>>6;e=0;k=k&2097151;a=k;D[d+34|0]=((b&65535)<<16|m>>>16)&31|a<<5;b=w&2097151;f=se(s,l,-997805,-1)+b|0;a=$;a=b>>>0>f>>>0?a+1|0:a;b=a;a=c>>21;c=(c&2097151)<<11|g>>>21;m=c+f|0;f=a+b|0;f=c>>>0>m>>>0?f+1|0:f;c=m;a=c;D[d+41|0]=(f&511)<<23|a>>>9;D[d+40|0]=(f&1)<<31|a>>>1;b=0;m=g&2097151;g=m;D[d+37|0]=(e&524287)<<13|k>>>19|g<<2;a=y&2097151;g=se(s,l,136657,0)+a|0;e=$;e=a>>>0>g>>>0?e+1|0:e;a=f;f=a>>21;a=(a&2097151)<<11|c>>>21;g=a+g|0;e=e+f|0;e=a>>>0>g>>>0?e+1|0:e;a=g;D[d+44|0]=(e&4095)<<20|a>>>12;D[d+43|0]=(e&15)<<28|a>>>4;f=0;k=c&2097151;c=k;D[d+39|0]=(b&16383)<<18|m>>>14|c<<7;b=v&2097151;c=se(s,l,-683901,-1)+b|0;a=$;a=b>>>0>c>>>0?a+1|0:a;b=e;e=e>>21;b=(b&2097151)<<11|g>>>21;c=b+c|0;a=a+e|0;a=b>>>0>c>>>0?a+1|0:a;e=c;D[d+46|0]=(a&127)<<25|e>>>7;g=g&2097151;D[d+42|0]=(f&131071)<<15|k>>>17|g<<4;b=a;a=a>>21;b=(b&2097151)<<11|e>>>21;k=b+(z&2097151)|0;c=0;f=a+c|0;f=b>>>0>k>>>0?f+1|0:f;a=k;D[d+49|0]=(f&1023)<<22|a>>>10;D[d+48|0]=(f&3)<<30|a>>>2;m=e&2097151;e=m;D[d+45|0]=(c&1048575)<<12|g>>>20|e<<1;a=f>>21;c=(f&2097151)<<11|k>>>21;f=c+(p&2097151)|0;b=0;e=a+b|0;e=c>>>0>f>>>0?e+1|0:e;a=f;D[d+52|0]=(e&8191)<<19|a>>>13;c=e;D[d+51|0]=(e&31)<<27|a>>>5;f=0;k=k&2097151;e=k;D[d+47|0]=(b&32767)<<17|m>>>15|e<<6;b=(c&2097151)<<11|a>>>21;m=b+(o&2097151)|0;e=c>>21;e=b>>>0>m>>>0?e+1|0:e;D[d+53|0]=m;D[d+50|0]=(f&262143)<<14|k>>>18|a<<3;b=e;a=m;D[d+54|0]=(e&255)<<24|a>>>8;a=(e&2097151)<<11|a>>>21;g=a+(r&2097151)|0;f=e>>21;f=a>>>0>g>>>0?f+1|0:f;a=g;D[d+57|0]=(f&2047)<<21|a>>>11;c=a;D[d+56|0]=(f&7)<<29|a>>>3;a=f>>21;c=(f&2097151)<<11|c>>>21;f=c+(n&2097151)|0;e=a;e=c>>>0>f>>>0?e+1|0:e;a=f;D[d+59|0]=(e&63)<<26|a>>>6;k=g&2097151;a=k;D[d+55|0]=((b&65535)<<16|m>>>16)&31|a<<5;a=e>>21;b=(e&2097151)<<11|f>>>21;e=b+(i&2097151)|0;c=0;a=a+c|0;a=b>>>0>e>>>0?a+1|0:a;D[d+63|0]=(a&131071)<<15|e>>>17;D[d+62|0]=(a&511)<<23|e>>>9;D[d+61|0]=(a&1)<<31|e>>>1;b=0;g=f&2097151;f=g;D[d+58|0]=(c&524287)<<13|k>>>19|f<<2;D[d+60|0]=(b&16383)<<18|f>>>14|e<<7;_=h+624|0}function hb(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,E=0,H=0,I=0,J=0,K=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0;j=_-768|0;_=j;a:{if(G[d+63|0]>31){break a}i=_-272|0;_=i;W=G[a+31|0];V=G[a+30|0];S=G[a+6|0];T=G[a+5|0];U=G[a+9|0];n=G[a+8|0];C=G[a+12|0];I=G[a+11|0];x=G[a+15|0];y=G[a+14|0];A=G[a+28|0];z=G[a+27|0];v=G[a+25|0];o=G[a+24|0];M=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);B=G[a+29|0];w=G[a+4|0];t=G[a+7|0];r=G[a+10|0];s=G[a+13|0];p=G[a+26|0];l=G[a+23|0];q=j+128|0;R=q+40|0;k=R;f=G[a+21|0];g=f>>>17|0;e=f<<15;f=g;K=e;e=G[a+20|0];g=e>>>25|0;N=K|e<<7;e=f|g;f=G[a+22|0];g=f>>>9|0;f=f<<23|N;K=e|g;h=f;f=0;O=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);g=O+16777216|0;f=g>>>0<16777216?1:f;N=g;e=g;g=f>>>25|0;f=(f&33554431)<<7|e>>>25;e=h+f|0;g=g+K|0;g=e>>>0>>0?g+1|0:g;f=e+33554432|0;g=f>>>0<33554432?g+1|0:g;K=f;f=g;g=e;e=K&-67108864;F[k+24>>2]=g-e;g=o>>>19|0;o=o<<13;e=g;g=l>>>27|0;l=l<<5|o;e=e|g;g=v>>>11|0;v=v<<21|l;o=v+((f&67108863)<<6|K>>>26)|0;g=e|g;e=o;f=v+16777216|0;g=f>>>0<16777216?g+1|0:g;o=f;f=g;g=e;e=o&1040187392;F[k+28>>2]=g-e;e=p>>>28|0;p=z<<12|p<<4;l=e|z>>>20|A>>>12;g=f>>>25|0;f=(f&33554431)<<7|o>>>25;e=f+(A<<20|p)|0;g=g+l|0;g=e>>>0>>0?g+1|0:g;f=g;g=e+33554432|0;f=g>>>0<33554432?f+1|0:f;K=g;o=f;f=g&-67108864;F[k+32>>2]=e-f;p=y<<10|s<<2|x<<18;l=y>>>22|s>>>30|x>>>14;e=I<<11|r<<3;f=I>>>21|r>>>29;r=C<<19|e;e=C>>>13|f;g=r+16777216|0;e=g>>>0<16777216?e+1|0:e;z=g;f=g;g=e>>>25|0;f=(e&33554431)<<7|f>>>25;e=f+p|0;g=g+l|0;g=e>>>0>>0?g+1|0:g;f=e;e=e+33554432|0;g=e>>>0<33554432?g+1|0:g;x=e;p=g;g=f;f=e&-67108864;F[k+16>>2]=g-f;f=n>>>19|t>>>27;t=n<<13|t<<5|U<<21;l=U>>>11|f;s=T<<14|w<<6|S<<22;e=T>>>18|w>>>26|S>>>10;g=s+16777216|0;e=g>>>0<16777216?e+1|0:e;v=g;f=e>>>25|0;e=(e&33554431)<<7|g>>>25;t=e+t|0;g=f+l|0;g=e>>>0>t>>>0?g+1|0:g;f=t;e=f+33554432|0;g=e>>>0<33554432?g+1|0:g;y=e;l=g;g=f;f=e&-67108864;F[k+8>>2]=g-f;f=V>>>22|B>>>30;g=o>>>26|0;w=W<<18&33292288|(V<<10|B<<2);o=(o&67108863)<<6|K>>>26;t=w+o|0;o=t;g=f;f=w+16777216|0;g=f>>>0<16777216?g+1|0:g;t=f;f=g;g=o;e=t&33554432;F[k+36>>2]=g-e;e=(p&67108863)<<6|x>>>26;p=e+O|0;F[k+20>>2]=p-(N&-33554432);e=r;l=e+((l&67108863)<<6|y>>>26)|0;F[k+12>>2]=l-(z&234881024);l=s-(v&2113929216)|0;f=se((f&33554431)<<7|t>>>25,f>>>25|0,19,0);e=f+M|0;g=$;g=e>>>0>>0?g+1|0:g;f=e;e=g;g=f+33554432|0;e=g>>>0<33554432?e+1|0:e;e=l+((e&67108863)<<6|g>>>26)|0;F[k+4>>2]=e;k=g&-67108864;F[R>>2]=f-k;F[q+84>>2]=0;F[q+88>>2]=0;F[q+80>>2]=1;F[q+92>>2]=0;F[q+96>>2]=0;F[q+100>>2]=0;F[q+104>>2]=0;F[q+108>>2]=0;F[q+112>>2]=0;F[q+116>>2]=0;M=i+192|0;fa(M,R);P=i+144|0;ha(P,M,1936);K=F[q+116>>2];O=F[q+112>>2];N=F[q+108>>2];W=F[q+104>>2];V=F[q+100>>2];S=F[q+96>>2];T=F[q+92>>2];U=F[q+88>>2];n=F[q+84>>2];C=F[i+228>>2];t=F[i+224>>2];r=F[i+220>>2];s=F[i+216>>2];o=F[i+212>>2];p=F[i+208>>2];l=F[i+204>>2];e=F[i+200>>2];f=F[i+196>>2];k=F[i+192>>2];g=F[q+80>>2];F[i+144>>2]=g+F[i+144>>2];I=k-g|0;F[i+192>>2]=I;x=f-n|0;F[i+196>>2]=x;y=e-U|0;F[i+200>>2]=y;A=l-T|0;F[i+204>>2]=A;z=p-S|0;F[i+208>>2]=z;v=o-V|0;F[i+212>>2]=v;B=s-W|0;F[i+216>>2]=B;w=r-N|0;F[i+220>>2]=w;t=t-O|0;F[i+224>>2]=t;r=C-K|0;F[i+228>>2]=r;s=F[i+148>>2];o=F[i+152>>2];p=F[i+156>>2];l=F[i+160>>2];e=F[i+164>>2];f=F[i+168>>2];k=F[i+172>>2];g=F[i+176>>2];F[i+180>>2]=K+F[i+180>>2];F[i+176>>2]=g+O;F[i+172>>2]=k+N;F[i+168>>2]=f+W;F[i+164>>2]=e+V;F[i+160>>2]=l+S;F[i+156>>2]=p+T;F[i+152>>2]=o+U;F[i+148>>2]=n+s;k=i+96|0;fa(k,P);ha(k,k,P);fa(q,k);ha(q,q,P);ha(q,q,M);f=_-144|0;_=f;g=f+96|0;fa(g,q);e=f+48|0;fa(e,g);fa(e,e);ha(e,q,e);ha(g,g,e);fa(g,g);ha(g,e,g);fa(e,g);fa(e,e);fa(e,e);fa(e,e);fa(e,e);ha(g,e,g);fa(e,g);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);ha(e,e,g);fa(f,e);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);fa(f,f);ha(e,f,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);ha(g,e,g);fa(e,g);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);ha(e,e,g);fa(f,e);g=1;while(1){fa(f,f);g=g+1|0;if((g|0)!=100){continue}break}e=f+48|0;ha(e,f,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);fa(e,e);g=f+96|0;ha(g,e,g);fa(g,g);fa(g,g);ha(q,g,q);_=f+144|0;ha(q,q,k);ha(q,q,M);g=i+48|0;fa(g,q);ha(g,g,P);F[i+36>>2]=F[i+84>>2]-r;F[i+32>>2]=F[i+80>>2]-t;F[i+28>>2]=F[i+76>>2]-w;F[i+24>>2]=F[i+72>>2]-B;F[i+20>>2]=F[i+68>>2]-v;F[i+16>>2]=F[i+64>>2]-z;F[i+12>>2]=F[i+60>>2]-A;F[i+8>>2]=F[i+56>>2]-y;F[i+4>>2]=F[i+52>>2]-x;F[i>>2]=F[i+48>>2]-I;Ga(i+240|0,i);b:{if(G[i+271|0]|(G[i+270|0]|(G[i+269|0]|(G[i+268|0]|(G[i+267|0]|(G[i+266|0]|(G[i+265|0]|(G[i+264|0]|(G[i+263|0]|(G[i+262|0]|(G[i+261|0]|(G[i+260|0]|(G[i+259|0]|(G[i+258|0]|(G[i+257|0]|(G[i+256|0]|(G[i+255|0]|(G[i+254|0]|(G[i+253|0]|(G[i+252|0]|(G[i+251|0]|(G[i+250|0]|(G[i+249|0]|(G[i+248|0]|(G[i+247|0]|(G[i+246|0]|(G[i+245|0]|(G[i+244|0]|(G[i+243|0]|(G[i+242|0]|(G[i+241|0]|G[i+240|0]))))))))))))))))))))))))))))))){I=F[i+192>>2];x=F[i+48>>2];y=F[i+196>>2];A=F[i+52>>2];z=F[i+200>>2];v=F[i+56>>2];B=F[i+204>>2];w=F[i+60>>2];t=F[i+208>>2];r=F[i+64>>2];s=F[i+212>>2];o=F[i+68>>2];p=F[i+216>>2];l=F[i+72>>2];e=F[i+220>>2];f=F[i+76>>2];k=F[i+224>>2];g=F[i+80>>2];F[i+36>>2]=F[i+228>>2]+F[i+84>>2];F[i+32>>2]=g+k;F[i+28>>2]=e+f;F[i+24>>2]=l+p;F[i+20>>2]=o+s;F[i+16>>2]=r+t;F[i+12>>2]=w+B;F[i+8>>2]=v+z;F[i+4>>2]=y+A;F[i>>2]=x+I;Ga(i+240|0,i);g=-1;if(G[i+271|0]|(G[i+270|0]|(G[i+269|0]|(G[i+268|0]|(G[i+267|0]|(G[i+266|0]|(G[i+265|0]|(G[i+264|0]|(G[i+263|0]|(G[i+262|0]|(G[i+261|0]|(G[i+260|0]|(G[i+259|0]|(G[i+258|0]|(G[i+257|0]|(G[i+256|0]|(G[i+255|0]|(G[i+254|0]|(G[i+253|0]|(G[i+252|0]|(G[i+251|0]|(G[i+250|0]|(G[i+249|0]|(G[i+248|0]|(G[i+247|0]|(G[i+246|0]|(G[i+245|0]|(G[i+244|0]|(G[i+243|0]|(G[i+242|0]|(G[i+241|0]|G[i+240|0]))))))))))))))))))))))))))))))){break b}ha(q,q,1984)}Ga(i+240|0,q);if((D[i+240|0]&1)==(G[a+31|0]>>>7|0)){F[q+36>>2]=0-F[q+36>>2];F[q+32>>2]=0-F[q+32>>2];F[q+28>>2]=0-F[q+28>>2];F[q+24>>2]=0-F[q+24>>2];F[q+20>>2]=0-F[q+20>>2];F[q+16>>2]=0-F[q+16>>2];F[q+12>>2]=0-F[q+12>>2];F[q+8>>2]=0-F[q+8>>2];F[q+4>>2]=0-F[q+4>>2];F[q>>2]=0-F[q>>2]}ha(q+120|0,q,R);g=0}_=i+272|0;if(g){break a}F[j+352>>2]=327033209;F[j+356>>2]=1541459225;F[j+344>>2]=-79577749;F[j+348>>2]=528734635;F[j+336>>2]=725511199;F[j+340>>2]=-1694144372;F[j+328>>2]=-1377402159;F[j+332>>2]=1359893119;s=32;F[j+320>>2]=1595750129;F[j+324>>2]=-1521486534;F[j+312>>2]=-23791573;F[j+316>>2]=1013904242;F[j+304>>2]=-2067093701;F[j+308>>2]=-1150833019;F[j+296>>2]=-205731576;F[j+300>>2]=1779033703;F[j+288>>2]=0;F[j+292>>2]=0;F[j+360>>2]=0;D[j+364|0]=G[d|0];D[j+365|0]=G[d+1|0];D[j+366|0]=G[d+2|0];D[j+367|0]=G[d+3|0];r=j+364|0;D[(r+F[j+360>>2]|0)+4|0]=G[d+4|0];D[(r+F[j+360>>2]|0)+5|0]=G[d+5|0];D[(r+F[j+360>>2]|0)+6|0]=G[d+6|0];D[(r+F[j+360>>2]|0)+7|0]=G[d+7|0];D[(r+F[j+360>>2]|0)+8|0]=G[d+8|0];D[(r+F[j+360>>2]|0)+9|0]=G[d+9|0];D[(r+F[j+360>>2]|0)+10|0]=G[d+10|0];D[(r+F[j+360>>2]|0)+11|0]=G[d+11|0];D[(r+F[j+360>>2]|0)+12|0]=G[d+12|0];D[(r+F[j+360>>2]|0)+13|0]=G[d+13|0];D[(r+F[j+360>>2]|0)+14|0]=G[d+14|0];D[(r+F[j+360>>2]|0)+15|0]=G[d+15|0];D[(r+F[j+360>>2]|0)+16|0]=G[d+16|0];D[(r+F[j+360>>2]|0)+17|0]=G[d+17|0];D[(r+F[j+360>>2]|0)+18|0]=G[d+18|0];D[(r+F[j+360>>2]|0)+19|0]=G[d+19|0];D[(r+F[j+360>>2]|0)+20|0]=G[d+20|0];D[(r+F[j+360>>2]|0)+21|0]=G[d+21|0];D[(r+F[j+360>>2]|0)+22|0]=G[d+22|0];D[(r+F[j+360>>2]|0)+23|0]=G[d+23|0];D[(r+F[j+360>>2]|0)+24|0]=G[d+24|0];D[(r+F[j+360>>2]|0)+25|0]=G[d+25|0];D[(r+F[j+360>>2]|0)+26|0]=G[d+26|0];D[(r+F[j+360>>2]|0)+27|0]=G[d+27|0];D[(r+F[j+360>>2]|0)+28|0]=G[d+28|0];D[(r+F[j+360>>2]|0)+29|0]=G[d+29|0];D[(r+F[j+360>>2]|0)+30|0]=G[d+30|0];D[(r+F[j+360>>2]|0)+31|0]=G[d+31|0];g=F[j+360>>2]+32|0;F[j+360>>2]=g;if((g|0)==128){ua(j+288|0,r);F[j+360>>2]=0;g=F[j+292>>2];k=F[j+288>>2]+1024|0;g=k>>>0<1024?g+1|0:g;F[j+288>>2]=k;F[j+292>>2]=g}c:{if(!a){break c}l=F[j+360>>2];if(l>>>0>128){break c}while(1){d:{if(!(s>>>0<128|l)){ua(j+288|0,a);g=F[j+292>>2];k=F[j+288>>2]+1024|0;g=k>>>0<1024?g+1|0:g;F[j+288>>2]=k;F[j+292>>2]=g;s=s-128|0;a=a+128|0;break d}g=128-l|0;o=g>>>0>s>>>0?s:g;e:{if(!o){break e}e=o&3;p=0;f:{if(o-1>>>0<3){u=0;break f}k=o&-4;u=0;f=0;while(1){g=l+u|0;l=j+364|0;D[g+l|0]=G[a+u|0];g=u|1;D[l+(g+F[j+360>>2]|0)|0]=G[a+g|0];g=u|2;D[l+(g+F[j+360>>2]|0)|0]=G[a+g|0];g=u|3;D[l+(g+F[j+360>>2]|0)|0]=G[a+g|0];u=u+4|0;l=F[j+360>>2];f=f+4|0;if((k|0)!=(f|0)){continue}break}}if(!e){break e}while(1){D[((l+u|0)+j|0)+364|0]=G[a+u|0];u=u+1|0;l=F[j+360>>2];p=p+1|0;if((e|0)!=(p|0)){continue}break}}s=s-o|0;a=a+o|0;g=l+o|0;F[j+360>>2]=g;if((g|0)!=128){break d}ua(j+288|0,r);F[j+360>>2]=0;f=F[j+292>>2];g=F[j+288>>2]+1024|0;f=g>>>0<1024?f+1|0:f;F[j+288>>2]=g;F[j+292>>2]=f}if(!s){break c}l=F[j+360>>2];continue}}g:{if(!b|!c){break g}a=F[j+360>>2];if(a>>>0>128){break g}while(1){h:{if(!(c>>>0<128|a)){ua(j+288|0,b);g=F[j+292>>2];a=F[j+288>>2]+1024|0;g=a>>>0<1024?g+1|0:g;F[j+288>>2]=a;F[j+292>>2]=g;c=c-128|0;b=b+128|0;break h}g=128-a|0;l=c>>>0>>0?c:g;i:{if(!l){break i}f=l&3;k=0;j:{if(l-1>>>0<3){u=0;break j}g=l&-4;u=0;p=0;while(1){e=j+364|0;D[e+(a+u|0)|0]=G[b+u|0];a=u|1;D[e+(a+F[j+360>>2]|0)|0]=G[a+b|0];a=u|2;D[e+(a+F[j+360>>2]|0)|0]=G[a+b|0];a=u|3;D[e+(a+F[j+360>>2]|0)|0]=G[a+b|0];u=u+4|0;a=F[j+360>>2];p=p+4|0;if((g|0)!=(p|0)){continue}break}}if(!f){break i}while(1){D[((a+u|0)+j|0)+364|0]=G[b+u|0];u=u+1|0;a=F[j+360>>2];k=k+1|0;if((f|0)!=(k|0)){continue}break}}c=c-l|0;b=b+l|0;a=a+l|0;F[j+360>>2]=a;if((a|0)!=128){break h}ua(j+288|0,r);F[j+360>>2]=0;g=F[j+292>>2];a=F[j+288>>2]+1024|0;g=a>>>0<1024?g+1|0:g;F[j+288>>2]=a;F[j+292>>2]=g}if(!c){break g}a=F[j+360>>2];continue}}e=j+528|0;db(j+288|0,e);mb(e);g=j+8|0;c=j+128|0;o=d+32|0;b=0;a=0;m=_-2272|0;_=m;while(1){k=m+2016|0;f=e+(b>>>3|0)|0;D[k+b|0]=G[f|0]>>>(b&6)&1;l=k;k=b|1;D[l+k|0]=G[f|0]>>>(k&7)&1;b=b+2|0;if((b|0)!=256){continue}break}while(1){k=a;a=a+1|0;s=k+(m+2016|0)|0;k:{if(!G[s|0]|k>>>0>254){break k}l=(m+2016|0)+a|0;b=D[l|0];l:{if(!b){break l}e=b<<1;f=D[s|0];b=e+f|0;if((b|0)<=15){D[s|0]=b;D[l|0]=0;break l}b=f-e|0;if((b|0)<-15){break k}D[s|0]=b;b=a;while(1){f=(m+2016|0)+b|0;if(!G[f|0]){D[f|0]=1;break l}D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break}}if(k>>>0>253){break k}b=k+2|0;p=b+(m+2016|0)|0;f=D[p|0];m:{if(!f){break m}l=f<<2;e=D[s|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break k}D[s|0]=f;while(1){f=(m+2016|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break m}break}D[f|0]=1;break m}D[s|0]=f;D[p|0]=0}if(k>>>0>252){break k}b=k+3|0;p=b+(m+2016|0)|0;f=D[p|0];n:{if(!f){break n}l=f<<3;e=D[s|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break k}D[s|0]=f;while(1){f=(m+2016|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break n}break}D[f|0]=1;break n}D[s|0]=f;D[p|0]=0}if(k>>>0>251){break k}b=k+4|0;p=b+(m+2016|0)|0;f=D[p|0];o:{if(!f){break o}l=f<<4;e=D[s|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break k}D[s|0]=f;while(1){f=(m+2016|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break o}break}D[f|0]=1;break o}D[s|0]=f;D[p|0]=0}if(k>>>0>250){break k}b=k+5|0;p=b+(m+2016|0)|0;f=D[p|0];p:{if(!f){break p}l=f<<5;e=D[s|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break k}D[s|0]=f;while(1){f=(m+2016|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break p}break}D[f|0]=1;break p}D[s|0]=f;D[p|0]=0}if(k>>>0>249){break k}b=k+6|0;l=b+(m+2016|0)|0;k=D[l|0];if(!k){break k}e=k<<6;f=D[s|0];k=e+f|0;if((k|0)>=16){k=f-e|0;if((k|0)<-15){break k}D[s|0]=k;while(1){k=(m+2016|0)+b|0;if(G[k|0]){D[k|0]=0;k=b>>>0<255;b=b+1|0;if(k){continue}break k}break}D[k|0]=1;break k}D[s|0]=k;D[l|0]=0}if((a|0)!=256){continue}break}b=0;while(1){a=m+1760|0;k=o+(b>>>3|0)|0;D[a+b|0]=G[k|0]>>>(b&6)&1;f=a;a=b|1;D[f+a|0]=G[k|0]>>>(a&7)&1;b=b+2|0;if((b|0)!=256){continue}break}a=0;while(1){k=a;a=a+1|0;o=k+(m+1760|0)|0;q:{if(!G[o|0]|k>>>0>254){break q}l=(m+1760|0)+a|0;b=D[l|0];r:{if(!b){break r}e=b<<1;f=D[o|0];b=e+f|0;if((b|0)<=15){D[o|0]=b;D[l|0]=0;break r}b=f-e|0;if((b|0)<-15){break q}D[o|0]=b;b=a;while(1){f=(m+1760|0)+b|0;if(!G[f|0]){D[f|0]=1;break r}D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break}}if(k>>>0>253){break q}b=k+2|0;p=b+(m+1760|0)|0;f=D[p|0];s:{if(!f){break s}l=f<<2;e=D[o|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break q}D[o|0]=f;while(1){f=(m+1760|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break s}break}D[f|0]=1;break s}D[o|0]=f;D[p|0]=0}if(k>>>0>252){break q}b=k+3|0;p=b+(m+1760|0)|0;f=D[p|0];t:{if(!f){break t}l=f<<3;e=D[o|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break q}D[o|0]=f;while(1){f=(m+1760|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break t}break}D[f|0]=1;break t}D[o|0]=f;D[p|0]=0}if(k>>>0>251){break q}b=k+4|0;p=b+(m+1760|0)|0;f=D[p|0];u:{if(!f){break u}l=f<<4;e=D[o|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break q}D[o|0]=f;while(1){f=(m+1760|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break u}break}D[f|0]=1;break u}D[o|0]=f;D[p|0]=0}if(k>>>0>250){break q}b=k+5|0;p=b+(m+1760|0)|0;f=D[p|0];v:{if(!f){break v}l=f<<5;e=D[o|0];f=l+e|0;if((f|0)>=16){f=e-l|0;if((f|0)<-15){break q}D[o|0]=f;while(1){f=(m+1760|0)+b|0;if(G[f|0]){D[f|0]=0;f=b>>>0<255;b=b+1|0;if(f){continue}break v}break}D[f|0]=1;break v}D[o|0]=f;D[p|0]=0}if(k>>>0>249){break q}b=k+6|0;l=b+(m+1760|0)|0;k=D[l|0];if(!k){break q}e=k<<6;f=D[o|0];k=e+f|0;if((k|0)>=16){k=f-e|0;if((k|0)<-15){break q}D[o|0]=k;while(1){k=(m+1760|0)+b|0;if(G[k|0]){D[k|0]=0;k=b>>>0<255;b=b+1|0;if(k){continue}break q}break}D[k|0]=1;break q}D[o|0]=k;D[l|0]=0}if((a|0)!=256){continue}break}r=m+480|0;Ha(r,c);s=F[c>>2];o=F[c+4>>2];p=F[c+8>>2];l=F[c+12>>2];e=F[c+16>>2];f=F[c+20>>2];k=F[c+24>>2];b=F[c+28>>2];a=F[c+36>>2];F[m+192>>2]=F[c+32>>2];F[m+196>>2]=a;F[m+184>>2]=k;F[m+188>>2]=b;F[m+176>>2]=e;F[m+180>>2]=f;F[m+168>>2]=p;F[m+172>>2]=l;F[m+160>>2]=s;F[m+164>>2]=o;s=F[c+48>>2];o=F[c+52>>2];p=F[c+56>>2];l=F[c+60>>2];a=c- -64|0;e=F[a>>2];f=F[a+4>>2];k=F[c+40>>2];b=F[c+44>>2];a=F[c+76>>2];F[m+232>>2]=F[c+72>>2];F[m+236>>2]=a;F[m+224>>2]=e;F[m+228>>2]=f;F[m+216>>2]=p;F[m+220>>2]=l;F[m+208>>2]=s;F[m+212>>2]=o;F[m+200>>2]=k;F[m+204>>2]=b;s=F[c+88>>2];o=F[c+92>>2];p=F[c+96>>2];l=F[c+100>>2];e=F[c+104>>2];f=F[c+108>>2];k=F[c+80>>2];b=F[c+84>>2];a=F[c+116>>2];F[m+272>>2]=F[c+112>>2];F[m+276>>2]=a;F[m+264>>2]=e;F[m+268>>2]=f;F[m+256>>2]=p;F[m+260>>2]=l;F[m+248>>2]=s;F[m+252>>2]=o;F[m+240>>2]=k;F[m+244>>2]=b;c=m+320|0;b=m+160|0;Sa(c,b);E=m+440|0;ha(m,c,E);J=m+360|0;H=m+400|0;ha(m+40|0,J,H);ha(m+80|0,H,E);ha(m+120|0,c,J);Ia(c,m,r);ha(b,c,E);Q=m+200|0;ha(Q,J,H);i=m+240|0;ha(i,H,E);q=m+280|0;ha(q,c,J);a=m+640|0;Ha(a,b);Ia(c,m,a);ha(b,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);a=m+800|0;Ha(a,b);Ia(c,m,a);ha(b,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);a=m+960|0;Ha(a,b);Ia(c,m,a);ha(b,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);a=m+1120|0;Ha(a,b);Ia(c,m,a);ha(b,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);a=m+1280|0;Ha(a,b);Ia(c,m,a);ha(b,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);a=m+1440|0;Ha(a,b);Ia(c,m,a);ha(b,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);Ha(m+1600|0,b);F[g+32>>2]=0;F[g+36>>2]=0;F[g+24>>2]=0;F[g+28>>2]=0;F[g+16>>2]=0;F[g+20>>2]=0;F[g+8>>2]=0;F[g+12>>2]=0;F[g>>2]=0;F[g+4>>2]=0;F[g+44>>2]=0;F[g+48>>2]=0;F[g+40>>2]=1;F[g+52>>2]=0;F[g+56>>2]=0;F[g+60>>2]=0;F[g+64>>2]=0;F[g+68>>2]=0;F[g+72>>2]=0;F[g+84>>2]=0;F[g+88>>2]=0;F[g+76>>2]=0;F[g+80>>2]=1;F[g+92>>2]=0;F[g+96>>2]=0;F[g+100>>2]=0;F[g+104>>2]=0;F[g+108>>2]=0;F[g+112>>2]=0;F[g+116>>2]=0;W=g+80|0;V=g+40|0;a=255;while(1){w:{x:{if(!(G[(m+2016|0)+a|0]|G[(m+1760|0)+a|0])){b=a-1|0;if(!(G[b+(m+1760|0)|0]?1:G[b+(m+2016|0)|0])){break x}a=b}if((a|0)<0){break w}while(1){Sa(m+320|0,g);b=a;C=D[a+(m+2016|0)|0];y:{if((C|0)>0){a=m+160|0;c=m+320|0;ha(a,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);Ia(c,a,(m+480|0)+L((C&254)>>>1|0,160)|0);break y}if((C|0)>=0){break y}n=m+160|0;h=m+320|0;ha(n,h,E);ha(Q,J,H);ha(i,H,E);ha(q,h,J);x=F[n+44>>2];y=F[n+48>>2];A=F[n+52>>2];z=F[n+56>>2];v=F[n+60>>2];I=n- -64|0;B=F[I>>2];w=F[n+68>>2];t=F[n+72>>2];r=F[n+76>>2];s=F[n+4>>2];o=F[n+8>>2];p=F[n+12>>2];l=F[n+16>>2];e=F[n+20>>2];f=F[n+24>>2];k=F[n+28>>2];c=F[n+32>>2];a=F[n+36>>2];F[h>>2]=F[n>>2]+F[n+40>>2];F[h+36>>2]=a+r;F[h+32>>2]=c+t;F[h+28>>2]=k+w;F[h+24>>2]=f+B;F[h+20>>2]=e+v;F[h+16>>2]=l+z;F[h+12>>2]=p+A;F[h+8>>2]=o+y;F[h+4>>2]=s+x;x=F[n+44>>2];y=F[n+48>>2];A=F[n+52>>2];z=F[n+56>>2];v=F[n+60>>2];B=F[I>>2];w=F[n+68>>2];t=F[n+72>>2];r=F[n>>2];s=F[n+40>>2];o=F[n+4>>2];p=F[n+8>>2];l=F[n+12>>2];e=F[n+16>>2];f=F[n+20>>2];k=F[n+24>>2];c=F[n+28>>2];a=F[n+32>>2];F[h+76>>2]=F[n+76>>2]-F[n+36>>2];F[h+72>>2]=t-a;F[h+68>>2]=w-c;u=h- -64|0;F[u>>2]=B-k;F[h+60>>2]=v-f;F[h+56>>2]=z-e;F[h+52>>2]=A-l;F[h+48>>2]=y-p;F[h+44>>2]=x-o;F[h+40>>2]=s-r;c=(m+480|0)+L((0-C&254)>>>1|0,160)|0;ha(h+80|0,h,c+40|0);a=h+40|0;ha(a,a,c);ha(h+120|0,c+120|0,n+120|0);ha(h,n+80|0,c+80|0);P=F[h+44>>2];R=F[h+84>>2];M=F[h+48>>2];K=F[h+88>>2];O=F[h+52>>2];N=F[h+92>>2];C=F[h+56>>2];I=F[h+96>>2];x=F[h+60>>2];y=F[h+100>>2];A=F[u>>2];z=F[h+104>>2];v=F[h+68>>2];B=F[h+108>>2];w=F[h+72>>2];t=F[h+112>>2];S=F[h>>2];T=F[h+4>>2];U=F[h+8>>2];n=F[h+12>>2];o=F[h+16>>2];p=F[h+20>>2];l=F[h+24>>2];e=F[h+28>>2];f=F[h+32>>2];k=F[h+36>>2];r=F[h+40>>2];s=F[h+80>>2];c=F[h+76>>2];a=F[h+116>>2];F[h+76>>2]=c+a;F[h+72>>2]=t+w;F[h+68>>2]=v+B;F[u>>2]=A+z;F[h+60>>2]=x+y;F[h+56>>2]=C+I;F[h+52>>2]=N+O;F[h+48>>2]=K+M;F[h+44>>2]=P+R;F[h+40>>2]=s+r;F[h+36>>2]=a-c;F[h+32>>2]=t-w;F[h+28>>2]=B-v;F[h+24>>2]=z-A;F[h+20>>2]=y-x;F[h+16>>2]=I-C;F[h+12>>2]=N-O;F[h+8>>2]=K-M;F[h+4>>2]=R-P;F[h>>2]=s-r;C=F[h+156>>2];I=k<<1;F[h+156>>2]=C+I;x=F[h+152>>2];y=f<<1;F[h+152>>2]=x+y;A=F[h+148>>2];z=e<<1;F[h+148>>2]=A+z;v=F[h+144>>2];B=l<<1;F[h+144>>2]=v+B;w=F[h+140>>2];t=p<<1;F[h+140>>2]=w+t;r=F[h+136>>2];s=o<<1;F[h+136>>2]=r+s;o=F[h+132>>2];p=n<<1;F[h+132>>2]=o+p;l=F[h+128>>2];e=U<<1;F[h+128>>2]=l+e;f=F[h+124>>2];k=T<<1;F[h+124>>2]=f+k;c=F[h+120>>2];a=S<<1;F[h+120>>2]=c+a;F[h+112>>2]=y-x;F[h+108>>2]=z-A;F[h+104>>2]=B-v;F[h+100>>2]=t-w;F[h+96>>2]=s-r;F[h+92>>2]=p-o;F[h+88>>2]=e-l;F[h+84>>2]=k-f;F[h+80>>2]=a-c;F[h+116>>2]=I-C}C=D[b+(m+1760|0)|0];z:{if((C|0)>0){a=m+160|0;c=m+320|0;ha(a,c,E);ha(Q,J,H);ha(i,H,E);ha(q,c,J);lb(c,a,L((C&254)>>>1|0,120)+5680|0);break z}if((C|0)>=0){break z}n=m+160|0;h=m+320|0;ha(n,h,E);ha(Q,J,H);ha(i,H,E);ha(q,h,J);x=F[n+44>>2];y=F[n+48>>2];A=F[n+52>>2];z=F[n+56>>2];v=F[n+60>>2];I=n- -64|0;B=F[I>>2];w=F[n+68>>2];t=F[n+72>>2];r=F[n+76>>2];s=F[n+4>>2];o=F[n+8>>2];p=F[n+12>>2];l=F[n+16>>2];e=F[n+20>>2];f=F[n+24>>2];k=F[n+28>>2];c=F[n+32>>2];a=F[n+36>>2];F[h>>2]=F[n>>2]+F[n+40>>2];F[h+36>>2]=a+r;F[h+32>>2]=c+t;F[h+28>>2]=k+w;F[h+24>>2]=f+B;F[h+20>>2]=e+v;F[h+16>>2]=l+z;F[h+12>>2]=p+A;F[h+8>>2]=o+y;F[h+4>>2]=s+x;x=F[n+44>>2];y=F[n+48>>2];A=F[n+52>>2];z=F[n+56>>2];v=F[n+60>>2];B=F[I>>2];w=F[n+68>>2];t=F[n+72>>2];r=F[n>>2];s=F[n+40>>2];o=F[n+4>>2];p=F[n+8>>2];l=F[n+12>>2];e=F[n+16>>2];f=F[n+20>>2];k=F[n+24>>2];c=F[n+28>>2];a=F[n+32>>2];F[h+76>>2]=F[n+76>>2]-F[n+36>>2];F[h+72>>2]=t-a;F[h+68>>2]=w-c;u=h- -64|0;F[u>>2]=B-k;F[h+60>>2]=v-f;F[h+56>>2]=z-e;F[h+52>>2]=A-l;F[h+48>>2]=y-p;F[h+44>>2]=x-o;F[h+40>>2]=s-r;c=L((0-C&254)>>>1|0,120)+5680|0;ha(h+80|0,h,c+40|0);a=h+40|0;ha(a,a,c);ha(h+120|0,c+80|0,n+120|0);S=F[n+84>>2];T=F[n+88>>2];U=F[n+92>>2];o=F[n+96>>2];p=F[n+100>>2];l=F[n+104>>2];e=F[n+108>>2];f=F[n+112>>2];k=F[n+116>>2];P=F[h+44>>2];R=F[h+84>>2];M=F[h+48>>2];K=F[h+88>>2];O=F[h+52>>2];N=F[h+92>>2];C=F[h+56>>2];I=F[h+96>>2];x=F[h+60>>2];y=F[h+100>>2];A=F[u>>2];z=F[h+104>>2];v=F[h+68>>2];B=F[h+108>>2];w=F[h+72>>2];t=F[h+112>>2];n=F[n+80>>2];r=F[h+40>>2];s=F[h+80>>2];c=F[h+76>>2];a=F[h+116>>2];F[h+76>>2]=c+a;F[h+72>>2]=t+w;F[h+68>>2]=v+B;F[u>>2]=A+z;F[h+60>>2]=x+y;F[h+56>>2]=C+I;F[h+52>>2]=N+O;F[h+48>>2]=K+M;F[h+44>>2]=P+R;F[h+40>>2]=s+r;F[h+36>>2]=a-c;F[h+32>>2]=t-w;F[h+28>>2]=B-v;F[h+24>>2]=z-A;F[h+20>>2]=y-x;F[h+16>>2]=I-C;F[h+12>>2]=N-O;F[h+8>>2]=K-M;F[h+4>>2]=R-P;F[h>>2]=s-r;C=F[h+156>>2];I=k<<1;F[h+156>>2]=C+I;x=F[h+152>>2];y=f<<1;F[h+152>>2]=x+y;A=F[h+148>>2];z=e<<1;F[h+148>>2]=A+z;v=F[h+144>>2];B=l<<1;F[h+144>>2]=v+B;w=F[h+140>>2];t=p<<1;F[h+140>>2]=w+t;r=F[h+136>>2];s=o<<1;F[h+136>>2]=r+s;o=F[h+132>>2];p=U<<1;F[h+132>>2]=o+p;l=F[h+128>>2];e=T<<1;F[h+128>>2]=l+e;f=F[h+124>>2];k=S<<1;F[h+124>>2]=f+k;c=F[h+120>>2];a=n<<1;F[h+120>>2]=c+a;F[h+112>>2]=y-x;F[h+108>>2]=z-A;F[h+104>>2]=B-v;F[h+100>>2]=t-w;F[h+96>>2]=s-r;F[h+92>>2]=p-o;F[h+88>>2]=e-l;F[h+84>>2]=k-f;F[h+80>>2]=a-c;F[h+116>>2]=I-C}ha(g,m+320|0,E);ha(V,J,H);ha(W,H,E);a=b-1|0;if((b|0)>0){continue}break}break w}a=a-2|0;if(b){continue}}break}_=m+2272|0;c=j+688|0;nb(c,j+88|0);b=j+640|0;ha(b,g,c);a=j+592|0;ha(a,j+48|0,c);Ga(j+496|0,a);Ga(j+736|0,b);u=!(G[d+1|0]^G[j+497|0]|G[d|0]^G[j+496|0]|G[d+2|0]^G[j+498|0]|G[d+3|0]^G[j+499|0]|G[d+4|0]^G[j+500|0]|G[d+5|0]^G[j+501|0]|G[d+6|0]^G[j+502|0]|G[d+7|0]^G[j+503|0]|G[d+8|0]^G[j+504|0]|G[d+9|0]^G[j+505|0]|G[d+10|0]^G[j+506|0]|G[d+11|0]^G[j+507|0]|G[d+12|0]^G[j+508|0]|G[d+13|0]^G[j+509|0]|G[d+14|0]^G[j+510|0]|G[d+15|0]^G[j+511|0]|G[d+16|0]^G[j+512|0]|G[d+17|0]^G[j+513|0]|G[d+18|0]^G[j+514|0]|G[d+19|0]^G[j+515|0]|G[d+20|0]^G[j+516|0]|G[d+21|0]^G[j+517|0]|G[d+22|0]^G[j+518|0]|G[d+23|0]^G[j+519|0]|G[d+24|0]^G[j+520|0]|G[d+25|0]^G[j+521|0]|G[d+26|0]^G[j+522|0]|G[d+27|0]^G[j+523|0]|G[d+28|0]^G[j+524|0]|G[d+29|0]^G[j+525|0]|G[d+30|0]^G[j+526|0]|G[d+31|0]^(G[j+527|0]^G[j+736|0]<<7&128))}_=j+768|0;return(u|0)!=0}function mb(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,E=0,F=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,aa=0,ba=0,ca=0;c=G[a+48|0];b=c>>>24|0;n=G[a+47|0];e=n|c<<8;g=G[a+49|0];h=g;d=h>>>16|0;h=h<<16;d=b|d;c=e|h;H=((d&3)<<30|c>>>2)&2097151;c=se(H,0,136657,0);d=G[a+27|0];b=d>>>24|0;f=G[a+26|0];h=f|d<<8;e=c;Y=G[a+28|0];d=Y;c=d>>>16|0;d=d<<16;c=b|c;b=d|h;c=((c&3)<<30|b>>>2)&2097151;d=e+c|0;b=$;h=d;d=c>>>0>d>>>0?b+1|0:b;c=G[a+50|0];b=c>>>24|0;g=g|c<<8;e=G[a+51|0];c=e>>>16|0;i=g|e<<16;g=b|c;c=h;e=G[a+52|0];b=e>>>8|0;h=e<<24;g=b|g;b=h|i;I=((g&127)<<25|b>>>7)&2097151;b=se(I,0,-997805,-1);h=c+b|0;c=$+d|0;c=b>>>0>h>>>0?c+1|0:c;d=c;b=G[a+53|0];c=b>>>24|0;g=e|b<<8;e=G[a+54|0];b=e>>>16|0;i=g|e<<16;g=b|c;b=h;e=G[a+55|0];c=e>>>8|0;h=e<<24;g=c|g;c=h|i;J=((g&15)<<28|c>>>4)&2097151;c=se(J,0,654183,0);h=b+c|0;b=$+d|0;b=c>>>0>h>>>0?b+1|0:b;c=h;h=b;d=G[a+56|0];b=d>>>24|0;i=e|d<<8;j=c;g=G[a+57|0];e=g;c=e>>>16|0;e=e<<16;d=b|c;c=e|i;K=((d&1)<<31|c>>>1)&2097151;b=se(K,0,470296,0);d=j+b|0;c=$+h|0;i=d;d=b>>>0>d>>>0?c+1|0:c;b=G[a+58|0];c=b>>>24|0;h=g|b<<8;b=c;e=h;h=G[a+59|0];c=h>>>16|0;g=e|h<<16;e=b|c;r=G[a+60|0];h=r;c=h>>>8|0;h=h<<24;e=c|e;c=h|g;L=((e&63)<<26|c>>>6)&2097151;c=se(L,0,666643,0);h=c+i|0;b=$+d|0;b=c>>>0>h>>>0?b+1|0:b;j=h;i=b;k=se(H,o,-997805,-1);b=G[a+24|0];d=b>>>24|0;e=G[a+23|0];g=e|b<<8;b=G[a+25|0];c=b>>>16|0;g=g|b<<16;d=c|d|f>>>8;b=f<<24|g;c=((d&31)<<27|b>>>5)&2097151;d=c+k|0;b=$;b=c>>>0>d>>>0?b+1|0:b;c=d;d=se(I,o,654183,0);f=c+d|0;c=$+b|0;c=d>>>0>f>>>0?c+1|0:c;b=se(J,o,470296,0);d=b+f|0;c=$+c|0;c=b>>>0>d>>>0?c+1|0:c;b=se(K,o,666643,0);f=b+d|0;d=$+c|0;g=f;f=b>>>0>f>>>0?d+1|0:d;b=se(H,o,654183,0);c=e<<16&2031616|(G[a+21|0]|G[a+22|0]<<8);d=b+c|0;b=$;b=c>>>0>d>>>0?b+1|0:b;c=se(I,o,470296,0);d=c+d|0;b=$+b|0;b=c>>>0>d>>>0?b+1|0:b;c=se(J,o,666643,0);e=c+d|0;d=$+b|0;l=e;d=c>>>0>e>>>0?d+1|0:d;e=d;s=d-((l>>>0<4293918720)-1|0)|0;b=s>>>21|0;E=l- -1048576|0;d=(s&2097151)<<11|E>>>21;g=d+g|0;c=b+f|0;c=d>>>0>g>>>0?c+1|0:c;p=c;Z=h- -1048576|0;f=i-((h>>>0<4293918720)-1|0)|0;h=f;k=c-((g>>>0<4293918720)-1|0)|0;q=g- -1048576|0;c=q;c=(k&2097151)<<11|c>>>21;j=c+j|0;d=(k>>21)+i|0;d=c>>>0>j>>>0?d+1|0:d;c=j;b=Z&-2097152;u=c-b|0;w=d-((b>>>0>c>>>0)+f|0)|0;b=G[a+61|0];c=b>>>24|0;f=r|b<<8;d=G[a+62|0];b=d>>>16|0;f=f|d<<16;d=b|c;b=G[a+63|0];c=b>>>8|0;b=b<<24|f;d=c|d;c=d>>>3|0;M=(d&7)<<29|b>>>3;A=c;b=se(M,c,-683901,-1);d=G[a+44|0];c=d;c=c<<16&2031616|(G[a+42|0]|G[a+43|0]<<8);f=b+c|0;b=$;b=c>>>0>f>>>0?b+1|0:b;r=b;j=b-((f>>>0<4293918720)-1|0)|0;t=f- -1048576|0;b=t;x=(j&2097151)<<11|b>>>21;i=j>>21;b=G[a+45|0];c=b>>>24|0;m=d|b<<8;b=G[a+46|0];d=b>>>16|0;m=m|b<<16;d=c|d|n>>>8;b=n<<24|m;b=((d&31)<<27|b>>>5)&2097151;d=b+x|0;c=i;Q=d;c=b>>>0>d>>>0?c+1|0:c;y=c;c=se(d,c,-683901,-1);d=c+u|0;b=$+w|0;b=c>>>0>d>>>0?b+1|0:b;c=d;_=c- -1048576|0;i=b-((c>>>0<4293918720)-1|0)|0;N=i;d=_&-2097152;W=c-d|0;X=b-((c>>>0>>0)+i|0)|0;c=se(Q,y,136657,0);b=q&-2097152;d=c+(g-b|0)|0;b=$+(p-((b>>>0>g>>>0)+k|0)|0)|0;q=d;k=c>>>0>d>>>0?b+1|0:b;b=t&-2097152;t=f-b|0;n=r-((b>>>0>f>>>0)+j|0)|0;c=se(L,o,-683901,-1);d=G[a+40|0];b=d>>>24|0;g=G[a+39|0];f=g|d<<8;i=c;c=G[a+41|0];d=c>>>16|0;c=c<<16;d=b|d;b=c|f;c=d>>>3|0;b=(d&7)<<29|b>>>3;d=i+b|0;c=c+$|0;c=b>>>0>d>>>0?c+1|0:c;b=d;d=se(M,A,136657,0);f=b+d|0;b=$+c|0;p=f;f=d>>>0>f>>>0?b+1|0:b;r=se(K,o,-683901,-1);b=G[a+37|0];c=b>>>24|0;B=G[a+36|0];d=B|b<<8;b=c;i=d;d=G[a+38|0];c=d>>>16|0;i=i|d<<16;d=b|c|g>>>8;b=g<<24|i;b=((d&63)<<26|b>>>6)&2097151;c=b+r|0;d=$;d=b>>>0>c>>>0?d+1|0:d;b=c;c=se(L,o,136657,0);g=b+c|0;b=$+d|0;b=c>>>0>g>>>0?b+1|0:b;d=se(M,A,-997805,-1);g=d+g|0;c=$+b|0;j=g;c=d>>>0>g>>>0?c+1|0:c;v=c;u=c-((g>>>0<4293918720)-1|0)|0;T=g- -1048576|0;c=T;c=(u&2097151)<<11|c>>>21;d=c+p|0;b=(u>>21)+f|0;i=d;b=c>>>0>d>>>0?b+1|0:b;w=b;r=b-((d>>>0<4293918720)-1|0)|0;b=r>>21;C=d- -1048576|0;d=(r&2097151)<<11|C>>>21;f=d+t|0;c=b+n|0;R=f;c=d>>>0>f>>>0?c+1|0:c;F=c;b=se(f,c,-683901,-1);d=b+q|0;c=$+k|0;S=d;t=b>>>0>d>>>0?c+1|0:c;k=l;l=e;c=se(H,o,470296,0);e=G[a+19|0];b=e>>>24|0;d=G[a+18|0];f=d|e<<8;g=c;e=G[a+20|0];c=e>>>16|0;e=e<<16;p=b|c;b=e|f;e=(p&7)<<29|b>>>3;f=g+e|0;b=$+(p>>>3|0)|0;z=f;e=e>>>0>f>>>0?b+1|0:b;n=se(H,o,666643,0);c=G[a+16|0];b=c>>>24|0;x=G[a+15|0];g=x|c<<8;f=G[a+17|0];c=f>>>16|0;g=g|f<<16;f=b|c;c=d<<24;d=d>>>8|f;b=c|g;b=((d&63)<<26|b>>>6)&2097151;c=b+n|0;d=$;g=c;d=b>>>0>c>>>0?d+1|0:d;m=d;q=d-((c>>>0<4293918720)-1|0)|0;b=q>>>21|0;U=c- -1048576|0;d=(q&2097151)<<11|U>>>21;f=d+z|0;c=b+e|0;c=d>>>0>f>>>0?c+1|0:c;d=se(I,o,666643,0);e=d+f|0;b=$+c|0;f=e;b=d>>>0>e>>>0?b+1|0:b;n=b;p=b-((e>>>0<4293918720)-1|0)|0;z=e- -1048576|0;b=C&-2097152;d=w-((b>>>0>i>>>0)+r|0)|0;O=i-b|0;C=d;b=(p&2097151)<<11|z>>>21;e=b+k|0;c=(p>>>21|0)+l|0;c=b>>>0>e>>>0?c+1|0:c;i=e;b=E&-2097152;e=se(Q,y,-997805,-1);l=(i-b|0)+e|0;b=$+(c-((s&8191)+(b>>>0>i>>>0)|0)|0)|0;b=e>>>0>l>>>0?b+1|0:b;e=se(R,F,136657,0);i=e+l|0;c=$+b|0;c=e>>>0>i>>>0?c+1|0:c;b=se(O,d,-683901,-1);e=b+i|0;d=$+c|0;d=b>>>0>e>>>0?d+1|0:d;r=d;k=d-((e>>>0<4293918720)-1|0)|0;c=k>>21;s=e- -1048576|0;b=(k&2097151)<<11|s>>>21;d=b+S|0;c=c+t|0;c=b>>>0>d>>>0?c+1|0:c;b=d;l=c;i=c-((b>>>0<4293918720)-1|0)|0;c=i>>21;w=b- -1048576|0;t=(i&2097151)<<11|w>>>21;E=t+W|0;d=c+X|0;aa=E;t=t>>>0>E>>>0?d+1|0:d;c=w&-2097152;ba=b-c|0;ca=l-((b>>>0>>0)+i|0)|0;b=s&-2097152;S=e-b|0;E=r-((b>>>0>e>>>0)+k|0)|0;c=se(Q,y,654183,0);b=z&-2097152;d=c+(f-b|0)|0;b=$+(n-((b>>>0>f>>>0)+p|0)|0)|0;b=c>>>0>d>>>0?b+1|0:b;c=se(R,F,-997805,-1);e=c+d|0;d=$+b|0;d=c>>>0>e>>>0?d+1|0:d;b=se(O,C,136657,0);e=b+e|0;c=$+d|0;z=e;i=b>>>0>e>>>0?c+1|0:c;b=T&-2097152;s=j-b|0;u=v-((b>>>0>j>>>0)+u|0)|0;b=se(J,o,-683901,-1);d=G[a+35|0];c=d>>>24|0;f=G[a+34|0];e=f|d<<8;d=b;c=B>>>16|c;b=B<<16|e;b=((c&1)<<31|b>>>1)&2097151;d=d+b|0;c=$;c=b>>>0>d>>>0?c+1|0:c;b=se(K,o,136657,0);e=b+d|0;d=$+c|0;d=b>>>0>e>>>0?d+1|0:d;b=se(L,o,-997805,-1);e=b+e|0;c=$+d|0;c=b>>>0>e>>>0?c+1|0:c;d=se(M,A,654183,0);e=d+e|0;b=$+c|0;n=e;e=d>>>0>e>>>0?b+1|0:b;k=se(I,o,-683901,-1);b=G[a+32|0];d=b>>>24|0;p=G[a+31|0];j=p|b<<8;b=G[a+33|0];c=b>>>16|0;j=j|b<<16;d=c|d|f>>>8;b=f<<24|j;c=((d&15)<<28|b>>>4)&2097151;d=c+k|0;b=$;b=c>>>0>d>>>0?b+1|0:b;c=d;d=se(J,o,136657,0);f=c+d|0;c=$+b|0;c=d>>>0>f>>>0?c+1|0:c;b=se(K,o,-997805,-1);d=b+f|0;c=$+c|0;c=b>>>0>d>>>0?c+1|0:c;b=se(L,o,654183,0);f=b+d|0;d=$+c|0;d=b>>>0>f>>>0?d+1|0:d;c=se(M,A,470296,0);f=c+f|0;b=$+d|0;b=c>>>0>f>>>0?b+1|0:b;r=b;k=b-((f>>>0<4293918720)-1|0)|0;w=f- -1048576|0;b=w;b=(k&2097151)<<11|b>>>21;j=b+n|0;c=(k>>21)+e|0;e=j;c=b>>>0>e>>>0?c+1|0:c;j=c;c=c-((e>>>0<4293918720)-1|0)|0;d=c>>21;l=e- -1048576|0;n=(c&2097151)<<11|l>>>21;v=n+s|0;b=d+u|0;V=v;b=n>>>0>v>>>0?b+1|0:b;s=b;d=se(v,b,-683901,-1);n=d+z|0;b=$+i|0;b=d>>>0>n>>>0?b+1|0:b;i=b;b=l&-2097152;j=j-((b>>>0>e>>>0)+c|0)|0;P=e-b|0;B=j;b=se(Q,y,470296,0);c=U&-2097152;d=b+(g-c|0)|0;c=$+(m-((q&2047)+(c>>>0>g>>>0)|0)|0)|0;c=b>>>0>d>>>0?c+1|0:c;b=d;d=se(R,F,654183,0);e=b+d|0;b=$+c|0;b=d>>>0>e>>>0?b+1|0:b;c=se(O,C,-997805,-1);d=c+e|0;b=$+b|0;b=c>>>0>d>>>0?b+1|0:b;c=se(v,s,136657,0);e=c+d|0;d=$+b|0;d=c>>>0>e>>>0?d+1|0:d;b=se(P,j,-683901,-1);e=b+e|0;c=$+d|0;c=b>>>0>e>>>0?c+1|0:c;l=c;j=c-((e>>>0<4293918720)-1|0)|0;c=j>>21;q=e- -1048576|0;b=(j&2097151)<<11|q>>>21;g=b+n|0;d=c+i|0;d=b>>>0>g>>>0?d+1|0:d;b=g;i=d;g=d-((b>>>0<4293918720)-1|0)|0;d=b- -1048576|0;c=(g>>21)+E|0;n=(g&2097151)<<11|d>>>21;m=n+S|0;W=m;n=n>>>0>m>>>0?c+1|0:c;c=d&-2097152;X=b-c|0;S=i-((b>>>0>>0)+g|0)|0;b=q&-2097152;z=e-b|0;u=l-((b>>>0>e>>>0)+j|0)|0;c=se(Q,y,666643,0);d=G[a+14|0];b=d>>>24|0;i=G[a+13|0];e=i|d<<8;d=x>>>16|b;b=x<<16|e;b=((d&1)<<31|b>>>1)&2097151;d=b+c|0;c=$;c=b>>>0>d>>>0?c+1|0:c;b=d;d=se(R,F,470296,0);e=b+d|0;b=$+c|0;b=d>>>0>e>>>0?b+1|0:b;c=se(O,C,654183,0);d=c+e|0;b=$+b|0;m=d;g=c>>>0>d>>>0?b+1|0:b;b=w&-2097152;q=f-b|0;l=r-((b>>>0>f>>>0)+k|0)|0;j=se(H,o,-683901,-1);b=G[a+29|0];c=b>>>24|0;d=Y|b<<8;b=c;e=d;d=G[a+30|0];c=d>>>16|0;e=e|d<<16;d=b|c|p>>>8;b=p<<24|e;b=((d&127)<<25|b>>>7)&2097151;c=b+j|0;d=$;d=b>>>0>c>>>0?d+1|0:d;b=c;c=se(I,o,136657,0);e=b+c|0;b=$+d|0;b=c>>>0>e>>>0?b+1|0:b;d=se(J,o,-997805,-1);e=d+e|0;c=$+b|0;c=d>>>0>e>>>0?c+1|0:c;b=se(K,o,654183,0);d=b+e|0;c=$+c|0;c=b>>>0>d>>>0?c+1|0:c;b=d;d=se(L,o,470296,0);e=b+d|0;b=$+c|0;b=d>>>0>e>>>0?b+1|0:b;c=se(M,A,666643,0);e=c+e|0;d=$+b|0;d=c>>>0>e>>>0?d+1|0:d;c=h>>21;h=(h&2097151)<<11|Z>>>21;e=h+e|0;b=c+d|0;b=e>>>0>>0?b+1|0:b;r=b;k=b-((e>>>0<4293918720)-1|0)|0;w=e- -1048576|0;b=w;d=(k&2097151)<<11|b>>>21;h=d+q|0;b=(k>>21)+l|0;A=h;b=d>>>0>h>>>0?b+1|0:b;v=b;b=se(h,b,-683901,-1);c=b+m|0;d=$+g|0;d=b>>>0>c>>>0?d+1|0:d;b=c;c=se(V,s,-997805,-1);h=b+c|0;b=$+d|0;b=c>>>0>h>>>0?b+1|0:b;d=se(P,B,136657,0);h=d+h|0;c=$+b|0;p=h;h=d>>>0>h>>>0?c+1|0:c;c=se(R,F,666643,0);b=G[a+11|0];d=b>>>24|0;l=G[a+10|0];g=l|b<<8;f=G[a+12|0];b=f>>>16|0;f=g|f<<16;g=c;c=b|d|i>>>8;b=((c&15)<<28|(i<<24|f)>>>4)&2097151;d=g+b|0;c=$;c=b>>>0>d>>>0?c+1|0:c;b=d;d=se(O,C,470296,0);f=b+d|0;b=$+c|0;b=d>>>0>f>>>0?b+1|0:b;c=se(A,v,136657,0);d=c+f|0;b=$+b|0;b=c>>>0>d>>>0?b+1|0:b;c=se(V,s,654183,0);f=c+d|0;d=$+b|0;d=c>>>0>f>>>0?d+1|0:d;b=se(P,B,-997805,-1);f=b+f|0;c=$+d|0;x=f;c=b>>>0>f>>>0?c+1|0:c;j=c;b=f;i=c-((b>>>0<4293918720)-1|0)|0;m=b- -1048576|0;b=m;c=(i&2097151)<<11|b>>>21;f=c+p|0;b=(i>>21)+h|0;b=c>>>0>f>>>0?b+1|0:b;h=f;q=f- -1048576|0;c=q;g=b-((f>>>0<4293918720)-1|0)|0;d=g>>21;f=(g&2097151)<<11|c>>>21;p=f+z|0;c=d+u|0;F=p;p=f>>>0>p>>>0?c+1|0:c;f=h;d=b;c=w&-2097152;b=e-c|0;e=r-((c>>>0>e>>>0)+k|0)|0;h=(N&2097151)<<11|_>>>21;k=h+b|0;b=(N>>21)+e|0;b=h>>>0>k>>>0?b+1|0:b;h=k;r=b;k=b-((h>>>0<4293918720)-1|0)|0;w=h- -1048576|0;b=w;y=(k&2097151)<<11|b>>>21;c=k>>21;u=c;c=se(y,c,-683901,-1);e=c+f|0;b=$+d|0;b=c>>>0>e>>>0?b+1|0:b;d=e;c=q&-2097152;E=d-c|0;T=b-((c>>>0>d>>>0)+g|0)|0;c=se(y,u,136657,0);d=c+x|0;b=$+j|0;b=c>>>0>d>>>0?b+1|0:b;c=m&-2097152;z=d-c|0;N=b-((c>>>0>d>>>0)+i|0)|0;i=se(O,C,666643,0);c=G[a+8|0];b=c>>>24|0;e=G[a+7|0];f=e|c<<8;c=G[a+9|0];d=c>>>16|0;f=f|c<<16;c=b|d|l>>>8;c=((c&127)<<25|(l<<24|f)>>>7)&2097151;d=c+i|0;b=$;b=c>>>0>d>>>0?b+1|0:b;c=d;d=se(A,v,-997805,-1);f=c+d|0;c=$+b|0;c=d>>>0>f>>>0?c+1|0:c;b=se(V,s,470296,0);f=b+f|0;d=$+c|0;d=b>>>0>f>>>0?d+1|0:d;c=se(P,B,654183,0);f=c+f|0;b=$+d|0;j=f;d=c>>>0>f>>>0?b+1|0:b;b=se(A,v,654183,0);f=G[a+6|0];c=f>>>24|0;i=G[a+5|0];f=i|f<<8;g=b;b=e>>>16|0;e=e<<16;c=b|c;b=e|f;b=((c&3)<<30|b>>>2)&2097151;e=g+b|0;c=$;c=b>>>0>e>>>0?c+1|0:c;b=e;e=se(V,s,666643,0);f=b+e|0;b=$+c|0;b=e>>>0>f>>>0?b+1|0:b;e=se(P,B,470296,0);f=e+f|0;c=$+b|0;x=f;c=e>>>0>f>>>0?c+1|0:c;g=c;b=f;f=c-((b>>>0<4293918720)-1|0)|0;m=b- -1048576|0;c=m;c=(f&2097151)<<11|c>>>21;e=c+j|0;b=(f>>21)+d|0;q=e;b=c>>>0>e>>>0?b+1|0:b;d=b;b=e;e=d-((b>>>0<4293918720)-1|0)|0;j=b- -1048576|0;c=j;l=(e&2097151)<<11|c>>>21;s=l+z|0;c=(e>>21)+N|0;C=s;l=l>>>0>s>>>0?c+1|0:c;b=se(y,u,-997805,-1);c=b+q|0;d=$+d|0;d=b>>>0>c>>>0?d+1|0:d;b=j&-2097152;U=c-b|0;z=d-((b>>>0>c>>>0)+e|0)|0;b=se(y,u,654183,0);d=b+x|0;c=$+g|0;c=b>>>0>d>>>0?c+1|0:c;b=m&-2097152;s=d-b|0;N=c-((b>>>0>d>>>0)+f|0)|0;j=se(A,v,470296,0);b=G[a+3|0];c=b>>>24|0;f=G[a+2|0];e=f|b<<8;d=G[a+4|0];b=d>>>16|0;e=e|d<<16;c=b|c|i>>>8;b=((c&31)<<27|(i<<24|e)>>>5)&2097151;c=b+j|0;d=$;d=b>>>0>c>>>0?d+1|0:d;b=c;c=se(P,B,666643,0);e=b+c|0;b=$+d|0;g=e;e=c>>>0>e>>>0?b+1|0:b;b=se(A,v,666643,0);c=f<<16&2031616|(G[a|0]|G[a+1|0]<<8);d=b+c|0;b=$;b=c>>>0>d>>>0?b+1|0:b;j=b;i=b-((d>>>0<4293918720)-1|0)|0;x=d- -1048576|0;b=x;f=(i&2097151)<<11|b>>>21;g=f+g|0;b=(i>>21)+e|0;m=g;b=f>>>0>g>>>0?b+1|0:b;g=b;b=m;f=g-((b>>>0<4293918720)-1|0)|0;q=b- -1048576|0;b=q;e=(f&2097151)<<11|b>>>21;v=e+s|0;b=(f>>21)+N|0;b=e>>>0>v>>>0?b+1|0:b;e=b;b=se(y,u,470296,0);m=b+m|0;c=$+g|0;c=b>>>0>m>>>0?c+1|0:c;g=q&-2097152;b=m-g|0;f=c-((g>>>0>m>>>0)+f|0)|0;m=b;c=se(y,u,666643,0);b=x&-2097152;g=c+(d-b|0)|0;b=$+(j-((b>>>0>d>>>0)+i|0)|0)|0;i=g;d=g;b=c>>>0>d>>>0?b+1|0:b;c=b>>21;b=(b&2097151)<<11|d>>>21;d=m+b|0;c=c+f|0;c=b>>>0>d>>>0?c+1|0:c;g=d;b=c>>21;c=(c&2097151)<<11|d>>>21;d=c+v|0;b=b+e|0;b=c>>>0>d>>>0?b+1|0:b;f=d;c=b>>21;b=(b&2097151)<<11|d>>>21;e=b+U|0;d=c+z|0;B=e;c=e;d=b>>>0>c>>>0?d+1|0:d;b=d>>21;d=(d&2097151)<<11|c>>>21;e=d+C|0;c=b+l|0;v=e;b=e;c=d>>>0>b>>>0?c+1|0:c;d=c>>21;c=(c&2097151)<<11|b>>>21;e=c+E|0;b=d+T|0;u=e;d=e;b=c>>>0>d>>>0?b+1|0:b;c=b>>21;b=(b&2097151)<<11|d>>>21;d=b+F|0;c=c+p|0;c=b>>>0>d>>>0?c+1|0:c;x=d;b=c>>21;c=(c&2097151)<<11|d>>>21;d=c+X|0;b=b+S|0;b=c>>>0>d>>>0?b+1|0:b;m=d;c=b>>21;b=(b&2097151)<<11|d>>>21;e=b+W|0;d=c+n|0;q=e;c=e;d=b>>>0>c>>>0?d+1|0:d;b=d>>21;d=(d&2097151)<<11|c>>>21;e=d+ba|0;c=b+ca|0;n=e;b=e;c=d>>>0>b>>>0?c+1|0:c;d=c>>21;c=(c&2097151)<<11|b>>>21;e=c+aa|0;b=d+t|0;p=e;d=e;b=c>>>0>d>>>0?b+1|0:b;c=b>>21;e=(b&2097151)<<11|d>>>21;b=w&-2097152;d=h-b|0;e=e+d|0;b=(r-((b>>>0>h>>>0)+k|0)|0)+c|0;r=e;c=e;b=d>>>0>c>>>0?b+1|0:b;t=(b&2097151)<<11|c>>>21;d=b>>21;j=d;c=i&2097151;d=se(t,d,666643,0)+c|0;b=$;i=d;b=c>>>0>d>>>0?b+1|0:b;h=b;D[a|0]=d;D[a+1|0]=(b&255)<<24|d>>>8;b=g&2097151;d=se(t,j,470296,0)+b|0;c=$;c=b>>>0>d>>>0?c+1|0:c;e=(h&2097151)<<11|i>>>21;g=e+d|0;b=(h>>21)+c|0;b=e>>>0>g>>>0?b+1|0:b;e=g;d=e;D[a+4|0]=(b&2047)<<21|d>>>11;c=b;D[a+3|0]=(b&7)<<29|d>>>3;d=f&2097151;f=se(t,j,654183,0)+d|0;b=$;b=d>>>0>f>>>0?b+1|0:b;d=f;f=(c&2097151)<<11|e>>>21;g=d+f|0;c=(c>>21)+b|0;c=f>>>0>g>>>0?c+1|0:c;b=c;D[a+6|0]=(b&63)<<26|g>>>6;f=0;k=e&2097151;c=k;D[a+2|0]=((h&65535)<<16|i>>>16)&31|c<<5;d=B&2097151;h=se(t,j,-997805,-1)+d|0;c=$;c=d>>>0>h>>>0?c+1|0:c;d=h;h=(b&2097151)<<11|g>>>21;e=d+h|0;b=(b>>21)+c|0;i=e;c=e;b=c>>>0>>0?b+1|0:b;D[a+9|0]=(b&511)<<23|c>>>9;D[a+8|0]=(b&1)<<31|c>>>1;e=0;l=g&2097151;d=l;D[a+5|0]=(f&524287)<<13|k>>>19|d<<2;c=v&2097151;h=se(t,j,136657,0)+c|0;d=$;d=c>>>0>h>>>0?d+1|0:d;c=b;b=b>>21;c=(c&2097151)<<11|i>>>21;h=c+h|0;b=b+d|0;b=c>>>0>h>>>0?b+1|0:b;f=h;c=f;D[a+12|0]=(b&4095)<<20|c>>>12;D[a+11|0]=(b&15)<<28|c>>>4;h=0;g=i&2097151;d=g;D[a+7|0]=(e&16383)<<18|l>>>14|d<<7;d=u&2097151;e=se(t,j,-683901,-1)+d|0;c=$;c=d>>>0>e>>>0?c+1|0:c;d=b;b=b>>21;d=(d&2097151)<<11|f>>>21;e=d+e|0;c=b+c|0;c=d>>>0>e>>>0?c+1|0:c;b=e;D[a+14|0]=(c&127)<<25|b>>>7;f=f&2097151;D[a+10|0]=(h&131071)<<15|g>>>17|f<<4;b=c;c=b>>21;h=(b&2097151)<<11|e>>>21;g=h+(x&2097151)|0;d=0;b=c+d|0;b=h>>>0>g>>>0?b+1|0:b;c=g;D[a+17|0]=(b&1023)<<22|c>>>10;D[a+16|0]=(b&3)<<30|c>>>2;i=e&2097151;e=i;D[a+13|0]=(d&1048575)<<12|f>>>20|e<<1;c=b>>21;b=(b&2097151)<<11|g>>>21;e=b+(m&2097151)|0;h=0;d=c+h|0;d=b>>>0>e>>>0?d+1|0:d;f=e;b=e;D[a+20|0]=(d&8191)<<19|b>>>13;D[a+19|0]=(d&31)<<27|b>>>5;g=g&2097151;c=g;D[a+15|0]=(h&32767)<<17|i>>>15|c<<6;h=(d&2097151)<<11|b>>>21;i=h+(q&2097151)|0;e=0;b=e+(d>>21)|0;b=h>>>0>i>>>0?b+1|0:b;h=b;D[a+21|0]=i;b=f;D[a+18|0]=(e&262143)<<14|c>>>18|b<<3;c=i;D[a+22|0]=(h&255)<<24|c>>>8;c=(h&2097151)<<11|c>>>21;e=c+(n&2097151)|0;b=h>>21;b=c>>>0>e>>>0?b+1|0:b;g=e;c=e;D[a+25|0]=(b&2047)<<21|c>>>11;d=c;D[a+24|0]=(b&7)<<29|c>>>3;c=b>>21;b=(b&2097151)<<11|d>>>21;f=b+(p&2097151)|0;d=b>>>0>f>>>0?c+1|0:c;b=f;D[a+27|0]=(d&63)<<26|b>>>6;e=0;g=g&2097151;b=g;D[a+23|0]=((h&65535)<<16|i>>>16)&31|b<<5;c=d>>21;b=(d&2097151)<<11|f>>>21;d=b+(r&2097151)|0;c=b>>>0>d>>>0?c+1|0:c;b=d;D[a+31|0]=(c&131071)<<15|b>>>17;D[a+30|0]=(c&511)<<23|b>>>9;D[a+29|0]=(c&1)<<31|b>>>1;b=0;f=f&2097151;D[a+26|0]=(e&524287)<<13|g>>>19|f<<2;D[a+28|0]=(b&16383)<<18|f>>>14|d<<7}function Wd(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;k=_-160|0;_=k;l=-1;if(!(e>>>0<8|g>>>0>i>>>0)){i=F[a+4>>2];j=F[a+8>>2];a=k+80|0;Aa(b,c,0,0,i,j,a,80);b=F[k+108>>2];F[k+24>>2]=F[k+104>>2];F[k+28>>2]=b;b=F[k+100>>2];F[k+16>>2]=F[k+96>>2];F[k+20>>2]=b;b=F[k+92>>2];F[k+8>>2]=F[k+88>>2];F[k+12>>2]=b;b=F[k+124>>2];F[k+40>>2]=F[k+120>>2];F[k+44>>2]=b;b=F[k+132>>2];F[k+48>>2]=F[k+128>>2];F[k+52>>2]=b;b=F[k+140>>2];F[k+56>>2]=F[k+136>>2];F[k+60>>2]=b;b=F[k+156>>2];F[k+72>>2]=F[k+152>>2];F[k+76>>2]=b;b=F[k+84>>2];F[k>>2]=F[k+80>>2];F[k+4>>2]=b;b=F[k+116>>2];F[k+32>>2]=F[k+112>>2];F[k+36>>2]=b;b=F[k+148>>2];F[k+64>>2]=F[k+144>>2];F[k+68>>2]=b;ia(a,80);ka(k+32|0,32,d,e-8|0,a);if(Ka((d+e|0)-8|0,a,8)){b=_-272|0;_=b;Hb(k,b+32|0);a=k- -64|0;c=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);F[b+16>>2]=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);F[b+20>>2]=c;c=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);F[b+24>>2]=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);F[b+28>>2]=c;if(g){c=0;while(1){d=c+f|0;a=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[b>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[b+4>>2]=a;a=G[d+12|0]|G[d+13|0]<<8|(G[d+14|0]<<16|G[d+15|0]<<24);F[b+8>>2]=G[d+8|0]|G[d+9|0]<<8|(G[d+10|0]<<16|G[d+11|0]<<24);F[b+12>>2]=a;a=_-16|0;_=a;n=G[d+15|0];o=G[d+14|0];p=G[d+13|0];q=G[d+12|0];s=G[d+11|0];r=G[d+10|0];t=G[d+9|0];u=G[d+8|0];m=G[d+6|0];v=G[d+5|0];w=G[d+4|0];x=G[d+3|0];y=G[d+2|0];z=G[d+1|0];A=G[d|0];e=F[b+256>>2];i=F[b+268>>2];l=F[b+264>>2];j=F[b+240>>2];B=G[d+7|0];d=F[b+260>>2];D[a+12|0]=j^G[((B^d)&255)+3392|0];D[a+8|0]=G[((r^l>>>8)&255)+3392|0]^j>>>8;D[a+4|0]=G[((p^i>>>16)&255)+3392|0]^j>>>16;D[a|0]=G[(A^e>>>24)+3392|0]^j>>>24;j=F[b+244>>2];D[a+13|0]=j^G[((l^s)&255)+3392|0];D[a+9|0]=G[((o^i>>>8)&255)+3392|0]^j>>>8;D[a+5|0]=G[((z^e>>>16)&255)+3392|0]^j>>>16;D[a+1|0]=G[(w^d>>>24)+3392|0]^j>>>24;j=F[b+248>>2];D[a+14|0]=j^G[((i^n)&255)+3392|0];D[a+10|0]=G[((y^e>>>8)&255)+3392|0]^j>>>8;D[a+6|0]=G[((v^d>>>16)&255)+3392|0]^j>>>16;D[a+2|0]=G[(u^l>>>24)+3392|0]^j>>>24;j=G[((e^x)&255)+3392|0];e=F[b+252>>2];D[a+15|0]=j^e;D[a+11|0]=G[((m^d>>>8)&255)+3392|0]^e>>>8;D[a+7|0]=G[((t^l>>>16)&255)+3392|0]^e>>>16;D[a+3|0]=G[(q^i>>>24)+3392|0]^e>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+224>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+228>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+232>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+236>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+2|0];i=G[a+1|0];l=G[a|0];j=G[a+14|0];n=G[a+12|0];o=G[a+15|0];p=G[a+8|0];q=G[a+10|0];s=G[a+9|0];r=G[a+11|0];t=G[a+4|0];u=G[a+5|0];m=G[a+6|0];v=G[a+7|0];w=G[a+3|0];d=F[b+208>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[q+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[l+3392|0]^d>>>24;d=F[b+212>>2];D[a+13|0]=d^G[j+3392|0];D[a+9|0]=G[r+3392|0]^d>>>8;D[a+5|0]=G[t+3392|0]^d>>>16;D[a+1|0]=G[i+3392|0]^d>>>24;d=F[b+216>>2];D[a+14|0]=d^G[o+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[u+3392|0]^d>>>16;D[a+2|0]=G[e+3392|0]^d>>>24;d=F[b+220>>2];D[a+15|0]=d^G[n+3392|0];D[a+11|0]=G[s+3392|0]^d>>>8;D[a+7|0]=G[m+3392|0]^d>>>16;D[a+3|0]=G[w+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+192>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+196>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+200>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+204>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+2|0];i=G[a+1|0];l=G[a|0];j=G[a+14|0];n=G[a+12|0];o=G[a+15|0];p=G[a+8|0];q=G[a+10|0];s=G[a+9|0];r=G[a+11|0];t=G[a+4|0];u=G[a+5|0];m=G[a+6|0];v=G[a+7|0];w=G[a+3|0];d=F[b+176>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[q+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[l+3392|0]^d>>>24;d=F[b+180>>2];D[a+13|0]=d^G[j+3392|0];D[a+9|0]=G[r+3392|0]^d>>>8;D[a+5|0]=G[t+3392|0]^d>>>16;D[a+1|0]=G[i+3392|0]^d>>>24;d=F[b+184>>2];D[a+14|0]=d^G[o+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[u+3392|0]^d>>>16;D[a+2|0]=G[e+3392|0]^d>>>24;d=F[b+188>>2];D[a+15|0]=d^G[n+3392|0];D[a+11|0]=G[s+3392|0]^d>>>8;D[a+7|0]=G[m+3392|0]^d>>>16;D[a+3|0]=G[w+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+160>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+164>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+168>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+172>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+144>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+148>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+152>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+156>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+128>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+132>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+136>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+140>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+112>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+116>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+120>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+124>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+96>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+100>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+104>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+108>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+80>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+84>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+88>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+92>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+3|0];i=G[a+6|0];l=G[a+9|0];j=G[a+12|0];n=G[a+2|0];o=G[a+5|0];p=G[a+8|0];q=G[a+15|0];s=G[a+1|0];r=G[a+4|0];t=G[a+11|0];u=G[a+14|0];m=G[a|0];v=G[a+7|0];w=G[a+10|0];d=F[b+64>>2];D[a+12|0]=d^G[G[a+13|0]+3392|0];D[a+8|0]=G[w+3392|0]^d>>>8;D[a+4|0]=G[v+3392|0]^d>>>16;D[a|0]=G[m+3392|0]^d>>>24;d=F[b+68>>2];D[a+13|0]=d^G[u+3392|0];D[a+9|0]=G[t+3392|0]^d>>>8;D[a+5|0]=G[r+3392|0]^d>>>16;D[a+1|0]=G[s+3392|0]^d>>>24;d=F[b+72>>2];D[a+14|0]=d^G[q+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=G[o+3392|0]^d>>>16;D[a+2|0]=G[n+3392|0]^d>>>24;d=F[b+76>>2];D[a+15|0]=d^G[j+3392|0];D[a+11|0]=G[l+3392|0]^d>>>8;D[a+7|0]=G[i+3392|0]^d>>>16;D[a+3|0]=G[e+3392|0]^d>>>24;xa(a);e=G[a+15|0];i=G[a+12|0];D[a+15|0]=i;l=G[G[a+2|0]+3392|0];D[a+2|0]=l;j=G[G[a+1|0]+3392|0];D[a+1|0]=j;n=G[G[a|0]+3392|0];D[a|0]=n;o=G[a+9|0];p=G[a+8|0];q=G[a+4|0];s=G[a+11|0];r=G[a+14|0];t=G[a+7|0];u=G[a+10|0];d=G[a+13|0];m=G[a+5|0];v=G[a+3|0];D[a+7|0]=G[G[a+6|0]+3392|0];D[a+6|0]=G[m+3392|0];D[a+3|0]=G[v+3392|0];m=G[d+3392|0];d=F[b+48>>2];D[a+12|0]=m^d;D[a+8|0]=G[u+3392|0]^d>>>8;D[a+4|0]=G[t+3392|0]^d>>>16;D[a|0]=n^d>>>24;d=F[b+52>>2];D[a+13|0]=d^G[r+3392|0];D[a+1|0]=j^d>>>24;D[a+9|0]=G[s+3392|0]^d>>>8;D[a+5|0]=G[q+3392|0]^d>>>16;d=F[b+56>>2];D[a+2|0]=l^d>>>24;l=G[a+6|0];D[a+14|0]=d^G[e+3392|0];D[a+10|0]=G[p+3392|0]^d>>>8;D[a+6|0]=l^d>>>16;d=F[b+60>>2];D[a+3|0]=G[a+3|0]^d>>>24;e=G[a+7|0];D[a+15|0]=d^G[i+3392|0];D[a+11|0]=G[o+3392|0]^d>>>8;D[a+7|0]=e^d>>>16;xa(a);n=G[a+15|0];j=G[a+12|0];D[a+15|0]=j;o=G[G[a+1|0]+3392|0];D[a+1|0]=o;p=G[G[a+2|0]+3392|0];D[a+2|0]=p;q=G[G[a+3|0]+3392|0];D[a+3|0]=q;s=G[a+7|0];r=G[G[a+6|0]+3392|0];D[a+7|0]=r;e=F[b+32>>2];i=F[b+36>>2];l=F[b+40>>2];t=G[a|0];u=G[a+10|0];m=G[a+4|0];v=G[a+11|0];w=G[a+5|0];x=G[a+8|0];y=G[a+9|0];z=G[a+13|0];A=G[a+14|0];d=c+h|0;B=G[j+3392|0];j=F[b+44>>2];D[d+15|0]=B^j;D[d+11|0]=l^G[n+3392|0];D[d+7|0]=i^G[A+3392|0];D[d+3|0]=e^G[z+3392|0];D[d+14|0]=G[y+3392|0]^j>>>8;D[d+13|0]=r^j>>>16;D[d+12|0]=q^j>>>24;D[d+10|0]=G[x+3392|0]^l>>>8;D[d+9|0]=G[w+3392|0]^l>>>16;D[d+8|0]=p^l>>>24;D[d+6|0]=G[v+3392|0]^i>>>8;D[d+5|0]=G[m+3392|0]^i>>>16;D[d+4|0]=o^i>>>24;D[d+2|0]=G[u+3392|0]^e>>>8;D[d+1|0]=G[s+3392|0]^e>>>16;D[d|0]=G[t+3392|0]^e>>>24;_=a+16|0;D[d|0]=G[d|0]^G[b+16|0];D[d+1|0]=G[d+1|0]^G[b+17|0];D[d+2|0]=G[d+2|0]^G[b+18|0];D[d+3|0]=G[d+3|0]^G[b+19|0];D[d+4|0]=G[d+4|0]^G[b+20|0];D[d+5|0]=G[d+5|0]^G[b+21|0];D[d+6|0]=G[d+6|0]^G[b+22|0];D[d+7|0]=G[d+7|0]^G[b+23|0];D[d+8|0]=G[d+8|0]^G[b+24|0];D[d+9|0]=G[d+9|0]^G[b+25|0];D[d+10|0]=G[d+10|0]^G[b+26|0];D[d+11|0]=G[d+11|0]^G[b+27|0];D[d+12|0]=G[d+12|0]^G[b+28|0];D[d+13|0]=G[d+13|0]^G[b+29|0];D[d+14|0]=G[d+14|0]^G[b+30|0];D[d+15|0]=G[d+15|0]^G[b+31|0];a=F[b+12>>2];F[b+24>>2]=F[b+8>>2];F[b+28>>2]=a;a=F[b+4>>2];F[b+16>>2]=F[b>>2];F[b+20>>2]=a;c=c+16|0;if(g>>>0>c>>>0){continue}break}}ia(b+32|0,240);ia(b+16|0,16);ia(b,16);_=b+272|0;a=G[(g+h|0)-1|0];l=a>>>0>g>>>0?-1:g-a|0}ia(k,80)}_=k+160|0;return l|0}function Jb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;d=_-16|0;_=d;h=G[a+14|0];k=G[a+6|0];l=G[a+5|0];s=G[a+9|0];q=G[a+13|0];m=G[a+1|0];n=G[a+10|0];i=G[a+2|0];j=G[a+3|0];o=G[a+7|0];p=G[a+15|0];r=G[a+11|0];u=G[a|0];f=F[c>>2];v=G[a+4|0];e=F[c+4>>2];t=G[a+8|0];g=F[c+8>>2];w=G[a+12|0];a=F[c+12>>2];D[d+3|0]=G[(w^a>>>24)+3072|0];D[d+2|0]=G[(t^g>>>24)+3072|0];D[d+1|0]=G[(v^e>>>24)+3072|0];D[d|0]=G[(u^f>>>24)+3072|0];D[d+15|0]=G[((g^r)&255)+3072|0];D[d+12|0]=G[((a^p)&255)+3072|0];D[d+14|0]=G[((e^o)&255)+3072|0];D[d+13|0]=G[((f^j)&255)+3072|0];D[d+10|0]=G[(i^f>>>8&255)+3072|0];D[d+8|0]=G[(n^g>>>8&255)+3072|0];D[d+7|0]=G[(m^f>>>16&255)+3072|0];D[d+6|0]=G[(q^a>>>16&255)+3072|0];D[d+5|0]=G[(s^g>>>16&255)+3072|0];D[d+4|0]=G[(l^e>>>16&255)+3072|0];D[d+11|0]=G[(k^e>>>8&255)+3072|0];D[d+9|0]=G[(h^a>>>8&255)+3072|0];ya(d);a=F[c+16>>2];f=F[c+20>>2];e=F[c+24>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+28>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+32>>2];f=F[c+36>>2];e=F[c+40>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+44>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+48>>2];f=F[c+52>>2];e=F[c+56>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+60>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+64>>2];f=F[c+68>>2];e=F[c+72>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+76>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+80>>2];f=F[c+84>>2];e=F[c+88>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+92>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+96>>2];f=F[c+100>>2];e=F[c+104>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+108>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+112>>2];f=F[c+116>>2];e=F[c+120>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+124>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+128>>2];f=F[c+132>>2];e=F[c+136>>2];h=G[d+11|0];k=G[d+9|0];l=G[d+5|0];s=G[d+6|0];q=G[d+7|0];m=G[d+4|0];n=G[d+10|0];i=G[d+8|0];j=G[d+12|0];o=G[d+13|0];p=G[d+15|0];r=G[d+14|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+140>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];D[d+15|0]=G[((e^r)&255)+3072|0];D[d+12|0]=G[((g^p)&255)+3072|0];D[d+14|0]=G[((f^o)&255)+3072|0];D[d+13|0]=G[((a^j)&255)+3072|0];D[d+10|0]=G[(i^a>>>8&255)+3072|0];D[d+8|0]=G[(n^e>>>8&255)+3072|0];D[d+7|0]=G[(m^a>>>16&255)+3072|0];D[d+6|0]=G[(q^g>>>16&255)+3072|0];D[d+5|0]=G[(s^e>>>16&255)+3072|0];D[d+4|0]=G[(l^f>>>16&255)+3072|0];D[d+11|0]=G[(k^f>>>8&255)+3072|0];D[d+9|0]=G[(h^g>>>8&255)+3072|0];ya(d);a=F[c+156>>2];h=a^G[d+15|0];f=F[c+152>>2];k=f^G[d+14|0];e=F[c+148>>2];l=e^G[d+13|0];g=F[c+144>>2];s=g^G[d+12|0];q=G[d+11|0]^a>>>8;m=G[d+7|0]^a>>>16;a=G[d+3|0]^a>>>24;n=G[d+10|0]^f>>>8;i=G[d+6|0]^f>>>16;f=G[d+2|0]^f>>>24;j=G[d+9|0]^e>>>8;o=G[d+5|0]^e>>>16;e=G[d+1|0]^e>>>24;p=G[d+8|0]^g>>>8;r=G[d+4|0]^g>>>16;D[d|0]=G[(G[d|0]^g>>>24)+3072|0];D[d+10|0]=G[(p&255)+3072|0];D[d+8|0]=G[(n&255)+3072|0];D[d+7|0]=G[(r&255)+3072|0];D[d+6|0]=G[(m&255)+3072|0];D[d+5|0]=G[(i&255)+3072|0];D[d+4|0]=G[(o&255)+3072|0];D[d+3|0]=G[a+3072|0];D[d+2|0]=G[f+3072|0];D[d+1|0]=G[e+3072|0];D[d+15|0]=G[(k&255)+3072|0];D[d+12|0]=G[(h&255)+3072|0];D[d+11|0]=G[(j&255)+3072|0];D[d+9|0]=G[(q&255)+3072|0];D[d+14|0]=G[(l&255)+3072|0];D[d+13|0]=G[(s&255)+3072|0];ya(d);f=F[c+160>>2];D[d+12|0]=f^G[d+12|0];D[d+8|0]=G[d+8|0]^f>>>8;e=F[c+164>>2];h=e^G[d+13|0];D[d+13|0]=h;k=G[d+9|0]^e>>>8;D[d+9|0]=k;g=F[c+168>>2];l=g^G[d+14|0];D[d+14|0]=l;a=F[c+172>>2];D[d+1|0]=G[(G[d+1|0]^e>>>24)+3072|0];D[d|0]=G[(G[d|0]^f>>>24)+3072|0];D[d+2|0]=G[(G[d+2|0]^g>>>24)+3072|0];s=G[d+5|0];q=G[d+6|0];m=G[d+4|0];n=G[d+10|0];D[d+3|0]=G[(G[d+3|0]^a>>>24)+3072|0];D[d+6|0]=G[(G[d+7|0]^a>>>16&255)+3072|0];i=G[d+11|0];j=G[d+15|0];o=G[d+12|0];p=G[d+8|0];D[d+8|0]=G[(n^g>>>8&255)+3072|0];D[d+7|0]=G[(m^f>>>16&255)+3072|0];D[d+5|0]=G[(q^g>>>16&255)+3072|0];D[d+4|0]=G[(s^e>>>16&255)+3072|0];D[d+10|0]=G[p+3072|0];D[d+15|0]=G[(l&255)+3072|0];D[d+12|0]=G[((a^j)&255)+3072|0];D[d+11|0]=G[(k&255)+3072|0];D[d+9|0]=G[(i^a>>>8&255)+3072|0];D[d+14|0]=G[(h&255)+3072|0];D[d+13|0]=G[o+3072|0];ya(d);a=F[c+176>>2];f=F[c+180>>2];e=F[c+184>>2];h=G[d+4|0];k=G[d+5|0];l=G[d+6|0];s=G[d+7|0];q=G[d+8|0];m=G[d+9|0];n=G[d+10|0];i=G[d+11|0];j=G[d+12|0];o=G[d+13|0];p=G[d+14|0];r=G[d+15|0];u=G[d|0];v=G[d+1|0];t=G[d+2|0];g=F[c+188>>2];D[d+3|0]=G[(G[d+3|0]^g>>>24)+3072|0];D[d+2|0]=G[(t^e>>>24)+3072|0];D[d+1|0]=G[(v^f>>>24)+3072|0];D[d|0]=G[(u^a>>>24)+3072|0];r=G[((g^r)&255)+3072|0];p=G[((e^p)&255)+3072|0];o=G[((f^o)&255)+3072|0];j=G[((a^j)&255)+3072|0];i=G[(i^g>>>8&255)+3072|0];n=G[(n^e>>>8&255)+3072|0];m=G[(m^f>>>8&255)+3072|0];g=G[(s^g>>>16&255)+3072|0];e=G[(l^e>>>16&255)+3072|0];f=G[(k^f>>>16&255)+3072|0];h=G[(h^a>>>16&255)+3072|0];D[d+10|0]=G[(q^a>>>8&255)+3072|0];D[d+8|0]=n;D[d+7|0]=h;D[d+6|0]=g;D[d+5|0]=e;D[d+4|0]=f;D[d+15|0]=p;D[d+12|0]=r;D[d+11|0]=m;D[d+9|0]=i;D[d+14|0]=o;D[d+13|0]=j;ya(d);f=F[c+192>>2];D[d+12|0]=f^G[d+12|0];D[d+8|0]=G[d+8|0]^f>>>8;e=F[c+196>>2];h=e^G[d+13|0];D[d+13|0]=h;k=G[d+9|0]^e>>>8;D[d+9|0]=k;g=F[c+200>>2];l=g^G[d+14|0];D[d+14|0]=l;a=F[c+204>>2];D[d+1|0]=G[(G[d+1|0]^e>>>24)+3072|0];D[d|0]=G[(G[d|0]^f>>>24)+3072|0];D[d+2|0]=G[(G[d+2|0]^g>>>24)+3072|0];s=G[d+5|0];q=G[d+6|0];m=G[d+4|0];n=G[d+10|0];D[d+3|0]=G[(G[d+3|0]^a>>>24)+3072|0];i=G[d+11|0];j=G[d+15|0];o=G[d+7|0];p=G[d+12|0];r=G[d+8|0];D[d+8|0]=G[(n^g>>>8&255)+3072|0];D[d+7|0]=G[(m^f>>>16&255)+3072|0];D[d+6|0]=G[(o^a>>>16&255)+3072|0];D[d+5|0]=G[(q^g>>>16&255)+3072|0];D[d+4|0]=G[(s^e>>>16&255)+3072|0];D[d+10|0]=G[r+3072|0];D[d+15|0]=G[(l&255)+3072|0];D[d+12|0]=G[((a^j)&255)+3072|0];D[d+11|0]=G[(k&255)+3072|0];D[d+9|0]=G[(i^a>>>8&255)+3072|0];D[d+14|0]=G[(h&255)+3072|0];D[d+13|0]=G[p+3072|0];ya(d);f=F[c+208>>2];D[d+12|0]=f^G[d+12|0];D[d+8|0]=G[d+8|0]^f>>>8;e=F[c+212>>2];k=e^G[d+13|0];D[d+13|0]=k;h=G[d+9|0]^e>>>8;D[d+9|0]=h;g=F[c+216>>2];l=g^G[d+14|0];D[d+14|0]=l;a=F[c+220>>2];D[d+2|0]=G[(G[d+2|0]^g>>>24)+3072|0];s=G[d+4|0];q=G[d+6|0];m=G[d+5|0];n=G[d+10|0];i=G[d|0];j=G[d+1|0];D[d+3|0]=G[(G[d+3|0]^a>>>24)+3072|0];j=G[(j^e>>>24)+3072|0];D[d+1|0]=j;i=G[(i^f>>>24)+3072|0];D[d|0]=i;o=G[d+7|0];p=G[d+11|0];r=G[d+15|0];u=G[d+8|0];v=G[d+12|0];l=G[(l&255)+3072|0];D[d+15|0]=l;t=G[(h&255)+3072|0];D[d+11|0]=t;h=F[c+224>>2];r=h^G[((a^r)&255)+3072|0];D[d+12|0]=r;n=G[(n^g>>>8&255)+3072|0]^h>>>8;D[d+8|0]=n;m=G[(m^e>>>16&255)+3072|0]^h>>>16;D[d+4|0]=m;h=i^h>>>24;D[d|0]=h;e=F[c+228>>2];i=e^G[v+3072|0];D[d+13|0]=i;p=G[(p^a>>>8&255)+3072|0]^e>>>8;D[d+9|0]=p;g=G[(q^g>>>16&255)+3072|0]^e>>>16;D[d+5|0]=g;q=j^e>>>24;D[d+1|0]=q;e=F[c+232>>2];k=e^G[(k&255)+3072|0];D[d+14|0]=k;j=G[u+3072|0]^e>>>8;D[d+10|0]=j;o=G[(o^a>>>16&255)+3072|0]^e>>>16;D[d+6|0]=o;e=G[d+2|0]^e>>>24;D[d+2|0]=e;a=F[c+236>>2];c=G[(s^f>>>16&255)+3072|0]^a>>>16;D[d+7|0]=c;f=G[d+3|0]^a>>>24;D[d+3|0]=f;D[b+13|0]=c;D[b+12|0]=f;D[b+11|0]=k;D[b+10|0]=j;D[b+9|0]=o;D[b+8|0]=e;D[b+7|0]=i;D[b+6|0]=p;D[b+5|0]=g;D[b+4|0]=q;D[b+3|0]=r;D[b+2|0]=n;D[b+1|0]=m;D[b|0]=h;D[b+15|0]=a^l;D[b+14|0]=t^a>>>8;_=d+16|0}function bd(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;l=_-16|0;_=l;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{if(a>>>0<=244){e=F[9386];h=a>>>0<11?16:a+11&-8;c=h>>>3|0;b=e>>>c|0;if(b&3){d=c+((b^-1)&1)|0;b=d<<3;f=F[b+37592>>2];a=f+8|0;c=F[f+8>>2];b=b+37584|0;l:{if((c|0)==(b|0)){F[9386]=ue(-2,d)&e;break l}F[c+12>>2]=b;F[b+8>>2]=c}b=d<<3;F[f+4>>2]=b|3;b=b+f|0;F[b+4>>2]=F[b+4>>2]|1;break a}k=F[9388];if(k>>>0>=h>>>0){break k}if(b){a=2<>>12&16;c=a;b=b>>>a|0;a=b>>>5&8;c=c|a;b=b>>>a|0;a=b>>>2&4;c=c|a;b=b>>>a|0;a=b>>>1&2;c=c|a;b=b>>>a|0;a=b>>>1&1;c=(c|a)+(b>>>a|0)|0;a=c<<3;g=F[a+37592>>2];b=F[g+8>>2];a=a+37584|0;m:{if((b|0)==(a|0)){e=ue(-2,c)&e;F[9386]=e;break m}F[b+12>>2]=a;F[a+8>>2]=b}a=g+8|0;F[g+4>>2]=h|3;d=g+h|0;b=c<<3;f=b-h|0;F[d+4>>2]=f|1;F[b+g>>2]=f;if(k){b=k>>>3|0;c=(b<<3)+37584|0;g=F[9391];b=1<>2]}F[c+8>>2]=g;F[b+12>>2]=g;F[g+12>>2]=c;F[g+8>>2]=b}F[9391]=d;F[9388]=f;break a}j=F[9387];if(!j){break k}b=(j&0-j)-1|0;a=b>>>12&16;c=a;b=b>>>a|0;a=b>>>5&8;c=c|a;b=b>>>a|0;a=b>>>2&4;c=c|a;b=b>>>a|0;a=b>>>1&2;c=c|a;b=b>>>a|0;a=b>>>1&1;b=F[((c|a)+(b>>>a|0)<<2)+37848>>2];d=(F[b+4>>2]&-8)-h|0;c=b;while(1){o:{a=F[c+16>>2];if(!a){a=F[c+20>>2];if(!a){break o}}c=(F[a+4>>2]&-8)-h|0;f=c>>>0>>0;d=f?c:d;b=f?a:b;c=a;continue}break}i=F[b+24>>2];f=F[b+12>>2];if((f|0)!=(b|0)){a=F[b+8>>2];F[a+12>>2]=f;F[f+8>>2]=a;break b}c=b+20|0;a=F[c>>2];if(!a){a=F[b+16>>2];if(!a){break j}c=b+16|0}while(1){g=c;f=a;c=a+20|0;a=F[c>>2];if(a){continue}c=f+16|0;a=F[f+16>>2];if(a){continue}break}F[g>>2]=0;break b}h=-1;if(a>>>0>4294967231){break k}a=a+11|0;h=a&-8;j=F[9387];if(!j){break k}d=0-h|0;e=0;p:{if(h>>>0<256){break p}e=31;if(h>>>0>16777215){break p}a=a>>>8|0;g=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(c|g))|0;e=(a<<1|h>>>a+21&1)+28|0}c=F[(e<<2)+37848>>2];q:{r:{s:{if(!c){a=0;break s}a=0;b=h<<((e|0)==31?0:25-(e>>>1|0)|0);while(1){t:{g=(F[c+4>>2]&-8)-h|0;if(g>>>0>=d>>>0){break t}f=c;d=g;if(d){break t}d=0;a=c;break r}g=F[c+20>>2];c=F[((b>>>29&4)+c|0)+16>>2];a=g?(g|0)==(c|0)?a:g:a;b=b<<1;if(c){continue}break}}if(!(a|f)){f=0;a=2<>>12&16;c=a;b=b>>>a|0;a=b>>>5&8;c=c|a;b=b>>>a|0;a=b>>>2&4;c=c|a;b=b>>>a|0;a=b>>>1&2;c=c|a;b=b>>>a|0;a=b>>>1&1;a=F[((c|a)+(b>>>a|0)<<2)+37848>>2]}if(!a){break q}}while(1){b=(F[a+4>>2]&-8)-h|0;c=b>>>0>>0;d=c?b:d;f=c?a:f;b=F[a+16>>2];if(b){a=b}else{a=F[a+20>>2]}if(a){continue}break}}if(!f|F[9388]-h>>>0<=d>>>0){break k}e=F[f+24>>2];b=F[f+12>>2];if((f|0)!=(b|0)){a=F[f+8>>2];F[a+12>>2]=b;F[b+8>>2]=a;break c}c=f+20|0;a=F[c>>2];if(!a){a=F[f+16>>2];if(!a){break i}c=f+16|0}while(1){g=c;b=a;c=a+20|0;a=F[c>>2];if(a){continue}c=b+16|0;a=F[b+16>>2];if(a){continue}break}F[g>>2]=0;break c}c=F[9388];if(c>>>0>=h>>>0){d=F[9391];b=c-h|0;u:{if(b>>>0>=16){F[9388]=b;a=d+h|0;F[9391]=a;F[a+4>>2]=b|1;F[c+d>>2]=b;F[d+4>>2]=h|3;break u}F[9391]=0;F[9388]=0;F[d+4>>2]=c|3;a=c+d|0;F[a+4>>2]=F[a+4>>2]|1}a=d+8|0;break a}i=F[9389];if(i>>>0>h>>>0){b=i-h|0;F[9389]=b;c=F[9392];a=c+h|0;F[9392]=a;F[a+4>>2]=b|1;F[c+4>>2]=h|3;a=c+8|0;break a}a=0;j=h+47|0;if(F[9504]){c=F[9506]}else{F[9507]=-1;F[9508]=-1;F[9505]=4096;F[9506]=4096;F[9504]=l+12&-16^1431655768;F[9509]=0;F[9497]=0;c=4096}g=j+c|0;f=0-c|0;c=g&f;if(c>>>0<=h>>>0){break a}d=F[9496];if(d){b=F[9494];e=b+c|0;if(d>>>0>>0|b>>>0>=e>>>0){break a}}if(G[37988]&4){break f}v:{w:{d=F[9392];if(d){a=37992;while(1){b=F[a>>2];if(b>>>0<=d>>>0&d>>>0>2]>>>0){break w}a=F[a+8>>2];if(a){continue}break}}b=La(0);if((b|0)==-1){break g}e=c;d=F[9505];a=d-1|0;if(a&b){e=(c-b|0)+(a+b&0-d)|0}if(e>>>0<=h>>>0|e>>>0>2147483646){break g}d=F[9496];if(d){a=F[9494];f=a+e|0;if(d>>>0>>0|a>>>0>=f>>>0){break g}}a=La(e);if((b|0)!=(a|0)){break v}break e}e=f&g-i;if(e>>>0>2147483646){break g}b=La(e);if((b|0)==(F[a>>2]+F[a+4>>2]|0)){break h}a=b}if(!((a|0)==-1|h+48>>>0<=e>>>0)){b=F[9506];b=b+(j-e|0)&0-b;if(b>>>0>2147483646){b=a;break e}if((La(b)|0)!=-1){e=b+e|0;b=a;break e}La(0-e|0);break g}b=a;if((a|0)!=-1){break e}break g}f=0;break b}b=0;break c}if((b|0)!=-1){break e}}F[9497]=F[9497]|4}if(c>>>0>2147483646){break d}b=La(c);a=La(0);if((b|0)==-1|(a|0)==-1|a>>>0<=b>>>0){break d}e=a-b|0;if(e>>>0<=h+40>>>0){break d}}a=F[9494]+e|0;F[9494]=a;if(a>>>0>I[9495]){F[9495]=a}x:{y:{z:{g=F[9392];if(g){a=37992;while(1){d=F[a>>2];c=F[a+4>>2];if((d+c|0)==(b|0)){break z}a=F[a+8>>2];if(a){continue}break}break y}a=F[9390];if(!(a>>>0<=b>>>0?a:0)){F[9390]=b}a=0;F[9499]=e;F[9498]=b;F[9394]=-1;F[9395]=F[9504];F[9501]=0;while(1){d=a<<3;c=d+37584|0;F[d+37592>>2]=c;F[d+37596>>2]=c;a=a+1|0;if((a|0)!=32){continue}break}d=e-40|0;a=b+8&7?-8-b&7:0;c=d-a|0;F[9389]=c;a=a+b|0;F[9392]=a;F[a+4>>2]=c|1;F[(b+d|0)+4>>2]=40;F[9393]=F[9508];break x}if(G[a+12|0]&8|d>>>0>g>>>0|b>>>0<=g>>>0){break y}F[a+4>>2]=c+e;a=g+8&7?-8-g&7:0;c=a+g|0;F[9392]=c;b=F[9389]+e|0;a=b-a|0;F[9389]=a;F[c+4>>2]=a|1;F[(b+g|0)+4>>2]=40;F[9393]=F[9508];break x}if(I[9390]>b>>>0){F[9390]=b}c=b+e|0;a=37992;A:{B:{C:{D:{E:{F:{while(1){if((c|0)!=F[a>>2]){a=F[a+8>>2];if(a){continue}break F}break}if(!(G[a+12|0]&8)){break E}}a=37992;while(1){c=F[a>>2];if(c>>>0<=g>>>0){f=c+F[a+4>>2]|0;if(f>>>0>g>>>0){break D}}a=F[a+8>>2];continue}}F[a>>2]=b;F[a+4>>2]=F[a+4>>2]+e;j=(b+8&7?-8-b&7:0)+b|0;F[j+4>>2]=h|3;e=c+(c+8&7?-8-c&7:0)|0;i=h+j|0;c=e-i|0;if((e|0)==(g|0)){F[9392]=i;a=F[9389]+c|0;F[9389]=a;F[i+4>>2]=a|1;break B}if(F[9391]==(e|0)){F[9391]=i;a=F[9388]+c|0;F[9388]=a;F[i+4>>2]=a|1;F[a+i>>2]=a;break B}a=F[e+4>>2];if((a&3)==1){g=a&-8;G:{if(a>>>0<=255){d=F[e+8>>2];a=a>>>3|0;b=F[e+12>>2];if((b|0)==(d|0)){F[9386]=F[9386]&ue(-2,a);break G}F[d+12>>2]=b;F[b+8>>2]=d;break G}h=F[e+24>>2];b=F[e+12>>2];H:{if((e|0)!=(b|0)){a=F[e+8>>2];F[a+12>>2]=b;F[b+8>>2]=a;break H}I:{a=e+20|0;d=F[a>>2];if(d){break I}a=e+16|0;d=F[a>>2];if(d){break I}b=0;break H}while(1){f=a;b=d;a=b+20|0;d=F[a>>2];if(d){continue}a=b+16|0;d=F[b+16>>2];if(d){continue}break}F[f>>2]=0}if(!h){break G}d=F[e+28>>2];a=(d<<2)+37848|0;J:{if(F[a>>2]==(e|0)){F[a>>2]=b;if(b){break J}F[9387]=F[9387]&ue(-2,d);break G}F[h+(F[h+16>>2]==(e|0)?16:20)>>2]=b;if(!b){break G}}F[b+24>>2]=h;a=F[e+16>>2];if(a){F[b+16>>2]=a;F[a+24>>2]=b}a=F[e+20>>2];if(!a){break G}F[b+20>>2]=a;F[a+24>>2]=b}e=e+g|0;c=c+g|0}F[e+4>>2]=F[e+4>>2]&-2;F[i+4>>2]=c|1;F[c+i>>2]=c;if(c>>>0<=255){a=c>>>3|0;b=(a<<3)+37584|0;c=F[9386];a=1<>2]}F[b+8>>2]=i;F[a+12>>2]=i;F[i+12>>2]=b;F[i+8>>2]=a;break B}a=31;if(c>>>0<=16777215){a=c>>>8|0;f=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(d|f))|0;a=(a<<1|c>>>a+21&1)+28|0}F[i+28>>2]=a;F[i+16>>2]=0;F[i+20>>2]=0;f=(a<<2)+37848|0;d=F[9387];b=1<>2]=i;F[i+24>>2]=f;break L}a=c<<((a|0)==31?0:25-(a>>>1|0)|0);b=F[f>>2];while(1){d=b;if((F[b+4>>2]&-8)==(c|0)){break C}b=a>>>29|0;a=a<<1;f=d+(b&4)|0;b=F[f+16>>2];if(b){continue}break}F[f+16>>2]=i;F[i+24>>2]=d}F[i+12>>2]=i;F[i+8>>2]=i;break B}d=e-40|0;a=b+8&7?-8-b&7:0;c=d-a|0;F[9389]=c;a=a+b|0;F[9392]=a;F[a+4>>2]=c|1;F[(b+d|0)+4>>2]=40;F[9393]=F[9508];a=(f+(f-39&7?39-f&7:0)|0)-47|0;c=a>>>0>>0?g:a;F[c+4>>2]=27;a=F[9501];F[c+16>>2]=F[9500];F[c+20>>2]=a;a=F[9499];F[c+8>>2]=F[9498];F[c+12>>2]=a;F[9500]=c+8;F[9499]=e;F[9498]=b;F[9501]=0;a=c+24|0;while(1){F[a+4>>2]=7;b=a+8|0;a=a+4|0;if(b>>>0>>0){continue}break}if((c|0)==(g|0)){break x}F[c+4>>2]=F[c+4>>2]&-2;f=c-g|0;F[g+4>>2]=f|1;F[c>>2]=f;if(f>>>0<=255){a=f>>>3|0;b=(a<<3)+37584|0;c=F[9386];a=1<>2]}F[b+8>>2]=g;F[a+12>>2]=g;F[g+12>>2]=b;F[g+8>>2]=a;break x}a=31;F[g+16>>2]=0;F[g+20>>2]=0;if(f>>>0<=16777215){a=f>>>8|0;d=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(c|d))|0;a=(a<<1|f>>>a+21&1)+28|0}F[g+28>>2]=a;d=(a<<2)+37848|0;c=F[9387];b=1<>2]=g;F[g+24>>2]=d;break N}a=f<<((a|0)==31?0:25-(a>>>1|0)|0);b=F[d>>2];while(1){c=b;if((f|0)==(F[b+4>>2]&-8)){break A}b=a>>>29|0;a=a<<1;d=c+(b&4)|0;b=F[d+16>>2];if(b){continue}break}F[d+16>>2]=g;F[g+24>>2]=c}F[g+12>>2]=g;F[g+8>>2]=g;break x}a=F[d+8>>2];F[a+12>>2]=i;F[d+8>>2]=i;F[i+24>>2]=0;F[i+12>>2]=d;F[i+8>>2]=a}a=j+8|0;break a}a=F[c+8>>2];F[a+12>>2]=g;F[c+8>>2]=g;F[g+24>>2]=0;F[g+12>>2]=c;F[g+8>>2]=a}a=F[9389];if(a>>>0<=h>>>0){break d}b=a-h|0;F[9389]=b;c=F[9392];a=c+h|0;F[9392]=a;F[a+4>>2]=b|1;F[c+4>>2]=h|3;a=c+8|0;break a}F[9343]=48;a=0;break a}O:{if(!e){break O}c=F[f+28>>2];a=(c<<2)+37848|0;P:{if(F[a>>2]==(f|0)){F[a>>2]=b;if(b){break P}j=ue(-2,c)&j;F[9387]=j;break O}F[e+(F[e+16>>2]==(f|0)?16:20)>>2]=b;if(!b){break O}}F[b+24>>2]=e;a=F[f+16>>2];if(a){F[b+16>>2]=a;F[a+24>>2]=b}a=F[f+20>>2];if(!a){break O}F[b+20>>2]=a;F[a+24>>2]=b}Q:{if(d>>>0<=15){a=d+h|0;F[f+4>>2]=a|3;a=a+f|0;F[a+4>>2]=F[a+4>>2]|1;break Q}F[f+4>>2]=h|3;e=f+h|0;F[e+4>>2]=d|1;F[d+e>>2]=d;if(d>>>0<=255){a=d>>>3|0;b=(a<<3)+37584|0;c=F[9386];a=1<>2]}F[b+8>>2]=e;F[a+12>>2]=e;F[e+12>>2]=b;F[e+8>>2]=a;break Q}a=31;if(d>>>0<=16777215){a=d>>>8|0;g=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(c|g))|0;a=(a<<1|d>>>a+21&1)+28|0}F[e+28>>2]=a;F[e+16>>2]=0;F[e+20>>2]=0;b=(a<<2)+37848|0;S:{c=1<>2]=e;break T}a=d<<((a|0)==31?0:25-(a>>>1|0)|0);h=F[b>>2];while(1){b=h;if((F[b+4>>2]&-8)==(d|0)){break S}c=a>>>29|0;a=a<<1;c=(c&4)+b|0;h=F[c+16>>2];if(h){continue}break}F[c+16>>2]=e}F[e+24>>2]=b;F[e+12>>2]=e;F[e+8>>2]=e;break Q}a=F[b+8>>2];F[a+12>>2]=e;F[b+8>>2]=e;F[e+24>>2]=0;F[e+12>>2]=b;F[e+8>>2]=a}a=f+8|0;break a}U:{if(!i){break U}c=F[b+28>>2];a=(c<<2)+37848|0;V:{if(F[a>>2]==(b|0)){F[a>>2]=f;if(f){break V}F[9387]=ue(-2,c)&j;break U}F[i+(F[i+16>>2]==(b|0)?16:20)>>2]=f;if(!f){break U}}F[f+24>>2]=i;a=F[b+16>>2];if(a){F[f+16>>2]=a;F[a+24>>2]=f}a=F[b+20>>2];if(!a){break U}F[f+20>>2]=a;F[a+24>>2]=f}W:{if(d>>>0<=15){a=d+h|0;F[b+4>>2]=a|3;a=a+b|0;F[a+4>>2]=F[a+4>>2]|1;break W}F[b+4>>2]=h|3;f=b+h|0;F[f+4>>2]=d|1;F[d+f>>2]=d;if(k){a=k>>>3|0;c=(a<<3)+37584|0;g=F[9391];a=1<>2]}F[c+8>>2]=g;F[a+12>>2]=g;F[g+12>>2]=c;F[g+8>>2]=a}F[9391]=f;F[9388]=d}a=b+8|0}_=l+16|0;return a|0}function ta(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=F[c>>2];d=e;f=e>>31;e=F[b>>2];F[a>>2]=se(d,f,e,e>>31);F[a+4>>2]=$;e=F[c>>2];d=e;f=e>>31;e=F[b+8>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+8>>2];h=e;g=e>>31;e=F[b>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;F[a+8>>2]=d;F[a+12>>2]=d>>>0>>0?e+1|0:e;e=F[c+16>>2];d=e;f=e>>31;e=F[b>>2];e=se(d,f,e,e>>31);f=$;h=e;e=F[c+8>>2];g=e;i=e>>31;d=F[b+8>>2];e=d>>31;i=se(g,i,(d&2147483647)<<1,e);d=h+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c>>2];f=d;g=d>>31;d=F[b+16>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;F[a+16>>2]=d;F[a+20>>2]=d>>>0>>0?e+1|0:e;e=F[c+8>>2];d=e;f=e>>31;e=F[b+16>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+16>>2];h=e;g=e>>31;e=F[b+8>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+24>>2];h=d;g=d>>31;d=F[b>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c>>2];h=e;g=e>>31;e=F[b+24>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;F[a+24>>2]=f;F[a+28>>2]=f>>>0>>0?e+1|0:e;e=F[c+16>>2];d=e;f=e>>31;e=F[b+16>>2];e=se(d,f,e,e>>31);i=$;d=F[c+8>>2];f=d;h=d>>31;d=F[b+24>>2];d=se(f,h,d,d>>31);f=$;h=e;e=F[c+24>>2];g=e;j=e>>31;e=F[b+8>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+f|0;f=d;d=(d>>>0>>0?e+1|0:e)<<1|d>>>31;g=f<<1;f=h+g|0;e=d+i|0;e=f>>>0>>0?e+1|0:e;h=f;d=F[c+32>>2];f=d;g=d>>31;d=F[b>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c>>2];f=d;g=d>>31;d=F[b+32>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;F[a+32>>2]=d;F[a+36>>2]=d>>>0>>0?e+1|0:e;e=F[c+16>>2];d=e;f=e>>31;e=F[b+24>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+24>>2];h=e;g=e>>31;e=F[b+16>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+32>>2];h=d;g=d>>31;d=F[b+8>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c+8>>2];h=e;g=e>>31;e=F[b+32>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;h=f;d=F[c+40>>2];f=d;g=d>>31;d=F[b>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c>>2];f=d;g=d>>31;d=F[b+40>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;F[a+40>>2]=d;F[a+44>>2]=d>>>0>>0?e+1|0:e;e=F[c+32>>2];d=e;f=e>>31;e=F[b+16>>2];e=se(d,f,e,e>>31);i=$;d=F[c+40>>2];f=d;h=d>>31;d=F[b+8>>2];d=se(f,h,d,d>>31);f=$;h=e;e=F[c+24>>2];g=e;j=e>>31;e=F[b+24>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+8>>2];g=d;j=d>>31;d=F[b+40>>2];g=se(g,j,d,d>>31);f=f+g|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=d<<1|f>>>31;f=f<<1;d=h+f|0;e=e+i|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+16>>2];f=d;g=d>>31;d=F[b+32>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+48>>2];f=d;g=d>>31;d=F[b>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c>>2];h=d;g=d>>31;d=F[b+48>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;F[a+48>>2]=f;F[a+52>>2]=f>>>0>>0?d+1|0:d;e=F[c+24>>2];d=e;f=e>>31;e=F[b+32>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+32>>2];h=e;g=e>>31;e=F[b+24>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+40>>2];f=d;g=d>>31;d=F[b+16>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+16>>2];f=d;g=d>>31;d=F[b+40>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+48>>2];f=d;g=d>>31;d=F[b+8>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+8>>2];h=d;g=d>>31;d=F[b+48>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c+56>>2];h=e;g=e>>31;e=F[b>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;h=f;d=F[c>>2];f=d;g=d>>31;d=F[b+56>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;F[a+56>>2]=d;F[a+60>>2]=d>>>0>>0?e+1|0:e;e=F[c+32>>2];d=e;f=e>>31;e=F[b+32>>2];e=se(d,f,e,e>>31);i=$;d=F[c+24>>2];f=d;h=d>>31;d=F[b+40>>2];d=se(f,h,d,d>>31);f=$;h=e;e=F[c+40>>2];g=e;j=e>>31;e=F[b+24>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+56>>2];f=d;j=d>>31;d=F[b+8>>2];f=se(f,j,d,d>>31);d=g+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+8>>2];g=d;j=d>>31;d=F[b+56>>2];g=se(g,j,d,d>>31);f=f+g|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=d<<1|f>>>31;f=f<<1;d=h+f|0;e=e+i|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+48>>2];f=d;g=d>>31;d=F[b+16>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+16>>2];f=d;g=d>>31;d=F[b+48>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+64>>2];h=d;g=d>>31;d=F[b>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c>>2];h=e;g=e>>31;e=F[b+64>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;F[a+64>>2]=f;F[a+68>>2]=f>>>0>>0?e+1|0:e;e=F[c+32>>2];d=e;f=e>>31;e=F[b+40>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+40>>2];h=e;g=e>>31;e=F[b+32>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+48>>2];f=d;g=d>>31;d=F[b+24>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+24>>2];f=d;g=d>>31;d=F[b+48>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+56>>2];h=d;g=d>>31;d=F[b+16>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c+16>>2];h=e;g=e>>31;e=F[b+56>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;h=f;d=F[c+64>>2];f=d;g=d>>31;d=F[b+8>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+8>>2];f=d;g=d>>31;d=F[b+64>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+72>>2];f=d;g=d>>31;d=F[b>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c>>2];h=d;g=d>>31;d=F[b+72>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;F[a+72>>2]=f;F[a+76>>2]=f>>>0>>0?d+1|0:d;e=F[c+48>>2];d=e;f=e>>31;e=F[b+32>>2];e=se(d,f,e,e>>31);i=$;d=F[c+56>>2];f=d;h=d>>31;d=F[b+24>>2];d=se(f,h,d,d>>31);f=$;h=e;e=F[c+40>>2];g=e;j=e>>31;e=F[b+40>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+24>>2];f=d;j=d>>31;d=F[b+56>>2];f=se(f,j,d,d>>31);d=g+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+72>>2];f=d;j=d>>31;d=F[b+8>>2];f=se(f,j,d,d>>31);d=g+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+8>>2];f=d;j=d>>31;d=F[b+72>>2];f=se(f,j,d,d>>31);d=g+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;g=d<<1;f=h+g|0;d=(e<<1|d>>>31)+i|0;d=f>>>0>>0?d+1|0:d;e=F[c+32>>2];h=e;g=e>>31;e=F[b+48>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;h=f;d=F[c+64>>2];f=d;g=d>>31;d=F[b+16>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+16>>2];f=d;g=d>>31;d=F[b+64>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;F[a+80>>2]=d;F[a+84>>2]=d>>>0>>0?e+1|0:e;e=F[c+40>>2];d=e;f=e>>31;e=F[b+48>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+48>>2];h=e;g=e>>31;e=F[b+40>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+56>>2];h=d;g=d>>31;d=F[b+32>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c+32>>2];h=e;g=e>>31;e=F[b+56>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;h=f;d=F[c+64>>2];f=d;g=d>>31;d=F[b+24>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+24>>2];f=d;g=d>>31;d=F[b+64>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+72>>2];f=d;g=d>>31;d=F[b+16>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+16>>2];h=d;g=d>>31;d=F[b+72>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;F[a+88>>2]=f;F[a+92>>2]=f>>>0>>0?d+1|0:d;e=F[c+48>>2];d=e;f=e>>31;e=F[b+48>>2];e=se(d,f,e,e>>31);f=$;d=F[c+40>>2];h=d;g=d>>31;d=F[b+56>>2];d=se(h,g,d,d>>31);i=$;h=e;e=F[c+56>>2];g=e;j=e>>31;e=F[b+40>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+i|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+72>>2];i=d;j=d>>31;d=F[b+24>>2];i=se(i,j,d,d>>31);d=g+i|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+24>>2];i=d;j=d>>31;d=F[b+72>>2];i=se(i,j,d,d>>31);d=g+i|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;e=e<<1|d>>>31;i=d<<1;d=h+i|0;e=e+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+64>>2];h=d;g=d>>31;d=F[b+32>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c+32>>2];h=e;g=e>>31;e=F[b+64>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;F[a+96>>2]=f;F[a+100>>2]=f>>>0>>0?e+1|0:e;e=F[c+48>>2];d=e;f=e>>31;e=F[b+56>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+56>>2];h=e;g=e>>31;e=F[b+48>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+64>>2];f=d;g=d>>31;d=F[b+40>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+40>>2];f=d;g=d>>31;d=F[b+64>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+72>>2];h=d;g=d>>31;d=F[b+32>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=F[c+32>>2];h=e;g=e>>31;e=F[b+72>>2];i=se(h,g,e,e>>31);f=i+f|0;e=$+d|0;F[a+104>>2]=f;F[a+108>>2]=f>>>0>>0?e+1|0:e;e=F[c+64>>2];d=e;f=e>>31;e=F[b+48>>2];e=se(d,f,e,e>>31);f=$;d=F[c+72>>2];h=d;g=d>>31;d=F[b+40>>2];d=se(h,g,d,d>>31);i=$;h=e;e=F[c+56>>2];g=e;j=e>>31;e=F[b+56>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+i|0;e=d>>>0>>0?e+1|0:e;g=d;d=F[c+40>>2];i=d;j=d>>31;d=F[b+72>>2];i=se(i,j,d,d>>31);d=g+i|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;e=e<<1|d>>>31;i=d<<1;d=h+i|0;e=e+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=F[c+48>>2];h=d;g=d>>31;d=F[b+64>>2];i=se(h,g,d,d>>31);f=f+i|0;d=$+e|0;F[a+112>>2]=f;F[a+116>>2]=f>>>0>>0?d+1|0:d;e=F[c+56>>2];d=e;f=e>>31;e=F[b+64>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+64>>2];h=e;g=e>>31;e=F[b+56>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+72>>2];f=d;g=d>>31;d=F[b+48>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;h=d;d=F[c+48>>2];f=d;g=d>>31;d=F[b+72>>2];f=se(f,g,d,d>>31);d=h+f|0;e=$+e|0;F[a+120>>2]=d;F[a+124>>2]=d>>>0>>0?e+1|0:e;e=F[c+64>>2];d=e;f=e>>31;e=F[b+64>>2];e=se(d,f,e,e>>31);i=$;d=F[c+56>>2];f=d;h=d>>31;d=F[b+72>>2];d=se(f,h,d,d>>31);f=$;h=e;e=F[c+72>>2];g=e;j=e>>31;e=F[b+56>>2];g=se(g,j,e,e>>31);d=g+d|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;g=d<<1;f=h+g|0;d=(e<<1|d>>>31)+i|0;F[a+128>>2]=f;F[a+132>>2]=f>>>0>>0?d+1|0:d;e=F[c+64>>2];d=e;f=e>>31;e=F[b+72>>2];e=se(d,f,e,e>>31);f=$;d=e;e=F[c+72>>2];h=e;g=e>>31;e=F[b+64>>2];i=se(h,g,e,e>>31);d=d+i|0;e=$+f|0;F[a+136>>2]=d;F[a+140>>2]=d>>>0>>0?e+1|0:e;e=F[b+72>>2];b=0;c=F[c+72>>2];F[a+144>>2]=se(c,c>>31,(e&2147483647)<<1|b>>>31,e>>31);F[a+148>>2]=$}function ha(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0,H=0,I=0,J=0,K=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0;V=F[c+4>>2];d=V;v=d;E=d>>31;G=F[b+20>>2];d=G<<1;ka=d;Y=d>>31;d=se(v,E,d,Y);f=$;e=d;d=F[c>>2];w=d;x=d>>31;d=F[b+24>>2];H=d;y=d>>31;o=se(w,x,d,y);e=e+o|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=e;g=F[c+8>>2];e=g;la=e;P=e>>31;e=F[b+16>>2];I=e;z=e>>31;o=se(g,P,e,z);e=f+o|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;h=F[c+12>>2];d=h;ma=d;S=d>>31;o=F[b+12>>2];d=o<<1;na=d;Z=d>>31;p=se(h,S,d,Z);d=p+e|0;e=$+f|0;e=d>>>0

>>0?e+1|0:e;f=d;s=F[c+16>>2];d=s;va=d;W=d>>31;d=F[b+8>>2];J=d;A=d>>31;p=se(s,W,d,A);f=f+p|0;d=$+e|0;d=f>>>0

>>0?d+1|0:d;K=f;k=F[c+20>>2];e=k;wa=e;_=e>>31;p=F[b+4>>2];e=p<<1;oa=e;aa=e>>31;f=se(k,_,e,aa);e=K+f|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;f=e;l=F[c+24>>2];e=l;xa=e;pa=e>>31;e=F[b>>2];M=e;B=e>>31;C=se(l,pa,e,B);f=f+C|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;ba=F[c+28>>2];d=L(ba,19);q=d;T=d>>31;C=F[b+36>>2];d=C<<1;qa=d;ca=d>>31;r=se(q,T,d,ca);d=r+f|0;f=$+e|0;f=d>>>0>>0?f+1|0:f;e=d;ra=F[c+32>>2];d=L(ra,19);m=d;i=d>>31;d=F[b+32>>2];N=d;D=d>>31;r=se(m,i,d,D);e=e+r|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;ya=F[c+36>>2];c=L(ya,19);n=c;O=c>>31;r=F[b+28>>2];b=r<<1;sa=b;da=b>>31;c=se(c,O,b,da);b=c+e|0;d=$+d|0;U=b;b=b>>>0>>0?d+1|0:d;c=se(I,z,v,E);d=$;ea=G>>31;e=se(w,x,G,ea);c=e+c|0;f=$+d|0;f=c>>>0>>0?f+1|0:f;fa=o>>31;d=se(g,P,o,fa);c=d+c|0;e=$+f|0;e=c>>>0>>0?e+1|0:e;f=se(J,A,h,S);c=f+c|0;d=$+e|0;d=c>>>0>>0?d+1|0:d;ga=p>>31;e=se(s,W,p,ga);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;e=se(M,B,k,_);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;f=c;c=L(l,19);Q=c;X=c>>31;ha=C>>31;e=se(c,X,C,ha);c=f+e|0;f=$+d|0;f=c>>>0>>0?f+1|0:f;d=se(N,D,q,T);c=d+c|0;e=$+f|0;e=c>>>0>>0?e+1|0:e;ia=r>>31;f=se(m,i,r,ia);c=f+c|0;d=$+e|0;d=c>>>0>>0?d+1|0:d;e=se(n,O,H,y);c=e+c|0;d=$+d|0;K=c;c=c>>>0>>0?d+1|0:d;d=se(v,E,na,Z);f=$;l=se(w,x,I,z);e=l+d|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;l=se(J,A,g,P);e=l+e|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;l=se(h,S,oa,aa);d=l+e|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;l=se(M,B,s,W);f=l+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;t=f;e=L(k,19);ta=e;ja=e>>31;f=se(e,ja,qa,ca);e=t+f|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;f=se(N,D,Q,X);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;k=se(q,T,sa,da);e=k+e|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;k=se(m,i,H,y);d=k+e|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;k=se(n,O,ka,Y);f=k+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;k=f;Ba=d;e=f+33554432|0;d=e>>>0<33554432?d+1|0:d;l=e;Ca=d;f=K;K=(d&67108863)<<6|e>>>26;f=f+K|0;d=(d>>26)+c|0;d=f>>>0>>0?d+1|0:d;K=f;c=K+16777216|0;f=c>>>0<16777216?d+1|0:d;Da=c;e=f>>25;f=(f&33554431)<<7|c>>>25;c=f+U|0;d=b+e|0;d=c>>>0>>0?d+1|0:d;b=c+33554432|0;d=b>>>0<33554432?d+1|0:d;R=b;b=d;d=R&-67108864;F[a+24>>2]=c-d;c=se(v,E,oa,aa);d=$;e=se(w,x,J,A);c=e+c|0;f=$+d|0;f=c>>>0>>0?f+1|0:f;e=se(M,B,g,P);c=e+c|0;d=$+f|0;d=c>>>0>>0?d+1|0:d;f=c;c=L(h,19);h=c;U=c>>31;e=se(c,U,qa,ca);c=f+e|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;e=c;c=L(s,19);za=c;ua=c>>31;f=se(N,D,c,ua);c=e+f|0;e=$+d|0;e=c>>>0>>0?e+1|0:e;f=se(sa,da,ta,ja);c=f+c|0;d=$+e|0;d=c>>>0>>0?d+1|0:d;e=se(H,y,Q,X);c=e+c|0;f=$+d|0;f=c>>>0>>0?f+1|0:f;e=se(q,T,ka,Y);c=e+c|0;d=$+f|0;d=c>>>0>>0?d+1|0:d;e=se(m,i,I,z);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;f=se(n,O,na,Z);c=f+c|0;e=$+d|0;t=c;c=c>>>0>>0?e+1|0:e;d=se(M,B,v,E);f=$;s=se(w,x,p,ga);e=s+d|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=e;e=L(g,19);s=e;j=e>>31;g=se(e,j,C,ha);e=f+g|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;g=se(N,D,h,U);e=g+e|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=se(za,ua,r,ia);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;g=se(H,y,ta,ja);f=g+e|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;g=se(Q,X,G,ea);f=g+f|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;g=se(I,z,q,T);e=g+f|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;g=se(m,i,o,fa);e=g+e|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=se(n,O,J,A);e=f+e|0;d=$+d|0;Aa=e;g=e>>>0>>0?d+1|0:d;d=L(v,19);d=se(d,d>>31,qa,ca);e=$;f=se(w,x,M,B);d=f+d|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;V=se(N,D,s,j);f=V+d|0;d=$+e|0;h=se(h,U,sa,da);e=h+f|0;f=$+(f>>>0>>0?d+1|0:d)|0;f=e>>>0>>0?f+1|0:f;h=se(H,y,za,ua);e=h+e|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=se(ka,Y,ta,ja);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;h=se(I,z,Q,X);f=h+e|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;h=se(q,T,na,Z);f=h+f|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;h=se(m,i,J,A);e=h+f|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;h=se(n,O,oa,aa);e=h+e|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;h=e;V=d;e=e+33554432|0;d=e>>>0<33554432?d+1|0:d;U=e;s=d;f=d>>26;j=(d&67108863)<<6|e>>>26;d=j+Aa|0;e=f+g|0;g=d;d=d>>>0>>0?e+1|0:e;e=g+16777216|0;d=e>>>0<16777216?d+1|0:d;Aa=e;f=t;t=(d&33554431)<<7|e>>>25;e=f+t|0;d=(d>>25)+c|0;d=e>>>0>>0?d+1|0:d;c=e+33554432|0;d=c>>>0<33554432?d+1|0:d;t=c;c=d;d=t&-67108864;F[a+8>>2]=e-d;d=se(H,y,v,E);f=$;j=se(w,x,r,ia);e=j+d|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=se(la,P,G,ea);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;f=se(I,z,ma,S);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;j=se(va,W,o,fa);e=j+e|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;j=se(J,A,wa,_);d=j+e|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;j=se(p,ga,xa,pa);f=j+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=f;j=ba>>31;f=se(M,B,ba,j);e=e+f|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;f=se(m,i,C,ha);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;u=se(n,O,N,D);e=u+e|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;d=b>>26;R=(b&67108863)<<6|R>>>26;b=R+e|0;e=d+f|0;e=b>>>0>>0?e+1|0:e;f=b;d=e;b=f+16777216|0;d=b>>>0<16777216?d+1|0:d;R=b;b=d;d=R&-33554432;F[a+28>>2]=f-d;d=se(J,A,v,E);e=$;u=se(w,x,o,fa);d=u+d|0;f=$+e|0;f=d>>>0>>0?f+1|0:f;u=se(la,P,p,ga);d=u+d|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;u=se(M,B,ma,S);f=u+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=f;f=se(za,ua,C,ha);e=e+f|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;f=se(N,D,ta,ja);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;Q=se(Q,X,r,ia);e=Q+e|0;f=$+d|0;q=se(H,y,q,T);d=q+e|0;e=$+(e>>>0>>0?f+1|0:f)|0;m=se(m,i,G,ea);f=m+d|0;d=$+(d>>>0>>0?e+1|0:e)|0;d=f>>>0>>0?d+1|0:d;e=f;f=se(n,O,I,z);e=e+f|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;m=e;e=c>>26;f=(c&67108863)<<6|t>>>26;c=m+f|0;d=d+e|0;d=c>>>0>>0?d+1|0:d;e=c;c=e+16777216|0;f=c>>>0<16777216?d+1|0:d;m=c;c=f;d=m&-33554432;F[a+12>>2]=e-d;d=se(v,E,sa,da);f=$;i=se(w,x,N,D);e=i+d|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=se(H,y,la,P);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;i=se(ma,S,ka,Y);e=i+e|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;i=se(I,z,va,W);d=i+e|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;i=se(na,Z,wa,_);f=i+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=f;f=se(J,A,xa,pa);e=e+f|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;f=se(ba,j,oa,aa);e=f+e|0;d=$+d|0;d=e>>>0>>0?d+1|0:d;i=ra>>31;q=se(M,B,ra,i);e=q+e|0;f=$+d|0;n=se(n,O,qa,ca);d=n+e|0;e=$+(e>>>0>>0?f+1|0:f)|0;e=d>>>0>>0?e+1|0:e;t=d;d=b>>25;f=(b&33554431)<<7|R>>>25;b=t+f|0;d=d+e|0;d=b>>>0>>0?d+1|0:d;e=b;b=e+33554432|0;d=b>>>0<33554432?d+1|0:d;n=b;b=d;d=n&-67108864;F[a+32>>2]=e-d;d=l&-67108864;e=k-d|0;d=Ba-((d>>>0>k>>>0)+Ca|0)|0;f=e;e=c>>25;k=(c&33554431)<<7|m>>>25;c=f+k|0;d=d+e|0;d=c>>>0>>0?d+1|0:d;e=c+33554432|0;d=e>>>0<33554432?d+1|0:d;d=(K-(Da&-33554432)|0)+((d&67108863)<<6|e>>>26)|0;F[a+20>>2]=d;d=e&-67108864;F[a+16>>2]=c-d;c=se(N,D,v,E);d=$;e=se(w,x,C,ha);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;f=se(la,P,r,ia);c=f+c|0;e=$+d|0;e=c>>>0>>0?e+1|0:e;d=se(H,y,ma,S);c=d+c|0;f=$+e|0;f=c>>>0>>0?f+1|0:f;e=se(va,W,G,ea);c=e+c|0;d=$+f|0;d=c>>>0>>0?d+1|0:d;e=se(I,z,wa,_);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;e=se(o,fa,xa,pa);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;f=se(J,A,ba,j);c=f+c|0;e=$+d|0;e=c>>>0>>0?e+1|0:e;d=se(ra,i,p,ga);c=d+c|0;f=$+e|0;f=c>>>0>>0?f+1|0:f;e=se(M,B,ya,ya>>31);c=e+c|0;d=$+f|0;d=c>>>0>>0?d+1|0:d;e=b>>26;f=c;c=(b&67108863)<<6|n>>>26;b=f+c|0;d=d+e|0;d=b>>>0>>0?d+1|0:d;c=b+16777216|0;d=c>>>0<16777216?d+1|0:d;e=c&-33554432;F[a+36>>2]=b-e;f=g-(Aa&-33554432)|0;b=U&-67108864;e=h-b|0;G=V-((b>>>0>h>>>0)+s|0)|0;b=d;d=d>>25;c=se((b&33554431)<<7|c>>>25,d,19,0);b=c+e|0;e=$+G|0;e=b>>>0>>0?e+1|0:e;d=e;c=b+33554432|0;d=c>>>0<33554432?d+1|0:d;e=c;c=((d&67108863)<<6|e>>>26)+f|0;F[a+4>>2]=c;c=a;a=e&-67108864;F[c>>2]=b-a}function Sa(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0,H=0,I=0,J=0,K=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,aa=0,ba=0,ca=0,da=0,ea=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0;u=_-48|0;_=u;fa(a,b);fa(a+80|0,b+40|0);o=F[b+92>>2];c=o<<1;B=c;C=c>>31;l=F[b+84>>2];c=l<<1;D=c;w=c>>31;c=se(B,C,c,w);g=$;d=c;h=F[b+88>>2];c=h;i=c>>31;ba=c;e=se(c,i,c,i);d=d+e|0;c=$+g|0;c=d>>>0>>0?c+1|0:c;e=d;P=F[b+96>>2];d=P;G=d;J=d>>31;m=F[b+80>>2];d=m<<1;E=d;x=d>>31;g=se(G,J,d,x);d=e+g|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;f=d;g=F[b+108>>2];d=L(g,38);X=d;T=d>>31;H=g;ca=g>>31;e=se(d,T,g,ca);d=f+e|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;e=d;r=F[b+112>>2];d=L(r,19);K=d;M=d>>31;k=F[b+104>>2];d=k<<1;t=se(K,M,d,d>>31);e=e+t|0;d=$+c|0;d=e>>>0>>0?d+1|0:d;f=e;t=F[b+116>>2];c=L(t,38);y=c;z=c>>31;e=F[b+100>>2];c=e<<1;U=c;Q=c>>31;q=se(y,z,c,Q);c=f+q|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;q=c;c=d<<1|c>>>31;q=q<<1;R=c;d=q+33554432|0;c=d>>>0<33554432?c+1|0:c;I=d;N=c;d=c>>26;c=(c&67108863)<<6|I>>>26;v=d;d=se(D,w,G,J);j=$;f=c;c=h<<1;V=c;S=c>>31;h=o;da=h>>31;o=se(c,S,h,da);d=o+d|0;c=$+j|0;c=d>>>0>>0?c+1|0:c;o=e;Y=e>>31;n=se(e,Y,E,x);j=n+d|0;d=$+c|0;d=j>>>0>>0?d+1|0:d;p=j;c=g<<1;ha=c;ea=c>>31;j=se(K,M,c,ea);g=p+j|0;c=$+d|0;c=g>>>0>>0?c+1|0:c;d=g;O=k>>31;g=se(y,z,k,O);d=d+g|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;g=d;d=c<<1|d>>>31;g=g<<1;c=f+g|0;d=d+v|0;v=c;c=c>>>0>>0?d+1|0:d;d=v+16777216|0;c=d>>>0<16777216?c+1|0:c;ka=d;g=d;d=c>>25;c=(c&33554431)<<7|g>>>25;g=d;d=se(B,C,h,da);j=$;f=c;n=se(G,J,V,S);d=n+d|0;c=$+j|0;c=d>>>0>>0?c+1|0:c;j=se(D,w,U,Q);d=j+d|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;n=se(E,x,k,O);j=n+d|0;d=$+c|0;d=j>>>0>>0?d+1|0:d;Z=r>>31;n=se(K,M,r,Z);j=n+j|0;c=$+d|0;c=j>>>0>>0?c+1|0:c;n=se(y,z,ha,ea);j=n+j|0;d=$+c|0;d=j>>>0>>0?d+1|0:d;c=j;n=c<<1;j=f+n|0;c=(d<<1|c>>>31)+g|0;c=j>>>0>>0?c+1|0:c;d=j;g=d+33554432|0;c=g>>>0<33554432?c+1|0:c;aa=g;g=c;c=aa&-67108864;F[a+144>>2]=d-c;c=L(e,38);c=se(c,c>>31,e,Y);d=$;f=c;c=m>>31;e=se(m,c,m,c);c=f+e|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;e=c;c=L(k,19);p=c;A=c>>31;c=G<<1;ia=c;ga=c>>31;m=se(p,A,c,ga);e=e+m|0;c=$+d|0;c=e>>>0>>0?c+1|0:c;d=e;e=se(B,C,X,T);d=d+e|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;m=se(K,M,V,S);e=m+d|0;d=$+c|0;d=e>>>0>>0?d+1|0:d;m=se(D,w,y,z);e=m+e|0;c=$+d|0;c=e>>>0>>0?c+1|0:c;d=e;m=d<<1;c=c<<1|d>>>31;P=c;d=c;c=m+33554432|0;d=c>>>0<33554432?d+1|0:d;j=c;n=d;c=d>>26;d=(d&67108863)<<6|j>>>26;e=c;c=se(p,A,U,Q);s=$;W=d;f=l;ja=f>>31;l=se(E,x,f,ja);d=l+c|0;c=$+s|0;c=d>>>0>>0?c+1|0:c;s=se(G,J,X,T);l=s+d|0;d=$+c|0;d=l>>>0>>0?d+1|0:d;s=se(K,M,B,C);l=s+l|0;c=$+d|0;c=l>>>0>>0?c+1|0:c;s=se(y,z,ba,i);l=s+l|0;d=$+c|0;d=l>>>0>>0?d+1|0:d;c=l;s=c<<1;l=W+s|0;c=(d<<1|c>>>31)+e|0;c=l>>>0>>0?c+1|0:c;d=l+16777216|0;c=d>>>0<16777216?c+1|0:c;s=d;e=d;d=c>>25;c=(c&33554431)<<7|e>>>25;e=d;d=se(E,x,ba,i);la=$;W=c;f=se(D,w,f,ja);d=f+d|0;c=$+la|0;c=d>>>0>>0?c+1|0:c;p=se(p,A,k,O);f=p+d|0;d=$+c|0;d=f>>>0

>>0?d+1|0:d;p=se(U,Q,X,T);f=p+f|0;c=$+d|0;c=f>>>0

>>0?c+1|0:c;d=f;f=se(K,M,ia,ga);d=d+f|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;p=se(y,z,B,C);f=p+d|0;d=$+c|0;d=f>>>0

>>0?d+1|0:d;c=d<<1|f>>>31;f=f<<1;d=W+f|0;c=c+e|0;c=d>>>0>>0?c+1|0:c;e=d;f=d;d=c;c=e+33554432|0;d=c>>>0<33554432?d+1|0:d;p=c;e=d;c=c&-67108864;F[a+128>>2]=f-c;c=se(V,S,o,Y);d=$;f=se(G,J,B,C);c=f+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;A=se(D,w,k,O);f=A+c|0;c=$+d|0;c=f>>>0>>0?c+1|0:c;A=se(E,x,H,ca);f=A+f|0;d=$+c|0;d=f>>>0>>0?d+1|0:d;A=se(y,z,r,Z);f=A+f|0;c=$+d|0;d=f;c=(d>>>0>>0?c+1|0:c)<<1|d>>>31;W=d<<1;d=g>>26;f=(g&67108863)<<6|aa>>>26;g=W+f|0;c=c+d|0;c=g>>>0>>0?c+1|0:c;f=g;d=c;c=g+16777216|0;d=c>>>0<16777216?d+1|0:d;aa=c;g=d;c=c&-33554432;F[a+148>>2]=f-c;c=se(E,x,h,da);h=$;i=se(D,w,ba,i);d=i+c|0;c=$+h|0;c=d>>>0>>0?c+1|0:c;i=se(k,O,X,T);d=i+d|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;h=se(K,M,U,Q);i=h+d|0;d=$+c|0;d=h>>>0>i>>>0?d+1|0:d;c=i;i=se(y,z,G,J);c=c+i|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;i=c;c=d<<1|c>>>31;d=e>>26;f=i<<1;i=(e&67108863)<<6|p>>>26;e=f+i|0;c=c+d|0;c=e>>>0>>0?c+1|0:c;d=e;e=d+16777216|0;c=e>>>0<16777216?c+1|0:c;i=e;e=c;c=i&-33554432;F[a+132>>2]=d-c;c=se(k,O,V,S);h=$;f=se(G,J,G,J);d=f+c|0;c=$+h|0;c=d>>>0>>0?c+1|0:c;h=se(B,C,U,Q);d=h+d|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;h=se(D,w,ha,ea);d=h+d|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;f=se(E,x,r,Z);h=f+d|0;d=$+c|0;d=f>>>0>h>>>0?d+1|0:d;c=h;f=t>>31;h=se(y,z,t,f);c=c+h|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;h=c;c=d<<1|c>>>31;d=g>>25;p=h<<1;h=(g&33554431)<<7|aa>>>25;g=p+h|0;c=c+d|0;c=g>>>0>>0?c+1|0:c;d=g;g=d+33554432|0;c=g>>>0<33554432?c+1|0:c;h=g;g=c;c=h&-67108864;F[a+152>>2]=d-c;v=v-(ka&-33554432)|0;c=I&-67108864;d=q-c|0;q=R-((c>>>0>q>>>0)+N|0)|0;c=e>>25;i=(e&33554431)<<7|i>>>25;e=i+d|0;d=c+q|0;d=e>>>0>>0?d+1|0:d;c=d;d=e+33554432|0;c=d>>>0<33554432?c+1|0:c;c=((c&67108863)<<6|d>>>26)+v|0;F[a+140>>2]=c;c=d&-67108864;F[a+136>>2]=e-c;c=se(B,C,k,O);d=$;e=se(o,Y,ia,ga);c=e+c|0;d=$+d|0;d=c>>>0>>0?d+1|0:d;k=se(V,S,H,ca);e=k+c|0;c=$+d|0;c=e>>>0>>0?c+1|0:c;k=se(D,w,r,Z);e=k+e|0;d=$+c|0;d=e>>>0>>0?d+1|0:d;k=se(E,x,t,f);e=k+e|0;c=$+d|0;d=e;c=(d>>>0>>0?c+1|0:c)<<1|d>>>31;f=d<<1;d=g>>26;e=(g&67108863)<<6|h>>>26;g=f+e|0;c=c+d|0;c=e>>>0>g>>>0?c+1|0:c;d=c;c=g+16777216|0;d=c>>>0<16777216?d+1|0:d;e=c&-33554432;F[a+156>>2]=g-e;k=se((d&33554431)<<7|c>>>25,d>>25,19,0);e=j&-67108864;c=k+(m-e|0)|0;d=$+(P-((e>>>0>m>>>0)+n|0)|0)|0;d=c>>>0>>0?d+1|0:d;g=c+33554432|0;d=g>>>0<33554432?d+1|0:d;d=(l-(s&-33554432)|0)+((d&67108863)<<6|g>>>26)|0;F[a+124>>2]=d;d=g&-67108864;F[a+120>>2]=c-d;c=F[b+44>>2];d=F[b+48>>2];g=F[b+52>>2];e=F[b+56>>2];k=F[b+60>>2];i=F[b- -64>>2];o=F[b+68>>2];r=F[b+72>>2];l=F[b+40>>2];m=F[b>>2];H=F[b+4>>2];t=F[b+8>>2];q=F[b+12>>2];I=F[b+16>>2];h=F[b+20>>2];v=F[b+24>>2];j=F[b+28>>2];R=F[b+32>>2];F[a+76>>2]=F[b+76>>2]+F[b+36>>2];F[a+72>>2]=r+R;F[a+68>>2]=j+o;R=a- -64|0;F[R>>2]=i+v;F[a+60>>2]=h+k;F[a+56>>2]=e+I;F[a+52>>2]=g+q;F[a+48>>2]=d+t;F[a+44>>2]=c+H;F[a+40>>2]=l+m;fa(u,a+40|0);b=F[a+84>>2];c=F[a+88>>2];d=F[a+92>>2];g=F[a+96>>2];e=F[a+100>>2];k=F[a+104>>2];i=F[a+108>>2];o=F[a+112>>2];r=F[a>>2];l=F[a+80>>2];m=F[a+4>>2];H=F[a+8>>2];t=F[a+12>>2];q=F[a+16>>2];I=F[a+20>>2];h=F[a+24>>2];v=F[a+28>>2];j=F[a+32>>2];N=F[a+116>>2];P=F[a+36>>2];n=N-P|0;F[a+116>>2]=n;f=o-j|0;F[a+112>>2]=f;D=i-v|0;F[a+108>>2]=D;w=k-h|0;F[a+104>>2]=w;E=e-I|0;F[a+100>>2]=E;x=g-q|0;F[a+96>>2]=x;y=d-t|0;F[a+92>>2]=y;z=c-H|0;F[a+88>>2]=z;B=b-m|0;F[a+84>>2]=B;C=l-r|0;F[a+80>>2]=C;N=P+N|0;F[a+76>>2]=N;o=j+o|0;F[a+72>>2]=o;i=i+v|0;F[a+68>>2]=i;k=h+k|0;F[R>>2]=k;e=e+I|0;F[a+60>>2]=e;g=g+q|0;F[a+56>>2]=g;d=d+t|0;F[a+52>>2]=d;c=c+H|0;F[a+48>>2]=c;b=b+m|0;F[a+44>>2]=b;r=l+r|0;F[a+40>>2]=r;l=F[u>>2];m=F[u+4>>2];H=F[u+8>>2];t=F[u+12>>2];q=F[u+16>>2];I=F[u+20>>2];h=F[u+24>>2];v=F[u+28>>2];j=F[u+32>>2];F[a+36>>2]=F[u+36>>2]-N;F[a+32>>2]=j-o;F[a+28>>2]=v-i;F[a+24>>2]=h-k;F[a+20>>2]=I-e;F[a+16>>2]=q-g;F[a+12>>2]=t-d;F[a+8>>2]=H-c;F[a+4>>2]=m-b;F[a>>2]=l-r;b=F[a+124>>2];c=F[a+128>>2];d=F[a+132>>2];g=F[a+136>>2];e=F[a+140>>2];k=F[a+144>>2];i=F[a+148>>2];o=F[a+152>>2];r=F[a+120>>2];F[a+156>>2]=F[a+156>>2]-n;F[a+152>>2]=o-f;F[a+148>>2]=i-D;F[a+144>>2]=k-w;F[a+140>>2]=e-E;F[a+136>>2]=g-x;F[a+132>>2]=d-y;F[a+128>>2]=c-z;F[a+124>>2]=b-B;F[a+120>>2]=r-C;_=u+48|0}function Aa(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0;i=_-432|0;_=i;j=i- -64|0;F[j>>2]=0;F[j+4>>2]=0;F[i+72>>2]=0;F[i+76>>2]=0;F[i+80>>2]=0;F[i+84>>2]=0;F[i+88>>2]=0;F[i+92>>2]=0;F[i+96>>2]=0;F[i+100>>2]=0;F[i+104>>2]=0;F[i+108>>2]=0;F[i+48>>2]=0;F[i+52>>2]=0;F[i+56>>2]=0;F[i+60>>2]=0;D[i+15|0]=1;j=c?c:1792;d=c?d:32;a:{if(d>>>0>=65){c=i+224|0;F[c+80>>2]=1779033703;F[c+84>>2]=-1150833019;F[c+72>>2]=0;F[c+76>>2]=0;F[c+64>>2]=0;F[c+104>>2]=528734635;F[c+108>>2]=1541459225;F[c+96>>2]=1359893119;F[c+100>>2]=-1694144372;F[c+88>>2]=1013904242;F[c+92>>2]=-1521486534;ra(c,j,d);Ba(c,i+48|0);break a}ja(i+48|0,j,d)}c=F[i+108>>2];F[i+280>>2]=F[i+104>>2];F[i+284>>2]=c;c=F[i+100>>2];F[i+272>>2]=F[i+96>>2];F[i+276>>2]=c;c=F[i+92>>2];F[i+264>>2]=F[i+88>>2];F[i+268>>2]=c;c=F[i+84>>2];F[i+256>>2]=F[i+80>>2];F[i+260>>2]=c;c=F[i+76>>2];F[i+248>>2]=F[i+72>>2];F[i+252>>2]=c;c=i- -64|0;d=F[c+4>>2];F[i+240>>2]=F[c>>2];F[i+244>>2]=d;c=F[i+60>>2];F[i+232>>2]=F[i+56>>2];F[i+236>>2]=c;c=F[i+52>>2];F[i+224>>2]=F[i+48>>2];F[i+228>>2]=c;c=0;while(1){d=i+224|0;j=d+c|0;D[j|0]=G[j|0]^54;j=d+(c|1)|0;D[j|0]=G[j|0]^54;j=d+(c|2)|0;D[j|0]=G[j|0]^54;d=d+(c|3)|0;D[d|0]=G[d|0]^54;c=c+4|0;if((c|0)!=64){continue}break}c=i+112|0;F[c+80>>2]=1779033703;F[c+84>>2]=-1150833019;F[c+72>>2]=0;F[c+76>>2]=0;F[c+64>>2]=0;F[c+104>>2]=528734635;F[c+108>>2]=1541459225;F[c+96>>2]=1359893119;F[c+100>>2]=-1694144372;F[c+88>>2]=1013904242;F[c+92>>2]=-1521486534;d=i+224|0;ra(c,d,64);ia(d,64);ra(c,a,b);a=F[i+108>>2];F[i+392>>2]=F[i+104>>2];F[i+396>>2]=a;a=F[i+100>>2];F[i+384>>2]=F[i+96>>2];F[i+388>>2]=a;a=F[i+92>>2];F[i+376>>2]=F[i+88>>2];F[i+380>>2]=a;a=F[i+84>>2];F[i+368>>2]=F[i+80>>2];F[i+372>>2]=a;a=F[i+76>>2];F[i+360>>2]=F[i+72>>2];F[i+364>>2]=a;a=i- -64|0;b=F[a+4>>2];F[i+352>>2]=F[a>>2];F[i+356>>2]=b;a=F[i+60>>2];F[i+344>>2]=F[i+56>>2];F[i+348>>2]=a;a=F[i+52>>2];F[i+336>>2]=F[i+48>>2];F[i+340>>2]=a;c=0;while(1){a=i+336|0;b=a+c|0;D[b|0]=G[b|0]^92;b=a+(c|1)|0;D[b|0]=G[b|0]^92;b=a+(c|2)|0;D[b|0]=G[b|0]^92;a=a+(c|3)|0;D[a|0]=G[a|0]^92;c=c+4|0;if((c|0)!=64){continue}break}Ba(i+112|0,i+400|0);a=i+224|0;F[a+80>>2]=1779033703;F[a+84>>2]=-1150833019;F[a+72>>2]=0;F[a+76>>2]=0;F[a+64>>2]=0;F[a+104>>2]=528734635;F[a+108>>2]=1541459225;F[a+96>>2]=1359893119;F[a+100>>2]=-1694144372;F[a+88>>2]=1013904242;F[a+92>>2]=-1521486534;b=i+336|0;ra(a,b,96);Ba(a,i+16|0);ia(a,112);ia(b,96);F[i+80>>2]=0;F[i+84>>2]=0;F[i+88>>2]=0;F[i+92>>2]=0;F[i+96>>2]=0;F[i+100>>2]=0;F[i+104>>2]=0;F[i+108>>2]=0;a=F[i+44>>2];j=F[i+40>>2];F[i+72>>2]=j;F[i+76>>2]=a;b=F[i+36>>2];c=i- -64|0;k=F[i+32>>2];F[c>>2]=k;F[c+4>>2]=b;c=F[i+20>>2];l=F[i+16>>2];F[i+48>>2]=l;F[i+52>>2]=c;d=F[i+28>>2];m=F[i+24>>2];F[i+56>>2]=m;F[i+60>>2]=d;F[i+280>>2]=0;F[i+284>>2]=0;F[i+272>>2]=0;F[i+276>>2]=0;F[i+264>>2]=0;F[i+268>>2]=0;F[i+256>>2]=0;F[i+260>>2]=0;F[i+248>>2]=j;F[i+252>>2]=a;F[i+240>>2]=k;F[i+244>>2]=b;F[i+232>>2]=m;F[i+236>>2]=d;F[i+224>>2]=l;F[i+228>>2]=c;c=0;while(1){a=i+224|0;b=a+c|0;D[b|0]=G[b|0]^54;b=a+(c|1)|0;D[b|0]=G[b|0]^54;b=a+(c|2)|0;D[b|0]=G[b|0]^54;a=a+(c|3)|0;D[a|0]=G[a|0]^54;c=c+4|0;if((c|0)!=64){continue}break}a=i+112|0;F[a+80>>2]=1779033703;F[a+84>>2]=-1150833019;F[a+72>>2]=0;F[a+76>>2]=0;F[a+64>>2]=0;F[a+104>>2]=528734635;F[a+108>>2]=1541459225;F[a+96>>2]=1359893119;F[a+100>>2]=-1694144372;F[a+88>>2]=1013904242;F[a+92>>2]=-1521486534;b=i+224|0;ra(a,b,64);ia(b,64);ra(a,e,f);ra(a,i+15|0,1);a=F[i+108>>2];F[i+392>>2]=F[i+104>>2];F[i+396>>2]=a;a=F[i+100>>2];F[i+384>>2]=F[i+96>>2];F[i+388>>2]=a;a=F[i+92>>2];F[i+376>>2]=F[i+88>>2];F[i+380>>2]=a;a=F[i+84>>2];F[i+368>>2]=F[i+80>>2];F[i+372>>2]=a;a=F[i+76>>2];F[i+360>>2]=F[i+72>>2];F[i+364>>2]=a;a=i- -64|0;b=F[a+4>>2];F[i+352>>2]=F[a>>2];F[i+356>>2]=b;a=F[i+60>>2];F[i+344>>2]=F[i+56>>2];F[i+348>>2]=a;a=F[i+52>>2];F[i+336>>2]=F[i+48>>2];F[i+340>>2]=a;c=0;while(1){a=i+336|0;b=a+c|0;D[b|0]=G[b|0]^92;b=a+(c|1)|0;D[b|0]=G[b|0]^92;b=a+(c|2)|0;D[b|0]=G[b|0]^92;a=a+(c|3)|0;D[a|0]=G[a|0]^92;c=c+4|0;if((c|0)!=64){continue}break}d=i+400|0;Ba(i+112|0,d);a=i+224|0;F[a+80>>2]=1779033703;F[a+84>>2]=-1150833019;F[a+72>>2]=0;F[a+76>>2]=0;F[a+64>>2]=0;F[a+104>>2]=528734635;F[a+108>>2]=1541459225;F[a+96>>2]=1359893119;F[a+100>>2]=-1694144372;F[a+88>>2]=1013904242;F[a+92>>2]=-1521486534;b=i+336|0;ra(a,b,96);Ba(a,i+16|0);ia(a,112);ia(b,96);if(h>>>0>=33){while(1){a=F[i+20>>2];b=F[i+16>>2];D[g|0]=b;D[g+1|0]=b>>>8;D[g+2|0]=b>>>16;D[g+3|0]=b>>>24;D[g+4|0]=a;D[g+5|0]=a>>>8;D[g+6|0]=a>>>16;D[g+7|0]=a>>>24;a=F[i+28>>2];b=F[i+24>>2];D[g+8|0]=b;D[g+9|0]=b>>>8;D[g+10|0]=b>>>16;D[g+11|0]=b>>>24;D[g+12|0]=a;D[g+13|0]=a>>>8;D[g+14|0]=a>>>16;D[g+15|0]=a>>>24;a=F[i+44>>2];b=F[i+40>>2];D[g+24|0]=b;D[g+25|0]=b>>>8;D[g+26|0]=b>>>16;D[g+27|0]=b>>>24;D[g+28|0]=a;D[g+29|0]=a>>>8;D[g+30|0]=a>>>16;D[g+31|0]=a>>>24;a=F[i+36>>2];b=F[i+32>>2];D[g+16|0]=b;D[g+17|0]=b>>>8;D[g+18|0]=b>>>16;D[g+19|0]=b>>>24;D[g+20|0]=a;D[g+21|0]=a>>>8;D[g+22|0]=a>>>16;D[g+23|0]=a>>>24;D[i+15|0]=G[i+15|0]+1;a=F[i+108>>2];F[i+280>>2]=F[i+104>>2];F[i+284>>2]=a;a=F[i+100>>2];F[i+272>>2]=F[i+96>>2];F[i+276>>2]=a;a=F[i+92>>2];F[i+264>>2]=F[i+88>>2];F[i+268>>2]=a;a=F[i+84>>2];F[i+256>>2]=F[i+80>>2];F[i+260>>2]=a;a=F[i+76>>2];F[i+248>>2]=F[i+72>>2];F[i+252>>2]=a;b=i- -64|0;a=b;c=F[a+4>>2];F[i+240>>2]=F[a>>2];F[i+244>>2]=c;a=F[i+60>>2];F[i+232>>2]=F[i+56>>2];F[i+236>>2]=a;a=F[i+52>>2];F[i+224>>2]=F[i+48>>2];F[i+228>>2]=a;g=g+32|0;c=0;while(1){a=i+224|0;j=a+c|0;D[j|0]=G[j|0]^54;j=a+(c|1)|0;D[j|0]=G[j|0]^54;j=a+(c|2)|0;D[j|0]=G[j|0]^54;a=a+(c|3)|0;D[a|0]=G[a|0]^54;c=c+4|0;if((c|0)!=64){continue}break}a=i+112|0;F[a+80>>2]=1779033703;F[a+84>>2]=-1150833019;F[a+72>>2]=0;F[a+76>>2]=0;F[a+64>>2]=0;F[a+104>>2]=528734635;F[a+108>>2]=1541459225;F[a+96>>2]=1359893119;F[a+100>>2]=-1694144372;F[a+88>>2]=1013904242;F[a+92>>2]=-1521486534;c=i+224|0;ra(a,c,64);ia(c,64);ra(a,i+16|0,32);ra(a,e,f);ra(a,i+15|0,1);a=F[i+108>>2];F[i+392>>2]=F[i+104>>2];F[i+396>>2]=a;a=F[i+100>>2];F[i+384>>2]=F[i+96>>2];F[i+388>>2]=a;a=F[i+92>>2];F[i+376>>2]=F[i+88>>2];F[i+380>>2]=a;a=F[i+84>>2];F[i+368>>2]=F[i+80>>2];F[i+372>>2]=a;a=F[i+76>>2];F[i+360>>2]=F[i+72>>2];F[i+364>>2]=a;a=F[b+4>>2];F[i+352>>2]=F[b>>2];F[i+356>>2]=a;a=F[i+60>>2];F[i+344>>2]=F[i+56>>2];F[i+348>>2]=a;a=F[i+52>>2];F[i+336>>2]=F[i+48>>2];F[i+340>>2]=a;c=0;while(1){a=i+336|0;b=a+c|0;D[b|0]=G[b|0]^92;b=a+(c|1)|0;D[b|0]=G[b|0]^92;b=a+(c|2)|0;D[b|0]=G[b|0]^92;a=a+(c|3)|0;D[a|0]=G[a|0]^92;c=c+4|0;if((c|0)!=64){continue}break}Ba(i+112|0,d);a=i+224|0;F[a+80>>2]=1779033703;F[a+84>>2]=-1150833019;F[a+72>>2]=0;F[a+76>>2]=0;F[a+64>>2]=0;F[a+104>>2]=528734635;F[a+108>>2]=1541459225;F[a+96>>2]=1359893119;F[a+100>>2]=-1694144372;F[a+88>>2]=1013904242;F[a+92>>2]=-1521486534;b=i+336|0;ra(a,b,96);Ba(a,i+16|0);ia(a,112);ia(b,96);h=h-32|0;if(h>>>0>32){continue}break}}a=i+16|0;ja(g,a,h);ia(i+112|0,112);ia(i+48|0,64);ia(a,32);_=i+432|0}function ua(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,H=0;A=_-640|0;_=A;c=a- -64|0;g=F[c>>2];j=F[c+4>>2];w=F[a+56>>2];e=F[a+60>>2];r=F[a+48>>2];m=F[a+52>>2];p=F[a+40>>2];f=F[a+44>>2];u=F[a+32>>2];k=F[a+36>>2];s=F[a+24>>2];i=F[a+28>>2];n=F[a+16>>2];v=F[a+20>>2];q=F[a+8>>2];o=F[a+12>>2];while(1){c=x<<3;y=c+A|0;c=b+c|0;d=G[c+4|0]|G[c+5|0]<<8|(G[c+6|0]<<16|G[c+7|0]<<24);h=G[c|0]|G[c+1|0]<<8|(G[c+2|0]<<16|G[c+3|0]<<24);z=h<<24|h<<8&16711680;F[y>>2]=((d&255)<<24|h>>>8)&-16777216|((d&16777215)<<8|h>>>24)&16711680|(d>>>8&65280|d>>>24);c=0;F[y+4>>2]=(d<<24|h>>>8)&65280|(d<<8|h>>>24)&255|z|(c|c);x=x+1|0;if((x|0)!=16){continue}break}b=16;h=F[A>>2];x=h;l=F[A+4>>2];d=l;while(1){z=d;y=(b<<3)+A|0;c=y-56|0;d=F[c>>2];B=F[c+4>>2];t=y-16|0;c=F[t+4>>2];t=F[t>>2];C=ve(t,c,45);E=$;D=x;H=d;x=ve(t,c,3)^C;d=c;c=c>>>6|0;x=x^((d&63)<<26|t>>>6);d=H+x|0;c=(c^($^E))+B|0;c=d>>>0>>0?c+1|0:c;x=d;d=D+d|0;c=c+z|0;t=d;z=d>>>0>>0?c+1|0:c;d=y-120|0;c=F[d+4>>2];x=F[d>>2];d=ve(x,c,63);B=$;D=d;d=c;C=((c&127)<<25|x>>>7)^(D^ve(x,c,56));t=C+t|0;c=($^B^c>>>7)+z|0;F[y>>2]=t;F[y+4>>2]=t>>>0>>0?c+1|0:c;b=b+1|0;if((b|0)!=80){continue}break}b=0;while(1){x=b<<3;c=x+2080|0;d=F[c>>2];y=F[c+4>>2];c=ve(p,f,50);z=$;c=ve(p,f,46)^c;z=$^z;t=d;d=g+(ve(p,f,23)^c)|0;c=j+($^z)|0;c=d>>>0>>0?c+1|0:c;g=d;d=t+d|0;c=c+y|0;c=d>>>0>>0?c+1|0:c;d=d+h|0;c=c+l|0;c=d>>>0>>0?c+1|0:c;g=w^p&(r^w);d=g+d|0;c=(e^f&(e^m))+c|0;c=d>>>0>>0?c+1|0:c;g=d;d=ve(q,o,36);j=$;d=ve(q,o,30)^d;h=$^j;y=ve(q,o,25)^d;j=y+g|0;d=c;c=c+($^h)|0;c=j>>>0>>0?c+1|0:c;h=s&(q|n)|q&n;j=h+j|0;c=(i&(o|v)|o&v)+c|0;z=j;c=h>>>0>j>>>0?c+1|0:c;j=ve(j,c,36);y=$;h=c;j=ve(z,c,30)^j;y=$^y;l=n&(q|z)|q&z;j=l+(ve(z,c,25)^j)|0;c=(v&(c|o)|c&o)+($^y)|0;y=j;j=j>>>0>>0?c+1|0:c;l=x|8;c=l+2080|0;t=F[c>>2];B=F[c+4>>2];c=d+k|0;g=g+u|0;c=g>>>0>>0?c+1|0:c;u=g;d=w+(r^g&(p^r))|0;g=c;c=e+(m^c&(f^m))|0;c=d>>>0>>0?c+1|0:c;w=d;d=d+t|0;c=c+B|0;c=d>>>0>>0?c+1|0:c;w=ve(u,g,50);e=$;w=ve(u,g,46)^w;e=$^e;w=ve(u,g,23)^w;d=w+d|0;c=($^e)+c|0;c=d>>>0>>0?c+1|0:c;w=l+A|0;e=F[w>>2];d=e+d|0;c=F[w+4>>2]+c|0;c=d>>>0>>0?c+1|0:c;e=y;y=d;w=d;d=e+d|0;e=j;j=c;c=e+c|0;c=d>>>0>>0?c+1|0:c;w=ve(d,c,36);e=$;l=w;w=c;k=l^ve(d,c,30);l=$^e;e=ve(d,c,25)^k;k=q&(d|z)|d&z;e=e+k|0;c=(o&(c|h)|c&h)+($^l)|0;l=e;e=e>>>0>>0?c+1|0:c;t=x|16;c=t+2080|0;k=r+F[c>>2]|0;c=m+F[c+4>>2]|0;c=k>>>0>>0?c+1|0:c;r=k;m=t+A|0;k=F[m>>2];r=r+k|0;c=F[m+4>>2]+c|0;m=r;r=k>>>0>m>>>0?c+1|0:c;t=m;c=j+i|0;m=s+y|0;c=m>>>0>>0?c+1|0:c;s=m;k=p^m&(p^u);m=t+k|0;j=c;c=(f^c&(f^g))+r|0;c=k>>>0>m>>>0?c+1|0:c;r=m;m=ve(s,j,50);k=$;m=ve(s,j,46)^m;k=$^k;m=ve(s,j,23)^m;r=m+r|0;c=($^k)+c|0;c=r>>>0>>0?c+1|0:c;y=r;m=r;r=m+l|0;l=e;e=c;c=l+c|0;c=r>>>0>>0?c+1|0:c;m=ve(r,c,36);k=$;l=m;m=c;i=l^ve(r,c,30);l=$^k;k=ve(r,c,25)^i;i=z&(d|r)|d&r;k=k+i|0;c=(h&(c|w)|c&w)+($^l)|0;l=k;k=k>>>0>>0?c+1|0:c;t=x|24;c=t+2080|0;i=p+F[c>>2]|0;c=f+F[c+4>>2]|0;c=i>>>0

>>0?c+1|0:c;p=i;f=t+A|0;i=F[f>>2];p=p+i|0;c=F[f+4>>2]+c|0;f=p;p=i>>>0>f>>>0?c+1|0:c;t=f;c=e+v|0;f=n+y|0;c=f>>>0>>0?c+1|0:c;i=u^f&(u^s);e=t+i|0;n=c;c=(g^c&(g^j))+p|0;c=e>>>0>>0?c+1|0:c;p=e;e=ve(f,n,50);i=$;e=ve(f,n,46)^e;i=$^i;e=ve(f,n,23)^e;p=e+p|0;c=($^i)+c|0;c=e>>>0>p>>>0?c+1|0:c;v=p;i=p;p=i+l|0;e=c;c=c+k|0;c=i>>>0>p>>>0?c+1|0:c;k=ve(p,c,36);i=$;y=c;k=ve(p,c,30)^k;i=$^i;l=d&(p|r)|p&r;k=l+(ve(p,c,25)^k)|0;c=(w&(c|m)|c&m)+($^i)|0;c=k>>>0>>0?c+1|0:c;l=k;k=c;t=x|32;c=t+2080|0;i=u+F[c>>2]|0;c=g+F[c+4>>2]|0;c=i>>>0>>0?c+1|0:c;u=i;g=t+A|0;i=F[g>>2];u=u+i|0;c=F[g+4>>2]+c|0;g=u;u=i>>>0>g>>>0?c+1|0:c;i=g;c=e+o|0;g=q+v|0;c=g>>>0>>0?c+1|0:c;q=g;e=s^g&(f^s);g=i+e|0;o=c;c=(j^c&(j^n))+u|0;c=e>>>0>g>>>0?c+1|0:c;u=g;g=ve(q,o,50);e=$;g=ve(q,o,46)^g;e=$^e;g=ve(q,o,23)^g;u=g+u|0;c=($^e)+c|0;c=g>>>0>u>>>0?c+1|0:c;g=u;u=g+l|0;e=c;c=c+k|0;c=g>>>0>u>>>0?c+1|0:c;k=ve(u,c,36);i=$;l=k;k=c;v=l^ve(u,c,30);l=$^i;i=ve(u,c,25)^v;v=r&(p|u)|p&u;i=i+v|0;c=(m&(c|y)|c&y)+($^l)|0;l=i;i=i>>>0>>0?c+1|0:c;t=x|40;c=t+2080|0;v=s+F[c>>2]|0;c=j+F[c+4>>2]|0;c=s>>>0>v>>>0?c+1|0:c;s=v;j=t+A|0;v=F[j>>2];s=s+v|0;c=F[j+4>>2]+c|0;j=s;s=j>>>0>>0?c+1|0:c;v=j;c=e+h|0;j=g+z|0;c=j>>>0>>0?c+1|0:c;g=j;h=f^g&(f^q);e=v+h|0;j=c;c=(n^c&(n^o))+s|0;c=e>>>0>>0?c+1|0:c;s=e;e=ve(g,j,50);h=$;e=ve(g,j,46)^e;h=$^h;e=ve(g,j,23)^e;s=e+s|0;c=($^h)+c|0;c=e>>>0>s>>>0?c+1|0:c;z=s;h=s;s=h+l|0;e=c;c=c+i|0;c=h>>>0>s>>>0?c+1|0:c;h=ve(s,c,36);v=$;i=c;h=ve(s,c,30)^h;v=$^v;l=p&(u|s)|u&s;h=l+(ve(s,c,25)^h)|0;c=(y&(c|k)|c&k)+($^v)|0;c=h>>>0>>0?c+1|0:c;l=h;h=c;t=x|48;c=t+2080|0;v=f+F[c>>2]|0;c=n+F[c+4>>2]|0;c=f>>>0>v>>>0?c+1|0:c;f=v;n=t+A|0;v=F[n>>2];f=f+v|0;c=F[n+4>>2]+c|0;n=f;f=f>>>0>>0?c+1|0:c;v=n;c=e+w|0;n=d+z|0;c=n>>>0>>0?c+1|0:c;w=n;n=q^n&(g^q);d=v+n|0;e=c;c=(o^c&(j^o))+f|0;c=d>>>0>>0?c+1|0:c;f=ve(w,e,50);n=$;f=ve(w,e,46)^f;n=$^n;f=ve(w,e,23)^f;d=f+d|0;c=($^n)+c|0;c=d>>>0>>0?c+1|0:c;z=d;n=d;f=d+l|0;d=c;c=c+h|0;c=f>>>0>>0?c+1|0:c;n=f;f=ve(f,c,36);h=$;v=c;f=ve(n,c,30)^f;h=$^h;l=u&(s|n)|s&n;f=l+(ve(n,c,25)^f)|0;c=(k&(c|i)|c&i)+($^h)|0;c=f>>>0>>0?c+1|0:c;l=f;f=c;x=x|56;c=x+2080|0;h=q+F[c>>2]|0;c=o+F[c+4>>2]|0;c=h>>>0>>0?c+1|0:c;q=h;o=x+A|0;h=F[o>>2];q=q+h|0;c=F[o+4>>2]+c|0;o=q;q=h>>>0>o>>>0?c+1|0:c;h=o;c=d+m|0;o=r+z|0;c=o>>>0>>0?c+1|0:c;r=o;o=g^o&(g^w);d=h+o|0;m=c;c=(j^c&(e^j))+q|0;c=d>>>0>>0?c+1|0:c;q=ve(r,m,50);o=$;q=ve(r,m,46)^q;o=$^o;q=ve(r,m,23)^q;d=q+d|0;c=($^o)+c|0;c=d>>>0>>0?c+1|0:c;h=d;q=d+l|0;d=c;c=c+f|0;c=q>>>0>>0?c+1|0:c;o=c;c=d+y|0;f=h+p|0;c=f>>>0

>>0?c+1|0:c;p=f;f=c;if(b>>>0<=71){b=b+8|0;c=(b<<3)+A|0;h=F[c>>2];l=F[c+4>>2];continue}break}c=F[a+12>>2]+o|0;d=F[a+8>>2];b=d+q|0;F[a+8>>2]=b;F[a+12>>2]=b>>>0>>0?c+1|0:c;c=F[a+20>>2]+v|0;d=F[a+16>>2];b=d+n|0;F[a+16>>2]=b;F[a+20>>2]=b>>>0>>0?c+1|0:c;c=F[a+28>>2]+i|0;d=F[a+24>>2];b=d+s|0;F[a+24>>2]=b;F[a+28>>2]=b>>>0>>0?c+1|0:c;c=F[a+36>>2]+k|0;d=F[a+32>>2];b=d+u|0;F[a+32>>2]=b;F[a+36>>2]=b>>>0>>0?c+1|0:c;c=F[a+44>>2]+f|0;d=F[a+40>>2];b=d+p|0;F[a+40>>2]=b;F[a+44>>2]=b>>>0>>0?c+1|0:c;c=F[a+52>>2]+m|0;d=F[a+48>>2];b=d+r|0;F[a+48>>2]=b;F[a+52>>2]=b>>>0>>0?c+1|0:c;c=F[a+60>>2]+e|0;d=F[a+56>>2];b=d+w|0;F[a+56>>2]=b;F[a+60>>2]=b>>>0>>0?c+1|0:c;c=F[a+68>>2]+j|0;d=F[a+64>>2];b=d+g|0;F[a+64>>2]=b;F[a+68>>2]=b>>>0>>0?c+1|0:c;_=A+640|0}function cc(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;q=Pb(a,c);m=q+2|0;i=(m>>>0)/3|0;if(((m-L(i,3)|0)+(i<<2)|0)-2>>>0>g>>>0){F[a+3216>>2]=2;return-1}g=q+2|0;m=(g>>>0)/3|0;n=((((g-L(m,3)|0)+(m<<2)|0)-2|0)+f|0)-q|0;p=_-16|0;_=p;g=ob(a,c);if(!G[a+3220|0]){g=yb(g)}a:{b:{if(g>>>0>q>>>0){F[a+3216>>2]=2;break b}m=ob(a,c);g=b;if(!G[a+3220|0]){D[n+1|0]=10;D[n|0]=3;b=n+2|0;D[b|0]=32;b=b+1|0;F[p+8>>2]=b;b=b+32|0;D[b|0]=18;b=b+1|0;D[b|0]=32;b=b+1|0;F[p+4>>2]=b;b=b+32|0;D[b|0]=26;b=b+1|0;D[b|0]=32;b=b+1|0;F[p>>2]=b;b=b+32|0;D[b|0]=34;n=b+1|0;b=m;if(b>>>0>=128){while(1){D[n|0]=b|128;n=n+1|0;i=b>>>0>16383;b=b>>>7|0;if(i){continue}break}}D[n|0]=b;F[p+12>>2]=n+1;i=G[a+3289|0]|G[a+3290|0]<<8|(G[a+3291|0]<<16|G[a+3292|0]<<24);h=F[p+8>>2];b=G[a+3285|0]|G[a+3286|0]<<8|(G[a+3287|0]<<16|G[a+3288|0]<<24);D[h|0]=b;D[h+1|0]=b>>>8;D[h+2|0]=b>>>16;D[h+3|0]=b>>>24;D[h+4|0]=i;D[h+5|0]=i>>>8;D[h+6|0]=i>>>16;D[h+7|0]=i>>>24;b=a+3309|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+24|0]=b;D[h+25|0]=b>>>8;D[h+26|0]=b>>>16;D[h+27|0]=b>>>24;D[h+28|0]=i;D[h+29|0]=i>>>8;D[h+30|0]=i>>>16;D[h+31|0]=i>>>24;b=a+3301|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+16|0]=b;D[h+17|0]=b>>>8;D[h+18|0]=b>>>16;D[h+19|0]=b>>>24;D[h+20|0]=i;D[h+21|0]=i>>>8;D[h+22|0]=i>>>16;D[h+23|0]=i>>>24;b=a+3293|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+8|0]=b;D[h+9|0]=b>>>8;D[h+10|0]=b>>>16;D[h+11|0]=b>>>24;D[h+12|0]=i;D[h+13|0]=i>>>8;D[h+14|0]=i>>>16;D[h+15|0]=i>>>24;i=G[a+3225|0]|G[a+3226|0]<<8|(G[a+3227|0]<<16|G[a+3228|0]<<24);h=F[p>>2];b=G[a+3221|0]|G[a+3222|0]<<8|(G[a+3223|0]<<16|G[a+3224|0]<<24);D[h|0]=b;D[h+1|0]=b>>>8;D[h+2|0]=b>>>16;D[h+3|0]=b>>>24;D[h+4|0]=i;D[h+5|0]=i>>>8;D[h+6|0]=i>>>16;D[h+7|0]=i>>>24;b=a+3229|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+8|0]=b;D[h+9|0]=b>>>8;D[h+10|0]=b>>>16;D[h+11|0]=b>>>24;D[h+12|0]=i;D[h+13|0]=i>>>8;D[h+14|0]=i>>>16;D[h+15|0]=i>>>24;b=a+3237|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+16|0]=b;D[h+17|0]=b>>>8;D[h+18|0]=b>>>16;D[h+19|0]=b>>>24;D[h+20|0]=i;D[h+21|0]=i>>>8;D[h+22|0]=i>>>16;D[h+23|0]=i>>>24;b=a+3245|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+24|0]=b;D[h+25|0]=b>>>8;D[h+26|0]=b>>>16;D[h+27|0]=b>>>24;D[h+28|0]=i;D[h+29|0]=i>>>8;D[h+30|0]=i>>>16;D[h+31|0]=i>>>24;i=G[a+3257|0]|G[a+3258|0]<<8|(G[a+3259|0]<<16|G[a+3260|0]<<24);h=F[p+4>>2];b=G[a+3253|0]|G[a+3254|0]<<8|(G[a+3255|0]<<16|G[a+3256|0]<<24);D[h|0]=b;D[h+1|0]=b>>>8;D[h+2|0]=b>>>16;D[h+3|0]=b>>>24;D[h+4|0]=i;D[h+5|0]=i>>>8;D[h+6|0]=i>>>16;D[h+7|0]=i>>>24;b=a+3261|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+8|0]=b;D[h+9|0]=b>>>8;D[h+10|0]=b>>>16;D[h+11|0]=b>>>24;D[h+12|0]=i;D[h+13|0]=i>>>8;D[h+14|0]=i>>>16;D[h+15|0]=i>>>24;b=a+3269|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+16|0]=b;D[h+17|0]=b>>>8;D[h+18|0]=b>>>16;D[h+19|0]=b>>>24;D[h+20|0]=i;D[h+21|0]=i>>>8;D[h+22|0]=i>>>16;D[h+23|0]=i>>>24;b=a+3277|0;i=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);b=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[h+24|0]=b;D[h+25|0]=b>>>8;D[h+26|0]=b>>>16;D[h+27|0]=b>>>24;D[h+28|0]=i;D[h+29|0]=i>>>8;D[h+30|0]=i>>>16;D[h+31|0]=i>>>24;n=F[p+12>>2]}l=_-96|0;_=l;h=a+48|0;i=(h|0)==F[a+44>>2]?0:F[a+112>>2];b=F[a+4>>2];j=aa[F[F[b>>2]+4>>2]](b,c)|0;b=F[a+4>>2];i=zb(i,j,aa[F[F[b>>2]>>2]](b)|0);b=F[a+44>>2];c:{if(((b|0)==(h|0))<<5>>>0>e>>>0){F[a+8>>2]=1;i=-1;break c}if(i>>>0>m>>>0){F[a+8>>2]=2;i=-1;break c}if((b|0)==(h|0)){F[a+44>>2]=a+148;Fa(d,h);b=F[a>>2];m=l- -64|0;za(h,a+152|0,m);Aa(m,32,a+12|0,32,F[b+8>>2],F[b+12>>2],l,64);b=F[l+28>>2];F[a+36>>2]=F[l+24>>2];F[a+40>>2]=b;b=F[l+20>>2];F[a+28>>2]=F[l+16>>2];F[a+32>>2]=b;b=F[l+12>>2];F[a+20>>2]=F[l+8>>2];F[a+24>>2]=b;b=F[l+4>>2];F[a+12>>2]=F[l>>2];F[a+16>>2]=b;b=F[l+36>>2];F[a+116>>2]=F[l+32>>2];F[a+120>>2]=b;b=F[l+44>>2];F[a+124>>2]=F[l+40>>2];F[a+128>>2]=b;b=F[l+52>>2];F[a+132>>2]=F[l+48>>2];F[a+136>>2]=b;b=F[l+60>>2];F[a+140>>2]=F[l+56>>2];F[a+144>>2]=b;F[a+112>>2]=0;ia(l,64);ia(m,32)}b=a+116|0;s=l|4;ka(b,32,1868,1,s);F[l>>2]=F[a+112>>2];ka(b,32,1869,1,b);F[a+112>>2]=F[a+112>>2]+1;b=F[a+4>>2];m=aa[F[F[b>>2]+4>>2]](b,c)|0;o=F[l>>2];b=m;D[n+1|0]=10;D[n|0]=3;k=n+2|0;D[k|0]=32;j=l- -64|0;k=k+1|0;F[j>>2]=k;k=k+32|0;D[k|0]=16;r=k+1|0;if(o>>>0>=128){while(1){D[r|0]=o|128;r=r+1|0;k=o>>>0>16383;o=o>>>7|0;if(k){continue}break}}D[r+1|0]=34;D[r|0]=o;o=r+2|0;if(b>>>0>=128){while(1){D[o|0]=b|128;o=o+1|0;k=b>>>0>16383;b=b>>>7|0;if(k){continue}break}}D[o|0]=b;F[j+4>>2]=o+1;k=G[h+4|0]|G[h+5|0]<<8|(G[h+6|0]<<16|G[h+7|0]<<24);j=F[l+64>>2];b=G[h|0]|G[h+1|0]<<8|(G[h+2|0]<<16|G[h+3|0]<<24);D[j|0]=b;D[j+1|0]=b>>>8;D[j+2|0]=b>>>16;D[j+3|0]=b>>>24;D[j+4|0]=k;D[j+5|0]=k>>>8;D[j+6|0]=k>>>16;D[j+7|0]=k>>>24;k=G[h+28|0]|G[h+29|0]<<8|(G[h+30|0]<<16|G[h+31|0]<<24);b=G[h+24|0]|G[h+25|0]<<8|(G[h+26|0]<<16|G[h+27|0]<<24);D[j+24|0]=b;D[j+25|0]=b>>>8;D[j+26|0]=b>>>16;D[j+27|0]=b>>>24;D[j+28|0]=k;D[j+29|0]=k>>>8;D[j+30|0]=k>>>16;D[j+31|0]=k>>>24;k=G[h+20|0]|G[h+21|0]<<8|(G[h+22|0]<<16|G[h+23|0]<<24);b=G[h+16|0]|G[h+17|0]<<8|(G[h+18|0]<<16|G[h+19|0]<<24);D[j+16|0]=b;D[j+17|0]=b>>>8;D[j+18|0]=b>>>16;D[j+19|0]=b>>>24;D[j+20|0]=k;D[j+21|0]=k>>>8;D[j+22|0]=k>>>16;D[j+23|0]=k>>>24;k=G[h+12|0]|G[h+13|0]<<8|(G[h+14|0]<<16|G[h+15|0]<<24);b=G[h+8|0]|G[h+9|0]<<8|(G[h+10|0]<<16|G[h+11|0]<<24);D[j+8|0]=b;D[j+9|0]=b>>>8;D[j+10|0]=b>>>16;D[j+11|0]=b>>>24;D[j+12|0]=k;D[j+13|0]=k>>>8;D[j+14|0]=k>>>16;D[j+15|0]=k>>>24;b=F[a+4>>2];aa[F[F[b>>2]+8>>2]](b,s,32,g,c,F[l+68>>2],m,n,i)|0;ia(l,36)}_=l+96|0;b=i;if((b|0)!=-1){break a}F[a+3216>>2]=F[a+8>>2];F[a+8>>2]=0}b=-1}_=p+16|0;ia(d,e);a=-1;if((b|0)!=-1){a=q+2|0;b=(a>>>0)/3|0;a=((a-L(b,3)|0)+(b<<2)|0)-2|0;ma((f+a|0)-q|0,q,f)}return a|0}function Rb(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;g=_-208|0;_=g;ab(g+168|0,d,e);f=F[g+172>>2];d=(f|c)!=0;a:{b:{c:{if(f){if(!d){break c}d=F[g+176>>2]==32}if(!d){break c}j=F[g+196>>2];if(!j){break c}e=F[g+180>>2];if(!e|F[g+184>>2]!=32){break c}d=F[g+188>>2];if(!d){break c}if(F[g+192>>2]==32){break b}}F[a+3216>>2]=4;a=-1;break a}d:{if(!c|!f){break d}if(!Ma(c,f)){break d}F[a+3216>>2]=6;a=-1;break a}h=G[f+4|0]|G[f+5|0]<<8|(G[f+6|0]<<16|G[f+7|0]<<24);c=G[f|0]|G[f+1|0]<<8|(G[f+2|0]<<16|G[f+3|0]<<24);D[a+3221|0]=c;D[a+3222|0]=c>>>8;D[a+3223|0]=c>>>16;D[a+3224|0]=c>>>24;D[a+3225|0]=h;D[a+3226|0]=h>>>8;D[a+3227|0]=h>>>16;D[a+3228|0]=h>>>24;h=G[f+28|0]|G[f+29|0]<<8|(G[f+30|0]<<16|G[f+31|0]<<24);i=a+3245|0;c=G[f+24|0]|G[f+25|0]<<8|(G[f+26|0]<<16|G[f+27|0]<<24);D[i|0]=c;D[i+1|0]=c>>>8;D[i+2|0]=c>>>16;D[i+3|0]=c>>>24;D[i+4|0]=h;D[i+5|0]=h>>>8;D[i+6|0]=h>>>16;D[i+7|0]=h>>>24;h=G[f+20|0]|G[f+21|0]<<8|(G[f+22|0]<<16|G[f+23|0]<<24);i=a+3237|0;c=G[f+16|0]|G[f+17|0]<<8|(G[f+18|0]<<16|G[f+19|0]<<24);D[i|0]=c;D[i+1|0]=c>>>8;D[i+2|0]=c>>>16;D[i+3|0]=c>>>24;D[i+4|0]=h;D[i+5|0]=h>>>8;D[i+6|0]=h>>>16;D[i+7|0]=h>>>24;h=G[f+12|0]|G[f+13|0]<<8|(G[f+14|0]<<16|G[f+15|0]<<24);i=a+3229|0;c=G[f+8|0]|G[f+9|0]<<8|(G[f+10|0]<<16|G[f+11|0]<<24);D[i|0]=c;D[i+1|0]=c>>>8;D[i+2|0]=c>>>16;D[i+3|0]=c>>>24;D[i+4|0]=h;D[i+5|0]=h>>>8;D[i+6|0]=h>>>16;D[i+7|0]=h>>>24;f=G[e+28|0]|G[e+29|0]<<8|(G[e+30|0]<<16|G[e+31|0]<<24);h=a+3277|0;c=G[e+24|0]|G[e+25|0]<<8|(G[e+26|0]<<16|G[e+27|0]<<24);D[h|0]=c;D[h+1|0]=c>>>8;D[h+2|0]=c>>>16;D[h+3|0]=c>>>24;D[h+4|0]=f;D[h+5|0]=f>>>8;D[h+6|0]=f>>>16;D[h+7|0]=f>>>24;f=G[e+20|0]|G[e+21|0]<<8|(G[e+22|0]<<16|G[e+23|0]<<24);h=a+3269|0;c=G[e+16|0]|G[e+17|0]<<8|(G[e+18|0]<<16|G[e+19|0]<<24);D[h|0]=c;D[h+1|0]=c>>>8;D[h+2|0]=c>>>16;D[h+3|0]=c>>>24;D[h+4|0]=f;D[h+5|0]=f>>>8;D[h+6|0]=f>>>16;D[h+7|0]=f>>>24;f=G[e+12|0]|G[e+13|0]<<8|(G[e+14|0]<<16|G[e+15|0]<<24);h=a+3261|0;c=G[e+8|0]|G[e+9|0]<<8|(G[e+10|0]<<16|G[e+11|0]<<24);D[h|0]=c;D[h+1|0]=c>>>8;D[h+2|0]=c>>>16;D[h+3|0]=c>>>24;D[h+4|0]=f;D[h+5|0]=f>>>8;D[h+6|0]=f>>>16;D[h+7|0]=f>>>24;f=G[e+4|0]|G[e+5|0]<<8|(G[e+6|0]<<16|G[e+7|0]<<24);c=G[e|0]|G[e+1|0]<<8|(G[e+2|0]<<16|G[e+3|0]<<24);D[a+3253|0]=c;D[a+3254|0]=c>>>8;D[a+3255|0]=c>>>16;D[a+3256|0]=c>>>24;D[a+3257|0]=f;D[a+3258|0]=f>>>8;D[a+3259|0]=f>>>16;D[a+3260|0]=f>>>24;e=G[d+28|0]|G[d+29|0]<<8|(G[d+30|0]<<16|G[d+31|0]<<24);f=a+3309|0;c=G[d+24|0]|G[d+25|0]<<8|(G[d+26|0]<<16|G[d+27|0]<<24);D[f|0]=c;D[f+1|0]=c>>>8;D[f+2|0]=c>>>16;D[f+3|0]=c>>>24;D[f+4|0]=e;D[f+5|0]=e>>>8;D[f+6|0]=e>>>16;D[f+7|0]=e>>>24;e=G[d+20|0]|G[d+21|0]<<8|(G[d+22|0]<<16|G[d+23|0]<<24);f=a+3301|0;c=G[d+16|0]|G[d+17|0]<<8|(G[d+18|0]<<16|G[d+19|0]<<24);D[f|0]=c;D[f+1|0]=c>>>8;D[f+2|0]=c>>>16;D[f+3|0]=c>>>24;D[f+4|0]=e;D[f+5|0]=e>>>8;D[f+6|0]=e>>>16;D[f+7|0]=e>>>24;e=G[d+12|0]|G[d+13|0]<<8|(G[d+14|0]<<16|G[d+15|0]<<24);f=a+3293|0;c=G[d+8|0]|G[d+9|0]<<8|(G[d+10|0]<<16|G[d+11|0]<<24);D[f|0]=c;D[f+1|0]=c>>>8;D[f+2|0]=c>>>16;D[f+3|0]=c>>>24;D[f+4|0]=e;D[f+5|0]=e>>>8;D[f+6|0]=e>>>16;D[f+7|0]=e>>>24;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);c=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);D[a+3285|0]=c;D[a+3286|0]=c>>>8;D[a+3287|0]=c>>>16;D[a+3288|0]=c>>>24;D[a+3289|0]=e;D[a+3290|0]=e>>>8;D[a+3291|0]=e>>>16;D[a+3292|0]=e>>>24;c=F[a+4>>2];fb(g+136|0,j,F[g+200>>2],aa[F[F[c>>2]>>2]](c)|0);c=F[g+152>>2];if(!(F[g+156>>2]==32?c:0)){F[a+3216>>2]=4;a=-1;break a}d=G[c+28|0]|G[c+29|0]<<8|(G[c+30|0]<<16|G[c+31|0]<<24);F[g+128>>2]=G[c+24|0]|G[c+25|0]<<8|(G[c+26|0]<<16|G[c+27|0]<<24);F[g+132>>2]=d;d=G[c+20|0]|G[c+21|0]<<8|(G[c+22|0]<<16|G[c+23|0]<<24);F[g+120>>2]=G[c+16|0]|G[c+17|0]<<8|(G[c+18|0]<<16|G[c+19|0]<<24);F[g+124>>2]=d;d=G[c+12|0]|G[c+13|0]<<8|(G[c+14|0]<<16|G[c+15|0]<<24);F[g+112>>2]=G[c+8|0]|G[c+9|0]<<8|(G[c+10|0]<<16|G[c+11|0]<<24);F[g+116>>2]=d;d=G[c+4|0]|G[c+5|0]<<8|(G[c+6|0]<<16|G[c+7|0]<<24);F[g+104>>2]=G[c|0]|G[c+1|0]<<8|(G[c+2|0]<<16|G[c+3|0]<<24);F[g+108>>2]=d;e=a+3285|0;c=b+164|0;d=F[b+160>>2];e:{f:{if((c|0)!=(d|0)){while(1){if(Ka(c+5|0,e,32)){break f}c=c+72|0;if((d|0)!=(c|0)){continue}break}}c=0;if(!G[b+7364|0]){break f}d=b+7368|0;if(Ka(b+7373|0,e,32)){break e}if(G[b+7364|0]<2){break f}c=Ka(b+7445|0,e,32)?b+7440|0:0}d=c}if(!d){F[a+3216>>2]=6;a=-1;break a}c=d+5|0;za(c,a+3221|0,g);d=b+96|0;b=a+3253|0;za(d,b,g+32|0);za(c,b,g- -64|0);e=_+-64|0;_=e;b=F[a>>2];Aa(g,96,0,0,F[b>>2],F[b+4>>2],e,64);d=a+152|0;c=F[a+148>>2];g:{if((c|0)!=(a+492|0)){c=c+68|0;F[a+148>>2]=c;b=d;break g}b=(((c|0)==(d|0)?-68:0)+a|0)+152|0}c=c-68|0;if((b|0)!=(c|0)){while(1){f=c;c=c-68|0;ja(f,c,68);if((b|0)!=(c|0)){continue}break}}F[a+184>>2]=0;b=F[e+28>>2];F[a+36>>2]=F[e+24>>2];F[a+40>>2]=b;b=F[e+20>>2];F[a+28>>2]=F[e+16>>2];F[a+32>>2]=b;b=F[e+12>>2];F[a+20>>2]=F[e+8>>2];F[a+24>>2]=b;b=F[e+4>>2];F[a+12>>2]=F[e>>2];F[a+16>>2]=b;b=F[e+60>>2];F[a+212>>2]=F[e+56>>2];F[a+216>>2]=b;b=F[e+52>>2];F[a+204>>2]=F[e+48>>2];F[a+208>>2]=b;b=F[e+44>>2];F[a+196>>2]=F[e+40>>2];F[a+200>>2]=b;b=F[e+36>>2];F[a+188>>2]=F[e+32>>2];F[a+192>>2]=b;b=G[g+124|0]|G[g+125|0]<<8|(G[g+126|0]<<16|G[g+127|0]<<24);a=G[g+120|0]|G[g+121|0]<<8|(G[g+122|0]<<16|G[g+123|0]<<24);D[d+16|0]=a;D[d+17|0]=a>>>8;D[d+18|0]=a>>>16;D[d+19|0]=a>>>24;D[d+20|0]=b;D[d+21|0]=b>>>8;D[d+22|0]=b>>>16;D[d+23|0]=b>>>24;b=G[g+116|0]|G[g+117|0]<<8|(G[g+118|0]<<16|G[g+119|0]<<24);a=G[g+112|0]|G[g+113|0]<<8|(G[g+114|0]<<16|G[g+115|0]<<24);D[d+8|0]=a;D[d+9|0]=a>>>8;D[d+10|0]=a>>>16;D[d+11|0]=a>>>24;D[d+12|0]=b;D[d+13|0]=b>>>8;D[d+14|0]=b>>>16;D[d+15|0]=b>>>24;b=G[g+108|0]|G[g+109|0]<<8|(G[g+110|0]<<16|G[g+111|0]<<24);a=G[g+104|0]|G[g+105|0]<<8|(G[g+106|0]<<16|G[g+107|0]<<24);D[d|0]=a;D[d+1|0]=a>>>8;D[d+2|0]=a>>>16;D[d+3|0]=a>>>24;D[d+4|0]=b;D[d+5|0]=b>>>8;D[d+6|0]=b>>>16;D[d+7|0]=b>>>24;b=G[g+132|0]|G[g+133|0]<<8|(G[g+134|0]<<16|G[g+135|0]<<24);a=G[g+128|0]|G[g+129|0]<<8|(G[g+130|0]<<16|G[g+131|0]<<24);D[d+24|0]=a;D[d+25|0]=a>>>8;D[d+26|0]=a>>>16;D[d+27|0]=a>>>24;D[d+28|0]=b;D[d+29|0]=b>>>8;D[d+30|0]=b>>>16;D[d+31|0]=b>>>24;ia(e,64);_=e- -64|0;ia(g,96);a=0}_=g+208|0;return a}function mc(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0;j=_+-64|0;_=j;a:{b:{if((oa(d)|0)==32){if((oa(f)|0)==32){break b}}F[a+3216>>2]=7;d=-1;break a}i=d;d=j+32|0;sa(c,i,d);sa(e,f,j);k=_-224|0;_=k;c:{if(h>>>0<=63){F[a+3216>>2]=1;d=-1;break c}l=k+160|0;Fa(g,l);c=k+96|0;Fa(g+32|0,c);D[a+3220|0]=0;f=G[b+124|0]|G[b+125|0]<<8|(G[b+126|0]<<16|G[b+127|0]<<24);i=a+3245|0;e=G[b+120|0]|G[b+121|0]<<8|(G[b+122|0]<<16|G[b+123|0]<<24);D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=G[b+116|0]|G[b+117|0]<<8|(G[b+118|0]<<16|G[b+119|0]<<24);i=a+3237|0;e=G[b+112|0]|G[b+113|0]<<8|(G[b+114|0]<<16|G[b+115|0]<<24);D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=G[b+108|0]|G[b+109|0]<<8|(G[b+110|0]<<16|G[b+111|0]<<24);i=a+3229|0;e=G[b+104|0]|G[b+105|0]<<8|(G[b+106|0]<<16|G[b+107|0]<<24);D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=G[b+100|0]|G[b+101|0]<<8|(G[b+102|0]<<16|G[b+103|0]<<24);e=G[b+96|0]|G[b+97|0]<<8|(G[b+98|0]<<16|G[b+99|0]<<24);D[a+3221|0]=e;D[a+3222|0]=e>>>8;D[a+3223|0]=e>>>16;D[a+3224|0]=e>>>24;D[a+3225|0]=f;D[a+3226|0]=f>>>8;D[a+3227|0]=f>>>16;D[a+3228|0]=f>>>24;f=F[k+164>>2];e=F[k+160>>2];D[a+3253|0]=e;D[a+3254|0]=e>>>8;D[a+3255|0]=e>>>16;D[a+3256|0]=e>>>24;D[a+3257|0]=f;D[a+3258|0]=f>>>8;D[a+3259|0]=f>>>16;D[a+3260|0]=f>>>24;f=F[k+172>>2];i=a+3261|0;e=F[k+168>>2];D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=F[k+180>>2];i=a+3269|0;e=F[k+176>>2];D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=F[k+188>>2];i=a+3277|0;e=F[k+184>>2];D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=G[j+4|0]|G[j+5|0]<<8|(G[j+6|0]<<16|G[j+7|0]<<24);e=G[j|0]|G[j+1|0]<<8|(G[j+2|0]<<16|G[j+3|0]<<24);D[a+3285|0]=e;D[a+3286|0]=e>>>8;D[a+3287|0]=e>>>16;D[a+3288|0]=e>>>24;D[a+3289|0]=f;D[a+3290|0]=f>>>8;D[a+3291|0]=f>>>16;D[a+3292|0]=f>>>24;f=G[j+12|0]|G[j+13|0]<<8|(G[j+14|0]<<16|G[j+15|0]<<24);i=a+3293|0;e=G[j+8|0]|G[j+9|0]<<8|(G[j+10|0]<<16|G[j+11|0]<<24);D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=G[j+20|0]|G[j+21|0]<<8|(G[j+22|0]<<16|G[j+23|0]<<24);i=a+3301|0;e=G[j+16|0]|G[j+17|0]<<8|(G[j+18|0]<<16|G[j+19|0]<<24);D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;f=G[j+28|0]|G[j+29|0]<<8|(G[j+30|0]<<16|G[j+31|0]<<24);i=a+3309|0;e=G[j+24|0]|G[j+25|0]<<8|(G[j+26|0]<<16|G[j+27|0]<<24);D[i|0]=e;D[i+1|0]=e>>>8;D[i+2|0]=e>>>16;D[i+3|0]=e>>>24;D[i+4|0]=f;D[i+5|0]=f>>>8;D[i+6|0]=f>>>16;D[i+7|0]=f>>>24;za(b+96|0,j,k);za(l,d,k+32|0);za(l,j,k- -64|0);e=_+-64|0;_=e;b=F[a>>2];Aa(k,96,0,0,F[b>>2],F[b+4>>2],e,64);f=a+48|0;d=F[a+44>>2];d:{if((d|0)!=(a+148|0)){d=d+100|0;F[a+44>>2]=d;b=f;break d}b=(((d|0)==(f|0)?-100:0)+a|0)+48|0}d=d-100|0;if((b|0)!=(d|0)){while(1){i=d;d=d-100|0;ja(i,d,100);if((b|0)!=(d|0)){continue}break}}F[a+112>>2]=0;b=F[e+28>>2];F[a+36>>2]=F[e+24>>2];F[a+40>>2]=b;b=F[e+20>>2];F[a+28>>2]=F[e+16>>2];F[a+32>>2]=b;b=F[e+12>>2];F[a+20>>2]=F[e+8>>2];F[a+24>>2]=b;b=F[e+4>>2];F[a+12>>2]=F[e>>2];F[a+16>>2]=b;b=F[e+60>>2];F[a+140>>2]=F[e+56>>2];F[a+144>>2]=b;b=F[e+52>>2];F[a+132>>2]=F[e+48>>2];F[a+136>>2]=b;b=F[e+44>>2];F[a+124>>2]=F[e+40>>2];F[a+128>>2]=b;b=F[e+36>>2];F[a+116>>2]=F[e+32>>2];F[a+120>>2]=b;b=G[c+52|0]|G[c+53|0]<<8|(G[c+54|0]<<16|G[c+55|0]<<24);a=G[c+48|0]|G[c+49|0]<<8|(G[c+50|0]<<16|G[c+51|0]<<24);D[f+48|0]=a;D[f+49|0]=a>>>8;D[f+50|0]=a>>>16;D[f+51|0]=a>>>24;D[f+52|0]=b;D[f+53|0]=b>>>8;D[f+54|0]=b>>>16;D[f+55|0]=b>>>24;b=G[c+44|0]|G[c+45|0]<<8|(G[c+46|0]<<16|G[c+47|0]<<24);a=G[c+40|0]|G[c+41|0]<<8|(G[c+42|0]<<16|G[c+43|0]<<24);D[f+40|0]=a;D[f+41|0]=a>>>8;D[f+42|0]=a>>>16;D[f+43|0]=a>>>24;D[f+44|0]=b;D[f+45|0]=b>>>8;D[f+46|0]=b>>>16;D[f+47|0]=b>>>24;b=G[c+36|0]|G[c+37|0]<<8|(G[c+38|0]<<16|G[c+39|0]<<24);a=G[c+32|0]|G[c+33|0]<<8|(G[c+34|0]<<16|G[c+35|0]<<24);D[f+32|0]=a;D[f+33|0]=a>>>8;D[f+34|0]=a>>>16;D[f+35|0]=a>>>24;D[f+36|0]=b;D[f+37|0]=b>>>8;D[f+38|0]=b>>>16;D[f+39|0]=b>>>24;b=G[c+28|0]|G[c+29|0]<<8|(G[c+30|0]<<16|G[c+31|0]<<24);a=G[c+24|0]|G[c+25|0]<<8|(G[c+26|0]<<16|G[c+27|0]<<24);D[f+24|0]=a;D[f+25|0]=a>>>8;D[f+26|0]=a>>>16;D[f+27|0]=a>>>24;D[f+28|0]=b;D[f+29|0]=b>>>8;D[f+30|0]=b>>>16;D[f+31|0]=b>>>24;b=G[c+20|0]|G[c+21|0]<<8|(G[c+22|0]<<16|G[c+23|0]<<24);a=G[c+16|0]|G[c+17|0]<<8|(G[c+18|0]<<16|G[c+19|0]<<24);D[f+16|0]=a;D[f+17|0]=a>>>8;D[f+18|0]=a>>>16;D[f+19|0]=a>>>24;D[f+20|0]=b;D[f+21|0]=b>>>8;D[f+22|0]=b>>>16;D[f+23|0]=b>>>24;b=G[c+12|0]|G[c+13|0]<<8|(G[c+14|0]<<16|G[c+15|0]<<24);a=G[c+8|0]|G[c+9|0]<<8|(G[c+10|0]<<16|G[c+11|0]<<24);D[f+8|0]=a;D[f+9|0]=a>>>8;D[f+10|0]=a>>>16;D[f+11|0]=a>>>24;D[f+12|0]=b;D[f+13|0]=b>>>8;D[f+14|0]=b>>>16;D[f+15|0]=b>>>24;b=G[c+4|0]|G[c+5|0]<<8|(G[c+6|0]<<16|G[c+7|0]<<24);a=G[c|0]|G[c+1|0]<<8|(G[c+2|0]<<16|G[c+3|0]<<24);D[f|0]=a;D[f+1|0]=a>>>8;D[f+2|0]=a>>>16;D[f+3|0]=a>>>24;D[f+4|0]=b;D[f+5|0]=b>>>8;D[f+6|0]=b>>>16;D[f+7|0]=b>>>24;b=G[c+60|0]|G[c+61|0]<<8|(G[c+62|0]<<16|G[c+63|0]<<24);a=G[c+56|0]|G[c+57|0]<<8|(G[c+58|0]<<16|G[c+59|0]<<24);D[f+56|0]=a;D[f+57|0]=a>>>8;D[f+58|0]=a>>>16;D[f+59|0]=a>>>24;D[f+60|0]=b;D[f+61|0]=b>>>8;D[f+62|0]=b>>>16;D[f+63|0]=b>>>24;ia(e,64);_=e- -64|0;ia(l,64);ia(c,64);ia(k,96);d=0}_=k+224|0;ia(g,h)}_=j- -64|0;return d|0}function ed(a,b,c,d,e,f){a=a|0;b=+b;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0;l=_-560|0;_=l;F[l+44>>2]=0;A(+b);g=v(1)|0;v(0)|0;a:{if((g|0)<0){s=1;w=1034;b=-b;A(+b);g=v(1)|0;v(0)|0;break a}if(e&2048){s=1;w=1037;break a}s=e&1;w=s?1040:1035;z=!s}b:{if((g&2146435072)==2146435072){d=s+3|0;pa(a,32,c,d,e&-65537);na(a,w,s);f=f&32;na(a,b!=b?f?1053:1248:f?1057:1321,3);pa(a,32,c,d,e^8192);i=(c|0)>(d|0)?c:d;break b}u=l+16|0;c:{d:{e:{b=Eb(b,l+44|0);b=b+b;if(b!=0){g=F[l+44>>2];F[l+44>>2]=g-1;r=f|32;if((r|0)!=97){break e}break c}r=f|32;if((r|0)==97){break c}k=F[l+44>>2];m=(d|0)<0?6:d;break d}k=g-29|0;F[l+44>>2]=k;b=b*268435456;m=(d|0)<0?6:d}p=(k|0)<0?l+48|0:l+336|0;h=p;while(1){if(b<4294967296&b>=0){d=~~b>>>0}else{d=0}F[h>>2]=d;h=h+4|0;b=(b-+(d>>>0))*1e9;if(b!=0){continue}break}f:{if((k|0)<=0){d=k;g=h;j=p;break f}j=p;d=k;while(1){d=d>>>0<29?d:29;g=h-4|0;g:{if(j>>>0>g>>>0){break g}i=0;while(1){o=F[g>>2];n=d&31;x=i;if((d&63)>>>0>=32){i=o<>>32-n;o=o<>>0>>0?i+1|0:i;i=te(n,i,1e9);o=se(i,$,1e9,0);F[g>>2]=n-o;g=g-4|0;if(j>>>0<=g>>>0){continue}break}if(!i){break g}j=j-4|0;F[j>>2]=i}while(1){g=h;if(j>>>0>>0){h=g-4|0;if(!F[h>>2]){continue}}break}d=F[l+44>>2]-d|0;F[l+44>>2]=d;h=g;if((d|0)>0){continue}break}}if((d|0)<0){t=((m+25>>>0)/9|0)+1|0;n=(r|0)==102;while(1){d=0-d|0;i=d>>>0<9?d:9;h:{if(g>>>0<=j>>>0){h=F[j>>2];break h}o=1e9>>>i|0;y=-1<>2];F[h>>2]=x+(d>>>i|0);d=L(o,d&y);h=h+4|0;if(h>>>0>>0){continue}break}h=F[j>>2];if(!d){break h}F[g>>2]=d;g=g+4|0}d=i+F[l+44>>2]|0;F[l+44>>2]=d;j=(!h<<2)+j|0;h=n?p:j;g=g-h>>2>(t|0)?h+(t<<2)|0:g;if((d|0)<0){continue}break}}d=0;i:{if(g>>>0<=j>>>0){break i}d=L(p-j>>2,9);h=10;i=F[j>>2];if(i>>>0<10){break i}while(1){d=d+1|0;h=L(h,10);if(i>>>0>=h>>>0){continue}break}}h=(m-((r|0)==102?0:d)|0)-((r|0)==103&(m|0)!=0)|0;if((h|0)<(L(g-p>>2,9)-9|0)){i=h+9216|0;n=(i|0)/9|0;k=((((k|0)<0?4:292)+l|0)+(n<<2)|0)-4048|0;h=10;i=i-L(n,9)|0;if((i|0)<=7){while(1){h=L(h,10);i=i+1|0;if((i|0)!=8){continue}break}}n=F[k>>2];t=(n>>>0)/(h>>>0)|0;i=n-L(h,t)|0;o=k+4|0;j:{if(!i&(o|0)==(g|0)){break j}k:{if(!(t&1)){b=9007199254740992;if(!(D[k-4|0]&1)|((h|0)!=1e9|j>>>0>=k>>>0)){break k}}b=9007199254740994}q=(g|0)==(o|0)?1:1.5;o=h>>>1|0;q=i>>>0>>0?.5:(o|0)==(i|0)?q:1.5;if(!(G[w|0]!=45|z)){q=-q;b=-b}i=n-i|0;F[k>>2]=i;if(b+q==b){break j}d=h+i|0;F[k>>2]=d;if(d>>>0>=1e9){while(1){F[k>>2]=0;k=k-4|0;if(k>>>0>>0){j=j-4|0;F[j>>2]=0}d=F[k>>2]+1|0;F[k>>2]=d;if(d>>>0>999999999){continue}break}}d=L(p-j>>2,9);h=10;i=F[j>>2];if(i>>>0<10){break j}while(1){d=d+1|0;h=L(h,10);if(i>>>0>=h>>>0){continue}break}}h=k+4|0;g=g>>>0>h>>>0?h:g}while(1){h=g;i=g>>>0<=j>>>0;if(!i){g=h-4|0;if(!F[g>>2]){continue}}break}l:{if((r|0)!=103){k=e&8;break l}g=m?m:1;k=(g|0)>(d|0)&(d|0)>-5;m=(k?d^-1:-1)+g|0;f=(k?-1:-2)+f|0;k=e&8;if(k){break l}g=-9;m:{if(i){break m}n=F[h-4>>2];if(!n){break m}i=10;g=0;if((n>>>0)%10|0){break m}while(1){k=g;g=g+1|0;i=L(i,10);if(!((n>>>0)%(i>>>0)|0)){continue}break}g=k^-1}i=L(h-p>>2,9);if((f&-33)==70){k=0;g=(g+i|0)-9|0;g=(g|0)>0?g:0;m=(g|0)>(m|0)?m:g;break l}k=0;g=((d+i|0)+g|0)-9|0;g=(g|0)>0?g:0;m=(g|0)>(m|0)?m:g}i=-1;r=k|m;if(((r?2147483645:2147483646)|0)<(m|0)){break b}n=(((r|0)!=0)+m|0)+1|0;o=f&-33;n:{if((o|0)==70){if((2147483647-n|0)<(d|0)){break b}g=(d|0)>0?d:0;break n}g=d>>31;g=Ra(g+d^g,0,u);if((u-g|0)<=1){while(1){g=g-1|0;D[g|0]=48;if((u-g|0)<2){continue}break}}t=g-2|0;D[t|0]=f;D[g-1|0]=(d|0)<0?45:43;g=u-t|0;if((g|0)>(2147483647-n|0)){break b}}d=g+n|0;if((d|0)>(s^2147483647)){break b}f=d+s|0;pa(a,32,c,f,e);na(a,w,s);pa(a,48,c,f,e^65536);o:{p:{q:{if((o|0)==70){g=l+16|0;d=g|8;k=g|9;i=j>>>0>p>>>0?p:j;j=i;while(1){g=Ra(F[j>>2],0,k);r:{if((i|0)!=(j|0)){if(l+16>>>0>=g>>>0){break r}while(1){g=g-1|0;D[g|0]=48;if(l+16>>>0>>0){continue}break}break r}if((g|0)!=(k|0)){break r}D[l+24|0]=48;g=d}na(a,g,k-g|0);j=j+4|0;if(p>>>0>=j>>>0){continue}break}if(r){na(a,1526,1)}if((m|0)<=0|h>>>0<=j>>>0){break q}while(1){g=Ra(F[j>>2],0,k);if(g>>>0>l+16>>>0){while(1){g=g-1|0;D[g|0]=48;if(l+16>>>0>>0){continue}break}}na(a,g,(m|0)<9?m:9);g=m-9|0;j=j+4|0;if(h>>>0<=j>>>0){break p}d=(m|0)>9;m=g;if(d){continue}break}break p}s:{if((m|0)<0){break s}i=h>>>0>j>>>0?h:j+4|0;g=l+16|0;d=g|8;p=g|9;h=j;while(1){g=Ra(F[h>>2],0,p);if((p|0)==(g|0)){D[l+24|0]=48;g=d}t:{if((h|0)!=(j|0)){if(l+16>>>0>=g>>>0){break t}while(1){g=g-1|0;D[g|0]=48;if(l+16>>>0>>0){continue}break}break t}na(a,g,1);g=g+1|0;if(!(k|m)){break t}na(a,1526,1)}x=g;g=p-g|0;na(a,x,(g|0)<(m|0)?g:m);m=m-g|0;h=h+4|0;if(i>>>0<=h>>>0){break s}if((m|0)>=0){continue}break}}pa(a,48,m+18|0,18,0);na(a,t,u-t|0);break o}g=m}pa(a,48,g+9|0,9,0)}pa(a,32,c,f,e^8192);i=(c|0)>(f|0)?c:f;break b}m=(f<<26>>31&9)+w|0;u:{if(d>>>0>11){break u}g=12-d|0;q=16;while(1){q=q*16;g=g-1|0;if(g){continue}break}if(G[m|0]==45){b=-(q+(-b-q));break u}b=b+q-q}h=F[l+44>>2];g=h>>31;g=Ra(g^g+h,0,u);if((u|0)==(g|0)){D[l+15|0]=48;g=l+15|0}k=s|2;j=f&32;h=F[l+44>>2];p=g-2|0;D[p|0]=f+15;D[g-1|0]=(h|0)<0?45:43;i=e&8;h=l+16|0;while(1){f=h;if(N(b)<2147483648){g=~~b}else{g=-2147483648}D[h|0]=j|G[g+5648|0];b=(b-+(g|0))*16;h=f+1|0;if(!(!((d|0)>0|i)&b==0|(h-(l+16|0)|0)!=1)){D[f+1|0]=46;h=f+2|0}if(b!=0){continue}break}i=-1;n=u-p|0;f=n+k|0;if((2147483645-f|0)<(d|0)){break b}v:{w:{if(!d){break w}j=h-(l+16|0)|0;if((j-2|0)>=(d|0)){break w}g=d+2|0;break v}j=h-(l+16|0)|0;g=j}d=g+f|0;pa(a,32,c,d,e);na(a,m,k);pa(a,48,c,d,e^65536);na(a,l+16|0,j);pa(a,48,g-j|0,0,0);na(a,p,n);pa(a,32,c,d,e^8192);i=(c|0)>(d|0)?c:d}_=l+560|0;return i|0}function Db(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;f=_-80|0;_=f;F[f+76>>2]=b;v=f+55|0;r=f+56|0;b=0;a:{b:{c:{d:{e:while(1){if((2147483647-m|0)<(b|0)){break d}m=b+m|0;f:{g:{h:{l=F[f+76>>2];b=l;k=G[b|0];if(k){while(1){i:{g=k&255;j:{if(!g){k=b;break j}if((g|0)!=37){break i}k=b;while(1){if(G[b+1|0]!=37){break j}g=b+2|0;F[f+76>>2]=g;k=k+1|0;h=G[b+2|0];b=g;if((h|0)==37){continue}break}}b=k-l|0;u=2147483647-m|0;if((b|0)>(u|0)){break d}if(a){na(a,l,b)}if(b){continue e}p=-1;g=1;b=F[f+76>>2];if(!(D[b+1|0]-48>>>0>=10|G[b+2|0]!=36)){p=D[b+1|0]-48|0;t=1;g=3}b=g+b|0;F[f+76>>2]=b;n=0;i=D[b|0];h=i-32|0;k:{if(h>>>0>31){g=b;break k}g=b;j=1<>2]=g;n=j|n;i=D[b+1|0];h=i-32|0;if(h>>>0>=32){break k}b=g;j=1<>>0>=10){break n}b=F[f+76>>2];if(G[b+2|0]!=36){break n}F[((D[b+1|0]<<2)+e|0)-192>>2]=10;o=F[((D[b+1|0]<<3)+d|0)-384>>2];t=1;b=b+3|0;break m}if(t){break h}t=0;o=0;if(a){b=F[c>>2];F[c>>2]=b+4;o=F[b>>2]}b=F[f+76>>2]+1|0}F[f+76>>2]=b;if((o|0)>=0){break l}o=0-o|0;n=n|8192;break l}o=Cb(f+76|0);if((o|0)<0){break d}b=F[f+76>>2]}g=0;j=-1;q=0;o:{if(G[b|0]!=46){break o}if(G[b+1|0]==42){p:{q:{if(D[b+2|0]-48>>>0>=10){break q}b=F[f+76>>2];if(G[b+3|0]!=36){break q}F[((D[b+2|0]<<2)+e|0)-192>>2]=10;j=F[((D[b+2|0]<<3)+d|0)-384>>2];b=b+4|0;break p}if(t){break h}if(a){b=F[c>>2];F[c>>2]=b+4;j=F[b>>2]}else{j=0}b=F[f+76>>2]+2|0}F[f+76>>2]=b;q=(j^-1)>>>31|0;break o}F[f+76>>2]=b+1;j=Cb(f+76|0);b=F[f+76>>2];q=1}while(1){s=g;k=28;if(D[b|0]-123>>>0<4294967238){break c}i=b+1|0;F[f+76>>2]=i;g=D[b|0];b=i;g=G[(g+L(s,58)|0)+5119|0];if(g-1>>>0<8){continue}break}r:{s:{if((g|0)!=27){if(!g){break c}if((p|0)>=0){F[(p<<2)+e>>2]=g;b=(p<<3)+d|0;g=F[b+4>>2];F[f+64>>2]=F[b>>2];F[f+68>>2]=g;break s}if(!a){break f}Bb(f- -64|0,g,c);i=F[f+76>>2];break r}if((p|0)>=0){break c}}b=0;if(!a){continue e}}h=n&-65537;g=n&8192?h:n;n=0;p=1024;k=r;t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{b=D[i-1|0];b=s?(b&15)==3?b&-33:b:b;switch(b-88|0){case 11:break t;case 9:case 13:case 14:case 15:break u;case 27:break z;case 12:case 17:break C;case 23:break D;case 0:case 32:break E;case 24:break F;case 22:break G;case 29:break H;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 10:case 16:case 18:case 19:case 20:case 21:case 25:case 26:case 28:case 30:case 31:break g;default:break I}}J:{switch(b-65|0){case 0:case 4:case 5:case 6:break u;case 2:break x;case 1:case 3:break g;default:break J}}if((b|0)==83){break y}break g}i=F[f+64>>2];h=F[f+68>>2];p=1024;break B}b=0;K:{switch(s&255){case 0:F[F[f+64>>2]>>2]=m;continue e;case 1:F[F[f+64>>2]>>2]=m;continue e;case 2:g=F[f+64>>2];F[g>>2]=m;F[g+4>>2]=m>>31;continue e;case 3:E[F[f+64>>2]>>1]=m;continue e;case 4:D[F[f+64>>2]]=m;continue e;case 6:F[F[f+64>>2]>>2]=m;continue e;case 7:break K;default:continue e}}g=F[f+64>>2];F[g>>2]=m;F[g+4>>2]=m>>31;continue e}j=j>>>0>8?j:8;g=g|8;b=120}l=r;w=b&32;i=F[f+64>>2];h=F[f+68>>2];if(i|h){while(1){l=l-1|0;D[l|0]=w|G[(i&15)+5648|0];x=!h&i>>>0>15|(h|0)!=0;s=h;h=h>>>4|0;i=(s&15)<<28|i>>>4;if(x){continue}break}}if(!(F[f+64>>2]|F[f+68>>2])|!(g&8)){break A}p=(b>>>4|0)+1024|0;n=2;break A}b=r;i=F[f+64>>2];h=F[f+68>>2];if(i|h){while(1){b=b-1|0;D[b|0]=i&7|48;s=!h&i>>>0>7|(h|0)!=0;l=h;h=h>>>3|0;i=(l&7)<<29|i>>>3;if(s){continue}break}}l=b;if(!(g&8)){break A}b=r-l|0;j=(b|0)<(j|0)?j:b+1|0;break A}b=F[f+68>>2];h=b;i=F[f+64>>2];if((b|0)<0){h=0-(h+((i|0)!=0)|0)|0;i=0-i|0;F[f+64>>2]=i;F[f+68>>2]=h;n=1;p=1024;break B}if(g&2048){n=1;p=1025;break B}n=g&1;p=n?1026:1024}l=Ra(i,h,r)}if((j|0)<0?q:0){break d}g=q?g&-65537:g;h=F[f+64>>2];b=F[f+68>>2];if(!(j|(h|b)!=0)){l=r;k=l;j=0;break g}b=!(b|h)+(r-l|0)|0;j=(b|0)<(j|0)?j:b;break g}q=(j|0)<0?2147483647:j;i=q;g=(i|0)!=0;b=F[f+64>>2];l=b?b:1528;k=l;b=l;L:{M:{N:{O:{if(!(b&3)|!i){break O}while(1){if(!G[b|0]){break N}i=i-1|0;g=(i|0)!=0;b=b+1|0;if(!(b&3)){break O}if(i){continue}break}}if(!g){break M}}P:{if(!G[b|0]|i>>>0<4){break P}while(1){g=F[b>>2];if((g^-1)&g-16843009&-2139062144){break P}b=b+4|0;i=i-4|0;if(i>>>0>3){continue}break}}if(!i){break M}while(1){if(!G[b|0]){break L}b=b+1|0;i=i-1|0;if(i){continue}break}}b=0}b=b?b-k|0:q;k=b+l|0;if((j|0)>=0){g=h;j=b;break g}g=h;j=b;if(G[k|0]){break d}break g}if(j){k=F[f+64>>2];break w}b=0;pa(a,32,o,0,g);break v}F[f+12>>2]=0;F[f+8>>2]=F[f+64>>2];k=f+8|0;F[f+64>>2]=k;j=-1}b=0;Q:{while(1){h=F[k>>2];if(!h){break Q}h=Ab(f+4|0,h);l=(h|0)<0;if(!(l|h>>>0>j-b>>>0)){k=k+4|0;b=b+h|0;if(j>>>0>b>>>0){continue}break Q}break}if(l){break b}}k=61;if((b|0)<0){break c}pa(a,32,o,b,g);if(!b){b=0;break v}j=0;k=F[f+64>>2];while(1){h=F[k>>2];if(!h){break v}h=Ab(f+4|0,h);j=h+j|0;if(j>>>0>b>>>0){break v}na(a,f+4|0,h);k=k+4|0;if(b>>>0>j>>>0){continue}break}}pa(a,32,o,b,g^8192);b=(b|0)<(o|0)?o:b;continue e}if((j|0)<0?q:0){break d}k=61;b=aa[6](a,K[f+64>>3],o,j,g,b)|0;if((b|0)>=0){continue e}break c}D[f+55|0]=F[f+64>>2];j=1;l=v;g=h;break g}g=b+1|0;F[f+76>>2]=g;k=G[b+1|0];b=g;continue}}if(a){break a}if(!t){break f}b=1;while(1){a=F[(b<<2)+e>>2];if(a){Bb((b<<3)+d|0,a,c);m=1;b=b+1|0;if((b|0)!=10){continue}break a}break}m=1;if(b>>>0>=10){break a}while(1){if(F[(b<<2)+e>>2]){break h}b=b+1|0;if((b|0)!=10){continue}break}break a}k=28;break c}i=k-l|0;j=(j|0)<(i|0)?i:j;if((j|0)>(2147483647-n|0)){break d}k=61;h=j+n|0;b=(h|0)>(o|0)?h:o;if((u|0)<(b|0)){break c}pa(a,32,b,h,g);na(a,p,n);pa(a,48,b,h,g^65536);pa(a,48,j,i,0);na(a,l,i);pa(a,32,b,h,g^8192);continue}break}m=0;break a}k=61}F[9343]=k}m=-1}_=f+80|0;return m}function ac(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=oa(d);if((j|0)==-1){F[a+3216>>2]=7;return-1}sa(c,d,c);d=j;l=_-48|0;_=l;a:{if((b|0)!=1){ab(l+8|0,c,d);c=F[l+36>>2];if(!c){F[a+3216>>2]=4;b=-1;break a}d=F[l+40>>2]}b=-1;h=_-240|0;_=h;g=a;a=F[a+4>>2];fb(h+8|0,c,d,aa[F[F[a>>2]>>2]](a)|0);b:{if(G[h+8|0]!=3){F[g+8>>2]=3;j=-1;break b}if(F[h+32>>2]?!G[h+9|0]|!F[h+24>>2]:1){F[g+8>>2]=4;j=-1;break b}a=F[g+4>>2];if(aa[F[F[a>>2]+12>>2]](a,F[h+36>>2])>>>0>f>>>0){F[g+8>>2]=2;j=-1;break b}if(F[h+28>>2]!=32){F[g+8>>2]=4;j=-1;break b}c:{d:{e:{f:{g:{c=g+152|0;j=F[g+148>>2];if((c|0)!=(j|0)){d=F[h+24>>2];a=c;while(1){if(!Ma(a,d)){break g}a=a+68|0;if((j|0)!=(a|0)){continue}break}}j=g+48|0;if((j|0)==F[g+44>>2]|I[h+12>>2]>=2001){break f}i=F[h+24>>2];a=G[i+12|0]|G[i+13|0]<<8|(G[i+14|0]<<16|G[i+15|0]<<24);F[h+48>>2]=G[i+8|0]|G[i+9|0]<<8|(G[i+10|0]<<16|G[i+11|0]<<24);F[h+52>>2]=a;a=G[i+20|0]|G[i+21|0]<<8|(G[i+22|0]<<16|G[i+23|0]<<24);F[h+56>>2]=G[i+16|0]|G[i+17|0]<<8|(G[i+18|0]<<16|G[i+19|0]<<24);F[h+60>>2]=a;a=G[i+28|0]|G[i+29|0]<<8|(G[i+30|0]<<16|G[i+31|0]<<24);d=h- -64|0;F[d>>2]=G[i+24|0]|G[i+25|0]<<8|(G[i+26|0]<<16|G[i+27|0]<<24);F[d+4>>2]=a;a=G[i+4|0]|G[i+5|0]<<8|(G[i+6|0]<<16|G[i+7|0]<<24);F[h+40>>2]=G[i|0]|G[i+1|0]<<8|(G[i+2|0]<<16|G[i+3|0]<<24);F[h+44>>2]=a;a=F[g>>2];i=h+40|0;k=h+208|0;za(j,i,k);j=h+144|0;Aa(k,32,g+12|0,32,F[a+8>>2],F[a+12>>2],j,64);d=F[h+172>>2];F[h+136>>2]=F[h+168>>2];F[h+140>>2]=d;a=F[h+164>>2];F[h+128>>2]=F[h+160>>2];F[h+132>>2]=a;a=F[h+180>>2];F[h+76>>2]=F[h+176>>2];F[h+80>>2]=a;a=F[h+188>>2];F[h+84>>2]=F[h+184>>2];F[h+88>>2]=a;a=F[h+196>>2];F[h+92>>2]=F[h+192>>2];F[h+96>>2]=a;a=F[h+204>>2];F[h+100>>2]=F[h+200>>2];F[h+104>>2]=a;F[h+72>>2]=0;a=F[h+156>>2];F[h+120>>2]=F[h+152>>2];F[h+124>>2]=a;a=F[h+148>>2];F[h+112>>2]=F[h+144>>2];F[h+116>>2]=a;ia(j,64);ia(k,32);j=Tb(g,h+72|0,h+8|0,e,f);ia(h+112|0,32);ia(i,68);if((j|0)==-1){break f}d=F[g+148>>2];if((d|0)==(g+492|0)){break e}d=d+68|0;F[g+148>>2]=d;break d}c=F[h+12>>2];if(c>>>0>2]){d=g+496|0;i=F[g+492>>2];if((d|0)==(i|0)){break f}while(1){h:{if(F[d+32>>2]!=(c|0)){break h}if(Ma(d,F[h+24>>2])){break h}a=F[g+4>>2];j=aa[F[F[a>>2]+16>>2]](a,d+36|0,32,F[h+16>>2],F[h+20>>2],F[h+32>>2],F[h+36>>2],e,f)|0;if((j|0)==-1){break h}ia(d,68);a=F[g+492>>2]-68|0;F[g+492>>2]=a;if((a|0)==(d|0)){break b}while(1){a=d;d=d+68|0;ja(a,d,68);if(F[g+492>>2]!=(d|0)){continue}break}break b}d=d+68|0;if((i|0)==(d|0)){break f}c=F[h+12>>2];continue}}j=Tb(g,a+32|0,h+8|0,e,f);if((j|0)!=-1){break c}}F[g+8>>2]=5;j=-1;break b}c=(g+((c|0)==(d|0)?-68:0)|0)+152|0}d=d-68|0;if((d|0)!=(c|0)){while(1){a=d;d=d-68|0;ja(a,d,68);if((c|0)!=(d|0)){continue}break}}e=F[h+24>>2];d=G[e+4|0]|G[e+5|0]<<8|(G[e+6|0]<<16|G[e+7|0]<<24);a=G[e|0]|G[e+1|0]<<8|(G[e+2|0]<<16|G[e+3|0]<<24);D[c|0]=a;D[c+1|0]=a>>>8;D[c+2|0]=a>>>16;D[c+3|0]=a>>>24;D[c+4|0]=d;D[c+5|0]=d>>>8;D[c+6|0]=d>>>16;D[c+7|0]=d>>>24;d=G[e+28|0]|G[e+29|0]<<8|(G[e+30|0]<<16|G[e+31|0]<<24);a=G[e+24|0]|G[e+25|0]<<8|(G[e+26|0]<<16|G[e+27|0]<<24);D[c+24|0]=a;D[c+25|0]=a>>>8;D[c+26|0]=a>>>16;D[c+27|0]=a>>>24;D[c+28|0]=d;D[c+29|0]=d>>>8;D[c+30|0]=d>>>16;D[c+31|0]=d>>>24;d=G[e+20|0]|G[e+21|0]<<8|(G[e+22|0]<<16|G[e+23|0]<<24);a=G[e+16|0]|G[e+17|0]<<8|(G[e+18|0]<<16|G[e+19|0]<<24);D[c+16|0]=a;D[c+17|0]=a>>>8;D[c+18|0]=a>>>16;D[c+19|0]=a>>>24;D[c+20|0]=d;D[c+21|0]=d>>>8;D[c+22|0]=d>>>16;D[c+23|0]=d>>>24;d=G[e+12|0]|G[e+13|0]<<8|(G[e+14|0]<<16|G[e+15|0]<<24);a=G[e+8|0]|G[e+9|0]<<8|(G[e+10|0]<<16|G[e+11|0]<<24);D[c+8|0]=a;D[c+9|0]=a>>>8;D[c+10|0]=a>>>16;D[c+11|0]=a>>>24;D[c+12|0]=d;D[c+13|0]=d>>>8;D[c+14|0]=d>>>16;D[c+15|0]=d>>>24;e=F[g>>2];a=_-96|0;_=a;d=g+48|0;m=a- -64|0;za(d,c,m);Aa(m,32,g+12|0,32,F[e+8>>2],F[e+12>>2],a,64);f=F[a+28>>2];e=F[a+24>>2];D[g+36|0]=e;D[g+37|0]=e>>>8;D[g+38|0]=e>>>16;D[g+39|0]=e>>>24;D[g+40|0]=f;D[g+41|0]=f>>>8;D[g+42|0]=f>>>16;D[g+43|0]=f>>>24;f=F[a+20>>2];e=F[a+16>>2];D[g+28|0]=e;D[g+29|0]=e>>>8;D[g+30|0]=e>>>16;D[g+31|0]=e>>>24;D[g+32|0]=f;D[g+33|0]=f>>>8;D[g+34|0]=f>>>16;D[g+35|0]=f>>>24;f=F[a+12>>2];e=F[a+8>>2];D[g+20|0]=e;D[g+21|0]=e>>>8;D[g+22|0]=e>>>16;D[g+23|0]=e>>>24;D[g+24|0]=f;D[g+25|0]=f>>>8;D[g+26|0]=f>>>16;D[g+27|0]=f>>>24;f=F[a+4>>2];e=F[a>>2];D[g+12|0]=e;D[g+13|0]=e>>>8;D[g+14|0]=e>>>16;D[g+15|0]=e>>>24;D[g+16|0]=f;D[g+17|0]=f>>>8;D[g+18|0]=f>>>16;D[g+19|0]=f>>>24;n=F[a+40>>2];o=F[a+44>>2];p=F[a+48>>2];q=F[a+52>>2];k=F[a+56>>2];i=F[a+60>>2];f=F[a+32>>2];e=F[a+36>>2];F[c+32>>2]=0;F[c+60>>2]=k;F[c+64>>2]=i;F[c+52>>2]=p;F[c+56>>2]=q;F[c+44>>2]=n;F[c+48>>2]=o;F[c+36>>2]=f;F[c+40>>2]=e;ia(a,64);ia(m,32);_=a+96|0;ia(d,100);a=F[g+44>>2]-100|0;F[g+44>>2]=a;if((a|0)!=(d|0)){while(1){a=d;d=d+100|0;ja(a,d,100);if(F[g+44>>2]!=(d|0)){continue}break}}a=c}if(I[a+32>>2]>2]){f=g+532|0;i=a+36|0;c=g+3216|0;k=g+496|0;while(1){d=c;e=F[g+492>>2];if((d|0)!=(e|0)){d=e+68|0;F[g+492>>2]=d}d=d-68|0;if((k|0)!=(d|0)){while(1){e=d;d=d-68|0;ja(e,d,68);if((d|0)!=(k|0)){continue}break}}ka(i,32,1868,1,f);F[g+528>>2]=F[a+32>>2];d=F[a+28>>2];F[k+24>>2]=F[a+24>>2];F[k+28>>2]=d;d=F[a+20>>2];F[k+16>>2]=F[a+16>>2];F[k+20>>2]=d;d=F[a+12>>2];F[k+8>>2]=F[a+8>>2];F[k+12>>2]=d;d=F[a+4>>2];F[k>>2]=F[a>>2];F[k+4>>2]=d;ka(i,32,1869,1,i);d=F[a+32>>2]+1|0;F[a+32>>2]=d;if(d>>>0>2]){continue}break}}c=a+36|0;ka(c,32,1869,1,c);F[a+32>>2]=F[a+32>>2]+1}_=h+240|0;a=j;if((a|0)==-1){F[g+3216>>2]=F[g+8>>2];F[g+8>>2]=0;break a}D[g+3220|0]=1;b=a}_=l+48|0;return b|0}function Gc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;i=Ob(a);if(Da(i)>>>0>e>>>0){F[a+3216>>2]=2;return-1}e=la(_a(d,i),1);D[e|0]=G[a+3220|0];f=a+3221|0;g=G[f+4|0]|G[f+5|0]<<8|(G[f+6|0]<<16|G[f+7|0]<<24);e=e+1|0;h=G[f|0]|G[f+1|0]<<8|(G[f+2|0]<<16|G[f+3|0]<<24);D[e|0]=h;D[e+1|0]=h>>>8;D[e+2|0]=h>>>16;D[e+3|0]=h>>>24;D[e+4|0]=g;D[e+5|0]=g>>>8;D[e+6|0]=g>>>16;D[e+7|0]=g>>>24;g=G[f+28|0]|G[f+29|0]<<8|(G[f+30|0]<<16|G[f+31|0]<<24);h=G[f+24|0]|G[f+25|0]<<8|(G[f+26|0]<<16|G[f+27|0]<<24);D[e+24|0]=h;D[e+25|0]=h>>>8;D[e+26|0]=h>>>16;D[e+27|0]=h>>>24;D[e+28|0]=g;D[e+29|0]=g>>>8;D[e+30|0]=g>>>16;D[e+31|0]=g>>>24;g=G[f+20|0]|G[f+21|0]<<8|(G[f+22|0]<<16|G[f+23|0]<<24);h=G[f+16|0]|G[f+17|0]<<8|(G[f+18|0]<<16|G[f+19|0]<<24);D[e+16|0]=h;D[e+17|0]=h>>>8;D[e+18|0]=h>>>16;D[e+19|0]=h>>>24;D[e+20|0]=g;D[e+21|0]=g>>>8;D[e+22|0]=g>>>16;D[e+23|0]=g>>>24;g=G[f+12|0]|G[f+13|0]<<8|(G[f+14|0]<<16|G[f+15|0]<<24);f=G[f+8|0]|G[f+9|0]<<8|(G[f+10|0]<<16|G[f+11|0]<<24);D[e+8|0]=f;D[e+9|0]=f>>>8;D[e+10|0]=f>>>16;D[e+11|0]=f>>>24;D[e+12|0]=g;D[e+13|0]=g>>>8;D[e+14|0]=g>>>16;D[e+15|0]=g>>>24;f=a+3253|0;g=G[f+4|0]|G[f+5|0]<<8|(G[f+6|0]<<16|G[f+7|0]<<24);e=e+32|0;h=G[f|0]|G[f+1|0]<<8|(G[f+2|0]<<16|G[f+3|0]<<24);D[e|0]=h;D[e+1|0]=h>>>8;D[e+2|0]=h>>>16;D[e+3|0]=h>>>24;D[e+4|0]=g;D[e+5|0]=g>>>8;D[e+6|0]=g>>>16;D[e+7|0]=g>>>24;g=G[f+28|0]|G[f+29|0]<<8|(G[f+30|0]<<16|G[f+31|0]<<24);h=G[f+24|0]|G[f+25|0]<<8|(G[f+26|0]<<16|G[f+27|0]<<24);D[e+24|0]=h;D[e+25|0]=h>>>8;D[e+26|0]=h>>>16;D[e+27|0]=h>>>24;D[e+28|0]=g;D[e+29|0]=g>>>8;D[e+30|0]=g>>>16;D[e+31|0]=g>>>24;g=G[f+20|0]|G[f+21|0]<<8|(G[f+22|0]<<16|G[f+23|0]<<24);h=G[f+16|0]|G[f+17|0]<<8|(G[f+18|0]<<16|G[f+19|0]<<24);D[e+16|0]=h;D[e+17|0]=h>>>8;D[e+18|0]=h>>>16;D[e+19|0]=h>>>24;D[e+20|0]=g;D[e+21|0]=g>>>8;D[e+22|0]=g>>>16;D[e+23|0]=g>>>24;g=G[f+12|0]|G[f+13|0]<<8|(G[f+14|0]<<16|G[f+15|0]<<24);f=G[f+8|0]|G[f+9|0]<<8|(G[f+10|0]<<16|G[f+11|0]<<24);D[e+8|0]=f;D[e+9|0]=f>>>8;D[e+10|0]=f>>>16;D[e+11|0]=f>>>24;D[e+12|0]=g;D[e+13|0]=g>>>8;D[e+14|0]=g>>>16;D[e+15|0]=g>>>24;f=a+3285|0;g=G[f+4|0]|G[f+5|0]<<8|(G[f+6|0]<<16|G[f+7|0]<<24);e=e+32|0;h=G[f|0]|G[f+1|0]<<8|(G[f+2|0]<<16|G[f+3|0]<<24);D[e|0]=h;D[e+1|0]=h>>>8;D[e+2|0]=h>>>16;D[e+3|0]=h>>>24;D[e+4|0]=g;D[e+5|0]=g>>>8;D[e+6|0]=g>>>16;D[e+7|0]=g>>>24;g=G[f+28|0]|G[f+29|0]<<8|(G[f+30|0]<<16|G[f+31|0]<<24);h=G[f+24|0]|G[f+25|0]<<8|(G[f+26|0]<<16|G[f+27|0]<<24);D[e+24|0]=h;D[e+25|0]=h>>>8;D[e+26|0]=h>>>16;D[e+27|0]=h>>>24;D[e+28|0]=g;D[e+29|0]=g>>>8;D[e+30|0]=g>>>16;D[e+31|0]=g>>>24;g=G[f+20|0]|G[f+21|0]<<8|(G[f+22|0]<<16|G[f+23|0]<<24);h=G[f+16|0]|G[f+17|0]<<8|(G[f+18|0]<<16|G[f+19|0]<<24);D[e+16|0]=h;D[e+17|0]=h>>>8;D[e+18|0]=h>>>16;D[e+19|0]=h>>>24;D[e+20|0]=g;D[e+21|0]=g>>>8;D[e+22|0]=g>>>16;D[e+23|0]=g>>>24;g=G[f+12|0]|G[f+13|0]<<8|(G[f+14|0]<<16|G[f+15|0]<<24);f=G[f+8|0]|G[f+9|0]<<8|(G[f+10|0]<<16|G[f+11|0]<<24);D[e+8|0]=f;D[e+9|0]=f>>>8;D[e+10|0]=f>>>16;D[e+11|0]=f>>>24;D[e+12|0]=g;D[e+13|0]=g>>>8;D[e+14|0]=g>>>16;D[e+15|0]=g>>>24;f=Ua(e+32|0,a+12|0,32);e=a+48|0;f=la(f,(F[a+44>>2]-e|0)/100|0);g=F[a+44>>2];if((g|0)!=(e|0)){while(1){f=la(Ua(Na(f,e),e+68|0,32),F[e+64>>2]);e=e+100|0;if((g|0)!=(e|0)){continue}break}}e=a+152|0;f=la(f,(F[a+148>>2]-e|0)/68|0);j=F[a+148>>2];if((j|0)!=(e|0)){while(1){g=G[e+4|0]|G[e+5|0]<<8|(G[e+6|0]<<16|G[e+7|0]<<24);h=G[e|0]|G[e+1|0]<<8|(G[e+2|0]<<16|G[e+3|0]<<24);D[f|0]=h;D[f+1|0]=h>>>8;D[f+2|0]=h>>>16;D[f+3|0]=h>>>24;D[f+4|0]=g;D[f+5|0]=g>>>8;D[f+6|0]=g>>>16;D[f+7|0]=g>>>24;g=G[e+28|0]|G[e+29|0]<<8|(G[e+30|0]<<16|G[e+31|0]<<24);h=G[e+24|0]|G[e+25|0]<<8|(G[e+26|0]<<16|G[e+27|0]<<24);D[f+24|0]=h;D[f+25|0]=h>>>8;D[f+26|0]=h>>>16;D[f+27|0]=h>>>24;D[f+28|0]=g;D[f+29|0]=g>>>8;D[f+30|0]=g>>>16;D[f+31|0]=g>>>24;g=G[e+20|0]|G[e+21|0]<<8|(G[e+22|0]<<16|G[e+23|0]<<24);h=G[e+16|0]|G[e+17|0]<<8|(G[e+18|0]<<16|G[e+19|0]<<24);D[f+16|0]=h;D[f+17|0]=h>>>8;D[f+18|0]=h>>>16;D[f+19|0]=h>>>24;D[f+20|0]=g;D[f+21|0]=g>>>8;D[f+22|0]=g>>>16;D[f+23|0]=g>>>24;g=G[e+12|0]|G[e+13|0]<<8|(G[e+14|0]<<16|G[e+15|0]<<24);h=G[e+8|0]|G[e+9|0]<<8|(G[e+10|0]<<16|G[e+11|0]<<24);D[f+8|0]=h;D[f+9|0]=h>>>8;D[f+10|0]=h>>>16;D[f+11|0]=h>>>24;D[f+12|0]=g;D[f+13|0]=g>>>8;D[f+14|0]=g>>>16;D[f+15|0]=g>>>24;f=la(Ua(f+32|0,e+36|0,32),F[e+32>>2]);e=e+68|0;if((j|0)!=(e|0)){continue}break}}e=a+496|0;f=la(f,(F[a+492>>2]-e|0)/68|0);h=F[a+492>>2];if((h|0)!=(e|0)){while(1){a=G[e+4|0]|G[e+5|0]<<8|(G[e+6|0]<<16|G[e+7|0]<<24);g=G[e|0]|G[e+1|0]<<8|(G[e+2|0]<<16|G[e+3|0]<<24);D[f|0]=g;D[f+1|0]=g>>>8;D[f+2|0]=g>>>16;D[f+3|0]=g>>>24;D[f+4|0]=a;D[f+5|0]=a>>>8;D[f+6|0]=a>>>16;D[f+7|0]=a>>>24;a=G[e+28|0]|G[e+29|0]<<8|(G[e+30|0]<<16|G[e+31|0]<<24);g=G[e+24|0]|G[e+25|0]<<8|(G[e+26|0]<<16|G[e+27|0]<<24);D[f+24|0]=g;D[f+25|0]=g>>>8;D[f+26|0]=g>>>16;D[f+27|0]=g>>>24;D[f+28|0]=a;D[f+29|0]=a>>>8;D[f+30|0]=a>>>16;D[f+31|0]=a>>>24;a=G[e+20|0]|G[e+21|0]<<8|(G[e+22|0]<<16|G[e+23|0]<<24);g=G[e+16|0]|G[e+17|0]<<8|(G[e+18|0]<<16|G[e+19|0]<<24);D[f+16|0]=g;D[f+17|0]=g>>>8;D[f+18|0]=g>>>16;D[f+19|0]=g>>>24;D[f+20|0]=a;D[f+21|0]=a>>>8;D[f+22|0]=a>>>16;D[f+23|0]=a>>>24;a=G[e+12|0]|G[e+13|0]<<8|(G[e+14|0]<<16|G[e+15|0]<<24);g=G[e+8|0]|G[e+9|0]<<8|(G[e+10|0]<<16|G[e+11|0]<<24);D[f+8|0]=g;D[f+9|0]=g>>>8;D[f+10|0]=g>>>16;D[f+11|0]=g>>>24;D[f+12|0]=a;D[f+13|0]=a>>>8;D[f+14|0]=a>>>16;D[f+15|0]=a>>>24;f=la(Ua(f+32|0,e+36|0,32),F[e+32>>2]);e=e+68|0;if((h|0)!=(e|0)){continue}break}}return Za(b,c,d,i)|0}function fa(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0,H=0,I=0,J=0,K=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,aa=0,ba=0,ca=0,da=0,ea=0;c=F[b+12>>2];d=c<<1;x=d;s=d>>31;k=c;U=c>>31;c=se(d,s,c,U);f=$;d=c;n=F[b+16>>2];c=n;t=c>>31;i=F[b+8>>2];c=i<<1;J=c;C=c>>31;e=se(n,t,c,C);d=d+e|0;c=$+f|0;c=d>>>0>>0?c+1|0:c;f=d;e=F[b+20>>2];d=e<<1;D=d;E=d>>31;h=F[b+4>>2];d=h<<1;u=d;o=d>>31;m=se(D,E,d,o);f=f+m|0;d=$+c|0;d=f>>>0>>0?d+1|0:d;g=F[b+24>>2];c=g;P=c;y=c>>31;z=F[b>>2];c=z<<1;v=c;p=c>>31;m=se(g,y,c,p);f=m+f|0;c=$+d|0;c=f>>>0>>0?c+1|0:c;l=f;m=F[b+32>>2];d=L(m,19);G=d;A=d>>31;Q=m>>31;f=se(d,A,m,Q);d=l+f|0;c=$+c|0;c=d>>>0>>0?c+1|0:c;l=d;R=F[b+36>>2];d=L(R,38);w=d;q=d>>31;f=F[b+28>>2];b=f<<1;_=b;V=b>>31;K=se(d,q,b,V);d=l+K|0;b=$+c|0;l=d;r=d>>>0>>0?b+1|0:b;b=se(u,o,n,t);c=$;d=se(J,C,k,U);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;K=e;S=e>>31;j=se(e,S,v,p);b=j+b|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;j=se(G,A,_,V);b=j+b|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;d=se(w,q,g,y);b=d+b|0;c=$+c|0;B=b;M=b>>>0>>0?c+1|0:c;b=se(u,o,x,s);d=$;N=i>>31;j=se(i,N,i,N);c=j+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;j=se(v,p,n,t);d=j+c|0;c=$+b|0;c=d>>>0>>0?c+1|0:c;b=L(f,38);T=b;O=b>>31;j=f;W=f>>31;f=se(b,O,f,W);b=f+d|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;c=b;b=g<<1;f=se(G,A,b,b>>31);b=c+f|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;d=se(w,q,D,E);b=d+b|0;c=$+c|0;X=b;c=b>>>0>>0?c+1|0:c;ca=c;b=c;c=X+33554432|0;b=c>>>0<33554432?b+1|0:b;aa=c;da=b;c=b>>26;d=(b&67108863)<<6|aa>>>26;b=d+B|0;c=c+M|0;M=b;d=b>>>0>>0?c+1|0:c;b=b+16777216|0;d=b>>>0<16777216?d+1|0:d;ea=b;c=d>>25;d=(d&33554431)<<7|b>>>25;b=d+l|0;c=c+r|0;c=b>>>0>>0?c+1|0:c;d=b;b=c;c=d+33554432|0;b=c>>>0<33554432?b+1|0:b;H=c;f=b;b=c&-67108864;F[a+24>>2]=d-b;b=se(v,p,i,N);c=$;r=h>>31;l=se(u,o,h,r);b=l+b|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;c=b;b=L(g,19);l=b;B=b>>31;g=se(b,B,g,y);b=c+g|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;g=se(D,E,T,O);d=g+b|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;c=n<<1;ba=c;Y=c>>31;g=se(G,A,c,Y);d=g+d|0;c=$+b|0;c=d>>>0>>0?c+1|0:c;b=d;d=se(w,q,x,s);b=b+d|0;c=$+c|0;Z=b;g=b>>>0>>0?c+1|0:c;b=se(D,E,l,B);c=$;h=se(v,p,h,r);b=h+b|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;h=se(n,t,T,O);b=h+b|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;h=se(G,A,x,s);d=h+b|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;h=se(w,q,i,N);d=h+d|0;c=$+b|0;I=d;r=d>>>0>>0?c+1|0:c;b=L(e,38);b=se(b,b>>31,e,S);c=$;e=b;b=z>>31;d=se(z,b,z,b);b=e+d|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;e=se(l,B,ba,Y);b=e+b|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;e=se(x,s,T,O);b=e+b|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;e=se(G,A,J,C);d=e+b|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;e=se(u,o,w,q);d=e+d|0;c=$+b|0;h=d;c=d>>>0>>0?c+1|0:c;l=c;b=d+33554432|0;c=b>>>0<33554432?c+1|0:c;z=b;B=c;b=c>>26;e=(c&67108863)<<6|z>>>26;c=e+I|0;d=b+r|0;r=c;I=Z;c=c>>>0>>0?d+1|0:d;b=r+16777216|0;c=b>>>0<16777216?c+1|0:c;Z=b;e=(c&33554431)<<7|b>>>25;d=I+e|0;c=(c>>25)+g|0;c=d>>>0>>0?c+1|0:c;b=d;d=b+33554432|0;c=d>>>0<33554432?c+1|0:c;g=d;e=c;c=d&-67108864;F[a+8>>2]=b-c;b=se(J,C,K,S);c=$;d=se(n,t,x,s);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;d=se(u,o,P,y);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;d=se(v,p,j,W);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;I=se(w,q,m,Q);d=I+b|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;c=f>>26;H=(f&67108863)<<6|H>>>26;f=H+d|0;d=b+c|0;b=f;c=b>>>0>>0?d+1|0:d;d=b+16777216|0;c=d>>>0<16777216?c+1|0:c;H=d;f=c;c=d&-33554432;F[a+28>>2]=b-c;b=se(v,p,k,U);d=$;i=se(u,o,i,N);c=i+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;i=se(P,y,T,O);c=i+c|0;d=$+b|0;d=c>>>0>>0?d+1|0:d;i=se(G,A,D,E);b=i+c|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;d=se(w,q,n,t);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;d=e>>26;e=(e&67108863)<<6|g>>>26;b=e+b|0;c=c+d|0;d=b;b=b>>>0>>0?c+1|0:c;c=d+16777216|0;b=c>>>0<16777216?b+1|0:b;i=c;e=b;b=c&-33554432;F[a+12>>2]=d-b;b=se(P,y,J,C);c=$;d=se(n,t,n,t);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;d=se(x,s,D,E);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;k=se(u,o,_,V);d=k+b|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;k=se(v,p,m,Q);c=k+d|0;d=$+b|0;d=c>>>0>>0?d+1|0:d;g=R>>31;k=se(w,q,R,g);b=k+c|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;d=b;b=f>>25;f=(f&33554431)<<7|H>>>25;d=d+f|0;c=b+c|0;c=d>>>0>>0?c+1|0:c;b=d;d=b+33554432|0;c=d>>>0<33554432?c+1|0:c;k=d;f=c;c=d&-67108864;F[a+32>>2]=b-c;M=M-(ea&-33554432)|0;c=e>>25;e=(e&33554431)<<7|i>>>25;b=aa&-67108864;d=e+(X-b|0)|0;b=c+(ca-((b>>>0>X>>>0)+da|0)|0)|0;b=d>>>0>>0?b+1|0:b;c=b;b=d+33554432|0;c=b>>>0<33554432?c+1|0:c;e=b;b=((c&67108863)<<6|b>>>26)+M|0;F[a+20>>2]=b;b=e&-67108864;F[a+16>>2]=d-b;b=se(x,s,P,y);d=$;e=se(K,S,ba,Y);c=e+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;e=se(J,C,j,W);d=e+c|0;c=$+b|0;c=d>>>0>>0?c+1|0:c;e=se(u,o,m,Q);b=e+d|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;e=se(v,p,R,g);b=e+b|0;c=$+d|0;d=b;b=b>>>0>>0?c+1|0:c;c=f>>26;f=(f&67108863)<<6|k>>>26;d=f+d|0;c=b+c|0;c=d>>>0>>0?c+1|0:c;b=c;c=d+16777216|0;b=c>>>0<16777216?b+1|0:b;f=c&-33554432;F[a+36>>2]=d-f;e=se((b&33554431)<<7|c>>>25,b>>25,19,0);d=z&-67108864;b=e+(h-d|0)|0;c=$+(l-((d>>>0>h>>>0)+B|0)|0)|0;d=b;b=b>>>0>>0?c+1|0:c;c=d+33554432|0;b=c>>>0<33554432?b+1|0:b;b=(r-(Z&-33554432)|0)+((b&67108863)<<6|c>>>26)|0;F[a+4>>2]=b;b=a;a=c&-67108864;F[b>>2]=d-a}function ga(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0,H=0,I=0,J=0,K=0,L=0;f=_-160|0;_=f;p=F[b>>2];c=F[b+16>>2];q=c;r=c>>31;c=F[b+24>>2];s=c;t=c>>31;u=F[b+8>>2];c=F[b+32>>2];v=c;w=c>>31;g=F[b+40>>2];d=F[b+72>>2];k=d;H=d;z=d>>31;c=F[b+48>>2];A=c;x=c>>31;e=se(d,z,c,x);o=$;c=F[b+64>>2];j=c;d=c>>31;n=d;c=d;d=F[b+56>>2];l=d;E=d;B=d>>31;d=se(j,c,d,B);c=d+e|0;b=$+o|0;i=c;b=c>>>0>>0?b+1|0:b;e=b;c=f;F[c+120>>2]=i<<1;F[c+124>>2]=b<<1|i>>>31;c=g;y=c;o=c>>31;b=se(j,n,c,o);d=$;h=se(A,x,l,B);c=h+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;h=se(v,w,k,z);d=h+c|0;c=$+b|0;G=d;c=d>>>0>>0?c+1|0:c;h=c;d=f;F[d+104>>2]=G<<1;F[d+108>>2]=c<<1|G>>>31;b=se(s,t,A,x);c=$;D=se(v,w,y,o);b=D+b|0;d=$+c|0;d=b>>>0>>0?d+1|0:d;D=se(q,r,l,B);b=D+b|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;d=b;D=0;b=u;g=b;J=b;u=b>>31;K=se(j,n,b,u);d=K+d|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;c=b;K=0;b=p;m=d;C=b;p=b>>31;d=se(k,z,b,p);b=m+d|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;F[f+72>>2]=b<<1;F[f+76>>2]=c<<1|b>>>31;b=se(k,z,(l&1073741823)<<2|I>>>30,l>>30);c=$;d=se(j,n,j,n);b=d+b|0;c=$+c|0;l=b;F[f+128>>2]=b;c=b>>>0>>0?c+1|0:c;F[f+132>>2]=c;I=c;b=se(q,r,v,w);d=$;m=se(s,t,s,t);c=m+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;m=se(y,o,(g&2147483647)<<1|D>>>31,g>>31);d=m+c|0;c=$+b|0;c=d>>>0>>0?c+1|0:c;m=se(C,p,A,x);d=m+d|0;b=$+c|0;c=d;d=(c>>>0>>0?b+1|0:b)<<1|c>>>31;m=c<<1;b=m+l|0;c=d+I|0;l=se(l,I,18,0);d=l+b|0;b=$+(b>>>0>>0?c+1|0:c)|0;F[f+48>>2]=d;F[f+52>>2]=d>>>0>>0?b+1|0:b;b=se(i,e,36,0);l=$;c=se(v,w,g,u);d=$;m=b;I=i;i=se(q,r,s,t);b=i+c|0;c=$+d|0;c=b>>>0>>0?c+1|0:c;i=se(y,o,C,p);d=i+b|0;b=$+c|0;b=d>>>0>>0?b+1|0:b;i=d;c=I+d|0;d=b+e|0;b=c;c=(b>>>0>>0?d+1|0:d)<<1|b>>>31;d=b<<1;b=m+d|0;c=c+l|0;F[f+40>>2]=b;F[f+44>>2]=b>>>0>>0?c+1|0:c;b=se(G,h,36,0);e=$;c=se(s,t,C,p);d=$;i=b;l=se(q,r,g,u);c=l+c|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;d=c;c=c+G|0;b=b+h|0;b=c>>>0>>0?b+1|0:b;d=c;c=b<<1|c>>>31;h=d<<1;b=i+h|0;d=c+e|0;F[f+24>>2]=b;F[f+28>>2]=b>>>0>>0?d+1|0:d;h=se((k&2147483647)<<1|L>>>31,k>>31,k,z);b=$;k=b;F[f+144>>2]=h;F[f+148>>2]=b;d=se(v,w,v,w);l=$;b=se(C,p,j,n);c=$;e=se(q,r,A,x);b=e+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;i=se(g,u,E,B);G=$;e=d;m=b;b=i;i=se(s,t,y,o);d=b+i|0;b=$+G|0;b=d>>>0>>0?b+1|0:b;b=b<<1|d>>>31;i=d<<1;d=m+i|0;c=b+c|0;c=d>>>0>>0?c+1|0:c;b=c<<1|d>>>31;i=d<<1;c=e+i|0;d=b+l|0;h=se(h,k,19,0);b=h+c|0;c=$+(c>>>0>>0?d+1|0:d)|0;F[f+64>>2]=b;F[f+68>>2]=b>>>0>>0?c+1|0:c;h=se(H,z,(j&2147483647)<<1|L>>>31,j>>31);b=$;F[f+136>>2]=h;F[f+140>>2]=b;e=b;b=se(q,r,y,o);d=$;k=se(s,t,v,w);c=k+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;k=se(g,u,A,x);d=k+c|0;c=$+b|0;c=d>>>0>>0?c+1|0:c;k=se(C,p,E,B);b=k+d|0;d=$+c|0;c=b;b=(b>>>0>>0?d+1|0:d)<<1|b>>>31;k=c<<1;d=k+h|0;c=b+e|0;c=d>>>0>>0?c+1|0:c;e=se(h,e,18,0);d=e+d|0;b=$+c|0;F[f+56>>2]=d;F[f+60>>2]=d>>>0>>0?b+1|0:b;b=se(A,x,j,n);c=$;d=se(E,B,E,B);b=d+b|0;c=$+c|0;c=b>>>0>>0?c+1|0:c;d=b;b=c;e=se(H,z,(y&2147483647)<<1|L>>>31,y>>31);c=e+d|0;d=$+b|0;d=c>>>0>>0?d+1|0:d;e=c;h=d;b=c<<1;F[f+112>>2]=b;c=d<<1|c>>>31;F[f+116>>2]=c;d=b;k=c;b=se(s,t,(g&1073741823)<<2|D>>>30,g>>30);g=$;i=se(q,r,q,r);c=i+b|0;b=$+g|0;b=c>>>0>>0?b+1|0:b;m=d;l=(C&2147483647)<<1|K>>>31;i=C>>31;d=se(v,w,l,i);c=d+c|0;b=$+b|0;b=c>>>0>>0?b+1|0:b;g=c;c=m+c|0;d=b+k|0;e=se(e,h,36,0);b=e+c|0;c=$+(c>>>0>>0?d+1|0:d)|0;F[f+32>>2]=b;F[f+36>>2]=b>>>0>>0?c+1|0:c;b=se(v,w,E,B);d=$;g=se(y,o,A,x);c=g+b|0;b=$+d|0;b=c>>>0>>0?b+1|0:b;g=se(s,t,j,n);d=g+c|0;c=$+b|0;c=d>>>0>>0?c+1|0:c;g=se(q,r,H,z);d=g+d|0;b=$+c|0;c=d;b=c>>>0>>0?b+1|0:b;g=b;d=f;e=c<<1;F[d+88>>2]=e;b=b<<1|c>>>31;F[d+92>>2]=b;h=se(J,u,l,i);e=h+e|0;d=$+b|0;g=se(c,g,36,0);b=g+e|0;c=$+(e>>>0>>0?d+1|0:d)|0;F[f+8>>2]=b;F[f+12>>2]=b>>>0>>0?c+1|0:c;b=se(A,x,A,x);g=$;c=se(v,w,j,n);e=$;d=se(s,t,H,z);h=$;i=b;k=c;b=d;d=se(y,o,E,B);b=b+d|0;c=$+h|0;c=b>>>0>>0?c+1|0:c;d=c<<1|b>>>31;h=b<<1;c=k+h|0;b=d+e|0;d=c;c=(c>>>0>>0?b+1|0:b)<<1|c>>>31;e=d<<1;d=i+e|0;b=c+g|0;g=d;F[f+96>>2]=d;b=d>>>0>>0?b+1|0:b;F[f+100>>2]=b;c=se(q,r,C,p);e=$;h=se(J,u,J,u);d=h+c|0;c=$+e|0;c=d>>>0>>0?c+1|0:c;h=d<<1;e=h+g|0;d=(c<<1|d>>>31)+b|0;g=se(g,b,18,0);c=g+e|0;b=$+(e>>>0>>0?d+1|0:d)|0;F[f+16>>2]=c;F[f+20>>2]=c>>>0>>0?b+1|0:b;b=se(v,w,A,x);d=$;g=se(y,o,y,o);c=g+b|0;b=$+d|0;j=se(q,r,j,n);d=j+c|0;c=$+(c>>>0>>0?b+1|0:b)|0;b=d;d=b>>>0>>0?c+1|0:c;c=se(J,u,H,z);j=$;e=b;n=se(s,t,E,B);b=n+c|0;c=$+j|0;j=b;b=(b>>>0>>0?c+1|0:c)<<1|b>>>31;j=j<<1;c=e+j|0;d=b+d|0;d=c>>>0>>0?d+1|0:d;j=c;b=f;n=c<<1;F[b+80>>2]=n;c=d<<1|c>>>31;F[b+84>>2]=c;g=se(C,p,C,p);n=g+n|0;b=$+c|0;j=se(j,d,36,0);d=j+n|0;c=$+(g>>>0>n>>>0?b+1|0:b)|0;F[f>>2]=d;F[f+4>>2]=d>>>0>>0?c+1|0:c;wa(f);ja(a,f,80);_=f+160|0}function ab(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;F[a+4>>2]=0;F[a+8>>2]=0;D[a|0]=0;F[a+12>>2]=0;F[a+16>>2]=0;F[a+20>>2]=0;F[a+24>>2]=0;F[a+28>>2]=0;F[a+32>>2]=0;a:{if(!c){break a}D[a|0]=G[b|0];if((c|0)==1){break a}g=b+c|0;d=b+1|0;while(1){h=d;if(G[d|0]==10){c=h+1|0;b=c;while(1){b:{if((b|0)==(g|0)){f=g;break b}d=D[b|0];f=b+1|0;b=f;if((d|0)<0){continue}}break}c:{if((c|0)==(f|0)){e=0;break c}c=(h^-1)+f|0;i=c&3;d=0;e=0;b=f;if((b-h|0)-2>>>0>=3){j=c&-4;c=0;while(1){e=(G[b-2|0]&127|(e<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;e=e|G[b|0]&127;c=c+4|0;if((j|0)!=(c|0)){continue}break}}if(i){while(1){b=b-1|0;e=G[b|0]&127|e<<7;d=d+1|0;if((i|0)!=(d|0)){continue}break}}if(g-f>>>0>>0){break a}}F[a+24>>2]=e;F[a+20>>2]=f;d=e+f|0}if((d|0)==(g|0)){break a}if(G[d|0]==18){f=d+1|0;b=f;while(1){d:{if((b|0)==(g|0)){c=g;break d}e=D[b|0];c=b+1|0;b=c;if((e|0)<0){continue}}break}e:{if((c|0)==(f|0)){e=0;break e}j=(d^-1)+c|0;i=j&3;f=0;e=0;b=c;if((b-d|0)-2>>>0>=3){j=j&-4;d=0;while(1){e=(G[b-2|0]&127|(e<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;e=e|G[b|0]&127;d=d+4|0;if((j|0)!=(d|0)){continue}break}}if(i){while(1){b=b-1|0;e=G[b|0]&127|e<<7;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if(g-c>>>0>>0){break a}}F[a+16>>2]=e;F[a+12>>2]=c;d=c+e|0}if((d|0)==(g|0)){break a}if(G[d|0]==26){f=d+1|0;b=f;while(1){f:{if((b|0)==(g|0)){c=g;break f}e=D[b|0];c=b+1|0;b=c;if((e|0)<0){continue}}break}g:{if((c|0)==(f|0)){e=0;break g}j=(d^-1)+c|0;i=j&3;f=0;e=0;b=c;if((b-d|0)-2>>>0>=3){j=j&-4;d=0;while(1){e=(G[b-2|0]&127|(e<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;e=e|G[b|0]&127;d=d+4|0;if((j|0)!=(d|0)){continue}break}}if(i){while(1){b=b-1|0;e=G[b|0]&127|e<<7;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if(g-c>>>0>>0){break a}}F[a+8>>2]=e;F[a+4>>2]=c;d=c+e|0}if((d|0)==(g|0)){break a}if(G[d|0]==34){f=d+1|0;b=f;while(1){h:{if((b|0)==(g|0)){c=g;break h}e=D[b|0];c=b+1|0;b=c;if((e|0)<0){continue}}break}i:{if((c|0)==(f|0)){e=0;break i}j=(d^-1)+c|0;i=j&3;f=0;e=0;b=c;if((b-d|0)-2>>>0>=3){j=j&-4;d=0;while(1){e=(G[b-2|0]&127|(e<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;e=e|G[b|0]&127;d=d+4|0;if((j|0)!=(d|0)){continue}break}}if(i){while(1){b=b-1|0;e=G[b|0]&127|e<<7;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if(g-c>>>0>>0){break a}}F[a+32>>2]=e;F[a+28>>2]=c;d=c+e|0}j:{if((d|0)==(g|0)|(d|0)!=(h|0)){break j}k:{switch(G[h|0]&7){case 0:while(1){l:{if((g|0)==(h|0)){b=g;break l}c=D[h|0];b=h+1|0;h=b;if((c|0)<0){continue}}break};while(1){if((b|0)==(g|0)){d=g;break j}c=D[b|0];d=b+1|0;b=d;if((c|0)<0){continue}break};break j;case 2:break k;default:break a}}while(1){m:{if((g|0)==(h|0)){d=g;break m}b=D[h|0];d=h+1|0;h=d;if((b|0)<0){continue}}break}b=d;while(1){n:{if((b|0)==(g|0)){f=g;break n}c=D[b|0];f=b+1|0;b=f;if((c|0)<0){continue}}break}if((d|0)==(f|0)){break j}i=f-d|0;c=i&3;e=0;h=0;b=f;if(b+(d^-1)>>>0>=3){i=i&-4;d=0;while(1){h=(G[b-2|0]&127|(h<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;h=h|G[b|0]&127;d=d+4|0;if((i|0)!=(d|0)){continue}break}}if(c){while(1){b=b-1|0;h=G[b|0]&127|h<<7;e=e+1|0;if((c|0)!=(e|0)){continue}break}}if(g-f>>>0>>0){break a}d=f+h|0}if((d|0)!=(g|0)){continue}break}}}function rb(a,b,c){var d=0,e=0,f=0,g=0;a:{if(!a){break a}d=a+32|0;if(d>>>0>b>>>0){break a}f=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);g=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);D[c|0]=g;D[c+1|0]=g>>>8;D[c+2|0]=g>>>16;D[c+3|0]=g>>>24;D[c+4|0]=f;D[c+5|0]=f>>>8;D[c+6|0]=f>>>16;D[c+7|0]=f>>>24;f=G[a+28|0]|G[a+29|0]<<8|(G[a+30|0]<<16|G[a+31|0]<<24);g=G[a+24|0]|G[a+25|0]<<8|(G[a+26|0]<<16|G[a+27|0]<<24);D[c+24|0]=g;D[c+25|0]=g>>>8;D[c+26|0]=g>>>16;D[c+27|0]=g>>>24;D[c+28|0]=f;D[c+29|0]=f>>>8;D[c+30|0]=f>>>16;D[c+31|0]=f>>>24;f=G[a+20|0]|G[a+21|0]<<8|(G[a+22|0]<<16|G[a+23|0]<<24);g=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);D[c+16|0]=g;D[c+17|0]=g>>>8;D[c+18|0]=g>>>16;D[c+19|0]=g>>>24;D[c+20|0]=f;D[c+21|0]=f>>>8;D[c+22|0]=f>>>16;D[c+23|0]=f>>>24;f=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);g=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);D[c+8|0]=g;D[c+9|0]=g>>>8;D[c+10|0]=g>>>16;D[c+11|0]=g>>>24;D[c+12|0]=f;D[c+13|0]=f>>>8;D[c+14|0]=f>>>16;D[c+15|0]=f>>>24;f=b;b=a+96|0;if(f>>>0>>0){break a}a=d;d=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);e=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);D[c+32|0]=e;D[c+33|0]=e>>>8;D[c+34|0]=e>>>16;D[c+35|0]=e>>>24;D[c+36|0]=d;D[c+37|0]=d>>>8;D[c+38|0]=d>>>16;D[c+39|0]=d>>>24;d=G[a+60|0]|G[a+61|0]<<8|(G[a+62|0]<<16|G[a+63|0]<<24);e=G[a+56|0]|G[a+57|0]<<8|(G[a+58|0]<<16|G[a+59|0]<<24);D[c+88|0]=e;D[c+89|0]=e>>>8;D[c+90|0]=e>>>16;D[c+91|0]=e>>>24;D[c+92|0]=d;D[c+93|0]=d>>>8;D[c+94|0]=d>>>16;D[c+95|0]=d>>>24;d=G[a+52|0]|G[a+53|0]<<8|(G[a+54|0]<<16|G[a+55|0]<<24);e=G[a+48|0]|G[a+49|0]<<8|(G[a+50|0]<<16|G[a+51|0]<<24);D[c+80|0]=e;D[c+81|0]=e>>>8;D[c+82|0]=e>>>16;D[c+83|0]=e>>>24;D[c+84|0]=d;D[c+85|0]=d>>>8;D[c+86|0]=d>>>16;D[c+87|0]=d>>>24;d=G[a+44|0]|G[a+45|0]<<8|(G[a+46|0]<<16|G[a+47|0]<<24);e=G[a+40|0]|G[a+41|0]<<8|(G[a+42|0]<<16|G[a+43|0]<<24);D[c+72|0]=e;D[c+73|0]=e>>>8;D[c+74|0]=e>>>16;D[c+75|0]=e>>>24;D[c+76|0]=d;D[c+77|0]=d>>>8;D[c+78|0]=d>>>16;D[c+79|0]=d>>>24;e=G[a+36|0]|G[a+37|0]<<8|(G[a+38|0]<<16|G[a+39|0]<<24);d=c- -64|0;f=G[a+32|0]|G[a+33|0]<<8|(G[a+34|0]<<16|G[a+35|0]<<24);D[d|0]=f;D[d+1|0]=f>>>8;D[d+2|0]=f>>>16;D[d+3|0]=f>>>24;D[d+4|0]=e;D[d+5|0]=e>>>8;D[d+6|0]=e>>>16;D[d+7|0]=e>>>24;d=G[a+28|0]|G[a+29|0]<<8|(G[a+30|0]<<16|G[a+31|0]<<24);e=G[a+24|0]|G[a+25|0]<<8|(G[a+26|0]<<16|G[a+27|0]<<24);D[c+56|0]=e;D[c+57|0]=e>>>8;D[c+58|0]=e>>>16;D[c+59|0]=e>>>24;D[c+60|0]=d;D[c+61|0]=d>>>8;D[c+62|0]=d>>>16;D[c+63|0]=d>>>24;d=G[a+20|0]|G[a+21|0]<<8|(G[a+22|0]<<16|G[a+23|0]<<24);e=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);D[c+48|0]=e;D[c+49|0]=e>>>8;D[c+50|0]=e>>>16;D[c+51|0]=e>>>24;D[c+52|0]=d;D[c+53|0]=d>>>8;D[c+54|0]=d>>>16;D[c+55|0]=d>>>24;d=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);a=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);D[c+40|0]=a;D[c+41|0]=a>>>8;D[c+42|0]=a>>>16;D[c+43|0]=a>>>24;D[c+44|0]=d;D[c+45|0]=d>>>8;D[c+46|0]=d>>>16;D[c+47|0]=d>>>24;e=b}return e}function ad(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0;a:{if(!a){break a}d=a-8|0;b=F[a-4>>2];a=b&-8;f=d+a|0;b:{if(b&1){break b}if(!(b&3)){break a}b=F[d>>2];d=d-b|0;if(d>>>0>>0<=255){e=F[d+8>>2];b=b>>>3|0;c=F[d+12>>2];if((c|0)==(e|0)){F[9386]=F[9386]&ue(-2,b);break b}F[e+12>>2]=c;F[c+8>>2]=e;break b}h=F[d+24>>2];b=F[d+12>>2];c:{if((d|0)!=(b|0)){c=F[d+8>>2];F[c+12>>2]=b;F[b+8>>2]=c;break c}d:{e=d+20|0;c=F[e>>2];if(c){break d}e=d+16|0;c=F[e>>2];if(c){break d}b=0;break c}while(1){g=e;b=c;e=b+20|0;c=F[e>>2];if(c){continue}e=b+16|0;c=F[b+16>>2];if(c){continue}break}F[g>>2]=0}if(!h){break b}e=F[d+28>>2];c=(e<<2)+37848|0;e:{if(F[c>>2]==(d|0)){F[c>>2]=b;if(b){break e}F[9387]=F[9387]&ue(-2,e);break b}F[h+(F[h+16>>2]==(d|0)?16:20)>>2]=b;if(!b){break b}}F[b+24>>2]=h;c=F[d+16>>2];if(c){F[b+16>>2]=c;F[c+24>>2]=b}c=F[d+20>>2];if(!c){break b}F[b+20>>2]=c;F[c+24>>2]=b;break b}b=F[f+4>>2];if((b&3)!=3){break b}F[9388]=a;F[f+4>>2]=b&-2;F[d+4>>2]=a|1;F[a+d>>2]=a;return}if(d>>>0>=f>>>0){break a}b=F[f+4>>2];if(!(b&1)){break a}f:{if(!(b&2)){if(F[9392]==(f|0)){F[9392]=d;a=F[9389]+a|0;F[9389]=a;F[d+4>>2]=a|1;if(F[9391]!=(d|0)){break a}F[9388]=0;F[9391]=0;return}if(F[9391]==(f|0)){F[9391]=d;a=F[9388]+a|0;F[9388]=a;F[d+4>>2]=a|1;F[a+d>>2]=a;return}a=(b&-8)+a|0;g:{if(b>>>0<=255){e=F[f+8>>2];b=b>>>3|0;c=F[f+12>>2];if((c|0)==(e|0)){F[9386]=F[9386]&ue(-2,b);break g}F[e+12>>2]=c;F[c+8>>2]=e;break g}h=F[f+24>>2];b=F[f+12>>2];h:{if((f|0)!=(b|0)){c=F[f+8>>2];F[c+12>>2]=b;F[b+8>>2]=c;break h}i:{e=f+20|0;c=F[e>>2];if(c){break i}e=f+16|0;c=F[e>>2];if(c){break i}b=0;break h}while(1){g=e;b=c;e=b+20|0;c=F[e>>2];if(c){continue}e=b+16|0;c=F[b+16>>2];if(c){continue}break}F[g>>2]=0}if(!h){break g}e=F[f+28>>2];c=(e<<2)+37848|0;j:{if(F[c>>2]==(f|0)){F[c>>2]=b;if(b){break j}F[9387]=F[9387]&ue(-2,e);break g}F[h+(F[h+16>>2]==(f|0)?16:20)>>2]=b;if(!b){break g}}F[b+24>>2]=h;c=F[f+16>>2];if(c){F[b+16>>2]=c;F[c+24>>2]=b}c=F[f+20>>2];if(!c){break g}F[b+20>>2]=c;F[c+24>>2]=b}F[d+4>>2]=a|1;F[a+d>>2]=a;if(F[9391]!=(d|0)){break f}F[9388]=a;return}F[f+4>>2]=b&-2;F[d+4>>2]=a|1;F[a+d>>2]=a}if(a>>>0<=255){a=a>>>3|0;b=(a<<3)+37584|0;c=F[9386];a=1<>2]}F[b+8>>2]=d;F[a+12>>2]=d;F[d+12>>2]=b;F[d+8>>2]=a;return}e=31;F[d+16>>2]=0;F[d+20>>2]=0;if(a>>>0<=16777215){b=a>>>8|0;g=b+1048320>>>16&8;b=b<>>16&4;b=b<>>16&2;b=(b<>>15|0)-(c|(e|g))|0;e=(b<<1|a>>>b+21&1)+28|0}F[d+28>>2]=e;g=(e<<2)+37848|0;l:{m:{c=F[9387];b=1<>2]=d;F[d+24>>2]=g;break n}e=a<<((e|0)==31?0:25-(e>>>1|0)|0);b=F[g>>2];while(1){c=b;if((F[b+4>>2]&-8)==(a|0)){break m}b=e>>>29|0;e=e<<1;g=c+(b&4)|0;b=F[g+16>>2];if(b){continue}break}F[g+16>>2]=d;F[d+24>>2]=c}F[d+12>>2]=d;F[d+8>>2]=d;break l}a=F[c+8>>2];F[a+12>>2]=d;F[c+8>>2]=d;F[d+24>>2]=0;F[d+12>>2]=c;F[d+8>>2]=a}a=F[9394]-1|0;F[9394]=a?a:-1}}function sb(a,b){var c=0,d=0,e=0;c=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);d=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[a|0]=d;D[a+1|0]=d>>>8;D[a+2|0]=d>>>16;D[a+3|0]=d>>>24;D[a+4|0]=c;D[a+5|0]=c>>>8;D[a+6|0]=c>>>16;D[a+7|0]=c>>>24;c=G[b+28|0]|G[b+29|0]<<8|(G[b+30|0]<<16|G[b+31|0]<<24);d=G[b+24|0]|G[b+25|0]<<8|(G[b+26|0]<<16|G[b+27|0]<<24);D[a+24|0]=d;D[a+25|0]=d>>>8;D[a+26|0]=d>>>16;D[a+27|0]=d>>>24;D[a+28|0]=c;D[a+29|0]=c>>>8;D[a+30|0]=c>>>16;D[a+31|0]=c>>>24;c=G[b+20|0]|G[b+21|0]<<8|(G[b+22|0]<<16|G[b+23|0]<<24);d=G[b+16|0]|G[b+17|0]<<8|(G[b+18|0]<<16|G[b+19|0]<<24);D[a+16|0]=d;D[a+17|0]=d>>>8;D[a+18|0]=d>>>16;D[a+19|0]=d>>>24;D[a+20|0]=c;D[a+21|0]=c>>>8;D[a+22|0]=c>>>16;D[a+23|0]=c>>>24;c=G[b+12|0]|G[b+13|0]<<8|(G[b+14|0]<<16|G[b+15|0]<<24);d=G[b+8|0]|G[b+9|0]<<8|(G[b+10|0]<<16|G[b+11|0]<<24);D[a+8|0]=d;D[a+9|0]=d>>>8;D[a+10|0]=d>>>16;D[a+11|0]=d>>>24;D[a+12|0]=c;D[a+13|0]=c>>>8;D[a+14|0]=c>>>16;D[a+15|0]=c>>>24;c=G[b+36|0]|G[b+37|0]<<8|(G[b+38|0]<<16|G[b+39|0]<<24);d=G[b+32|0]|G[b+33|0]<<8|(G[b+34|0]<<16|G[b+35|0]<<24);D[a+32|0]=d;D[a+33|0]=d>>>8;D[a+34|0]=d>>>16;D[a+35|0]=d>>>24;D[a+36|0]=c;D[a+37|0]=c>>>8;D[a+38|0]=c>>>16;D[a+39|0]=c>>>24;c=G[b+44|0]|G[b+45|0]<<8|(G[b+46|0]<<16|G[b+47|0]<<24);d=G[b+40|0]|G[b+41|0]<<8|(G[b+42|0]<<16|G[b+43|0]<<24);D[a+40|0]=d;D[a+41|0]=d>>>8;D[a+42|0]=d>>>16;D[a+43|0]=d>>>24;D[a+44|0]=c;D[a+45|0]=c>>>8;D[a+46|0]=c>>>16;D[a+47|0]=c>>>24;c=G[b+52|0]|G[b+53|0]<<8|(G[b+54|0]<<16|G[b+55|0]<<24);d=G[b+48|0]|G[b+49|0]<<8|(G[b+50|0]<<16|G[b+51|0]<<24);D[a+48|0]=d;D[a+49|0]=d>>>8;D[a+50|0]=d>>>16;D[a+51|0]=d>>>24;D[a+52|0]=c;D[a+53|0]=c>>>8;D[a+54|0]=c>>>16;D[a+55|0]=c>>>24;c=G[b+60|0]|G[b+61|0]<<8|(G[b+62|0]<<16|G[b+63|0]<<24);d=G[b+56|0]|G[b+57|0]<<8|(G[b+58|0]<<16|G[b+59|0]<<24);D[a+56|0]=d;D[a+57|0]=d>>>8;D[a+58|0]=d>>>16;D[a+59|0]=d>>>24;D[a+60|0]=c;D[a+61|0]=c>>>8;D[a+62|0]=c>>>16;D[a+63|0]=c>>>24;d=b- -64|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);c=a- -64|0;d=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);D[c|0]=d;D[c+1|0]=d>>>8;D[c+2|0]=d>>>16;D[c+3|0]=d>>>24;D[c+4|0]=e;D[c+5|0]=e>>>8;D[c+6|0]=e>>>16;D[c+7|0]=e>>>24;c=G[b+76|0]|G[b+77|0]<<8|(G[b+78|0]<<16|G[b+79|0]<<24);d=G[b+72|0]|G[b+73|0]<<8|(G[b+74|0]<<16|G[b+75|0]<<24);D[a+72|0]=d;D[a+73|0]=d>>>8;D[a+74|0]=d>>>16;D[a+75|0]=d>>>24;D[a+76|0]=c;D[a+77|0]=c>>>8;D[a+78|0]=c>>>16;D[a+79|0]=c>>>24;c=G[b+84|0]|G[b+85|0]<<8|(G[b+86|0]<<16|G[b+87|0]<<24);d=G[b+80|0]|G[b+81|0]<<8|(G[b+82|0]<<16|G[b+83|0]<<24);D[a+80|0]=d;D[a+81|0]=d>>>8;D[a+82|0]=d>>>16;D[a+83|0]=d>>>24;D[a+84|0]=c;D[a+85|0]=c>>>8;D[a+86|0]=c>>>16;D[a+87|0]=c>>>24;c=G[b+92|0]|G[b+93|0]<<8|(G[b+94|0]<<16|G[b+95|0]<<24);b=G[b+88|0]|G[b+89|0]<<8|(G[b+90|0]<<16|G[b+91|0]<<24);D[a+88|0]=b;D[a+89|0]=b>>>8;D[a+90|0]=b>>>16;D[a+91|0]=b>>>24;D[a+92|0]=c;D[a+93|0]=c>>>8;D[a+94|0]=c>>>16;D[a+95|0]=c>>>24;return a+96|0}function db(a,b){var c=0,d=0,e=0,f=0,g=0;a:{if(!a|!b){break a}c=F[a+72>>2];if(c>>>0>127){break a}F[a+72>>2]=c+1;d=F[a+4>>2]+(c>>>29|0)|0;e=c<<3;f=e+F[a>>2]|0;F[a>>2]=f;F[a+4>>2]=e>>>0>f>>>0?d+1|0:d;f=a+76|0;D[f+c|0]=128;c=F[a+72>>2];if(c>>>0>=113){if(c>>>0<=127){while(1){F[a+72>>2]=c+1;D[(a+c|0)+76|0]=0;c=F[a+72>>2];if(c>>>0<128){continue}break}}ua(a,f);c=0}while(1){F[a+72>>2]=c+1;D[(a+c|0)+76|0]=0;c=F[a+72>>2];if(c>>>0<120){continue}break}d=F[a>>2];c=d<<24|d<<8&16711680;g=d>>>8|0;e=F[a+4>>2];d=d>>>24|0;c=c|((g|e<<24)&65280|(d|e<<8)&255);d=(g|(e&255)<<24)&-16777216|(d|(e&16777215)<<8)&16711680|(e>>>8&65280|e>>>24);D[a+196|0]=d;D[a+197|0]=d>>>8;D[a+198|0]=d>>>16;D[a+199|0]=d>>>24;D[a+200|0]=c;D[a+201|0]=c>>>8;D[a+202|0]=c>>>16;D[a+203|0]=c>>>24;ua(a,f);D[b|0]=G[a+15|0];D[b+1|0]=H[a+14>>1];D[b+2|0]=F[a+12>>2]>>>8;D[b+3|0]=F[a+12>>2];D[b+4|0]=(F[a+12>>2]&16777215)<<8|F[a+8>>2]>>>24;D[b+5|0]=(F[a+12>>2]&65535)<<16|F[a+8>>2]>>>16;D[b+6|0]=(F[a+12>>2]&255)<<24|F[a+8>>2]>>>8;D[b+7|0]=F[a+8>>2];D[b+8|0]=G[a+23|0];D[b+9|0]=H[a+22>>1];D[b+10|0]=F[a+20>>2]>>>8;D[b+11|0]=F[a+20>>2];D[b+12|0]=(F[a+20>>2]&16777215)<<8|F[a+16>>2]>>>24;D[b+13|0]=(F[a+20>>2]&65535)<<16|F[a+16>>2]>>>16;D[b+14|0]=(F[a+20>>2]&255)<<24|F[a+16>>2]>>>8;D[b+15|0]=F[a+16>>2];D[b+16|0]=G[a+31|0];D[b+17|0]=H[a+30>>1];D[b+18|0]=F[a+28>>2]>>>8;D[b+19|0]=F[a+28>>2];D[b+20|0]=(F[a+28>>2]&16777215)<<8|F[a+24>>2]>>>24;D[b+21|0]=(F[a+28>>2]&65535)<<16|F[a+24>>2]>>>16;D[b+22|0]=(F[a+28>>2]&255)<<24|F[a+24>>2]>>>8;D[b+23|0]=F[a+24>>2];D[b+24|0]=G[a+39|0];D[b+25|0]=H[a+38>>1];D[b+26|0]=F[a+36>>2]>>>8;D[b+27|0]=F[a+36>>2];D[b+28|0]=(F[a+36>>2]&16777215)<<8|F[a+32>>2]>>>24;D[b+29|0]=(F[a+36>>2]&65535)<<16|F[a+32>>2]>>>16;D[b+30|0]=(F[a+36>>2]&255)<<24|F[a+32>>2]>>>8;D[b+31|0]=F[a+32>>2];D[b+32|0]=G[a+47|0];D[b+33|0]=H[a+46>>1];D[b+34|0]=F[a+44>>2]>>>8;D[b+35|0]=F[a+44>>2];D[b+36|0]=(F[a+44>>2]&16777215)<<8|F[a+40>>2]>>>24;D[b+37|0]=(F[a+44>>2]&65535)<<16|F[a+40>>2]>>>16;D[b+38|0]=(F[a+44>>2]&255)<<24|F[a+40>>2]>>>8;D[b+39|0]=F[a+40>>2];D[b+40|0]=G[a+55|0];D[b+41|0]=H[a+54>>1];D[b+42|0]=F[a+52>>2]>>>8;D[b+43|0]=F[a+52>>2];D[b+44|0]=(F[a+52>>2]&16777215)<<8|F[a+48>>2]>>>24;D[b+45|0]=(F[a+52>>2]&65535)<<16|F[a+48>>2]>>>16;D[b+46|0]=(F[a+52>>2]&255)<<24|F[a+48>>2]>>>8;D[b+47|0]=F[a+48>>2];D[b+48|0]=G[a+63|0];D[b+49|0]=H[a+62>>1];D[b+50|0]=F[a+60>>2]>>>8;D[b+51|0]=F[a+60>>2];D[b+52|0]=(F[a+60>>2]&16777215)<<8|F[a+56>>2]>>>24;D[b+53|0]=(F[a+60>>2]&65535)<<16|F[a+56>>2]>>>16;D[b+54|0]=(F[a+60>>2]&255)<<24|F[a+56>>2]>>>8;D[b+55|0]=F[a+56>>2];D[b+56|0]=G[a+71|0];D[b+57|0]=H[a+70>>1];c=a- -64|0;D[b+58|0]=F[c+4>>2]>>>8;D[b+59|0]=F[a+68>>2];D[b+60|0]=(F[c+4>>2]&16777215)<<8|F[c>>2]>>>24;D[b+61|0]=(F[c+4>>2]&65535)<<16|F[c>>2]>>>16;D[b+62|0]=(F[c+4>>2]&255)<<24|F[c>>2]>>>8;D[b+63|0]=F[c>>2]}}function ie(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0;j=_-160|0;_=j;l=-1;if(!(i>>>0<8|(e+16&-16)>>>0>g>>>0)){g=j+80|0;Aa(b,c,0,0,F[a+4>>2],F[a+8>>2],g,80);a=F[j+108>>2];F[j+24>>2]=F[j+104>>2];F[j+28>>2]=a;a=F[j+100>>2];F[j+16>>2]=F[j+96>>2];F[j+20>>2]=a;a=F[j+92>>2];F[j+8>>2]=F[j+88>>2];F[j+12>>2]=a;a=F[j+124>>2];F[j+40>>2]=F[j+120>>2];F[j+44>>2]=a;a=F[j+132>>2];F[j+48>>2]=F[j+128>>2];F[j+52>>2]=a;a=F[j+140>>2];F[j+56>>2]=F[j+136>>2];F[j+60>>2]=a;a=F[j+156>>2];F[j+72>>2]=F[j+152>>2];F[j+76>>2]=a;a=F[j+84>>2];F[j>>2]=F[j+80>>2];F[j+4>>2]=a;a=F[j+116>>2];F[j+32>>2]=F[j+112>>2];F[j+36>>2]=a;a=F[j+148>>2];F[j+64>>2]=F[j+144>>2];F[j+68>>2]=a;ia(g,80);a=0;l=0;b=_-256|0;_=b;Hb(j,b+16|0);c=j- -64|0;n=G[c+12|0]|G[c+13|0]<<8|(G[c+14|0]<<16|G[c+15|0]<<24);F[b+8>>2]=G[c+8|0]|G[c+9|0]<<8|(G[c+10|0]<<16|G[c+11|0]<<24);F[b+12>>2]=n;n=G[c+4|0]|G[c+5|0]<<8|(G[c+6|0]<<16|G[c+7|0]<<24);F[b>>2]=G[c|0]|G[c+1|0]<<8|(G[c+2|0]<<16|G[c+3|0]<<24);F[b+4>>2]=n;if(e>>>0>=16){while(1){D[b|0]=G[b|0]^G[d|0];D[b+1|0]=G[b+1|0]^G[d+1|0];D[b+2|0]=G[b+2|0]^G[d+2|0];D[b+3|0]=G[b+3|0]^G[d+3|0];D[b+4|0]=G[b+4|0]^G[d+4|0];D[b+5|0]=G[b+5|0]^G[d+5|0];D[b+6|0]=G[b+6|0]^G[d+6|0];D[b+7|0]=G[b+7|0]^G[d+7|0];D[b+8|0]=G[b+8|0]^G[d+8|0];D[b+9|0]=G[b+9|0]^G[d+9|0];D[b+10|0]=G[b+10|0]^G[d+10|0];D[b+11|0]=G[b+11|0]^G[d+11|0];D[b+12|0]=G[b+12|0]^G[d+12|0];D[b+13|0]=G[b+13|0]^G[d+13|0];D[b+14|0]=G[b+14|0]^G[d+14|0];D[b+15|0]=G[b+15|0]^G[d+15|0];Jb(b,f,b+16|0);c=G[f+12|0]|G[f+13|0]<<8|(G[f+14|0]<<16|G[f+15|0]<<24);F[b+8>>2]=G[f+8|0]|G[f+9|0]<<8|(G[f+10|0]<<16|G[f+11|0]<<24);F[b+12>>2]=c;c=G[f+4|0]|G[f+5|0]<<8|(G[f+6|0]<<16|G[f+7|0]<<24);F[b>>2]=G[f|0]|G[f+1|0]<<8|(G[f+2|0]<<16|G[f+3|0]<<24);F[b+4>>2]=c;f=f+16|0;d=d+16|0;e=e-16|0;if(e>>>0>15){continue}break}}n=0;a:{if(e){c=0;if(e-1>>>0>=3){o=e&-4;while(1){k=b+c|0;D[k|0]=G[k|0]^G[c+d|0];k=c|1;m=k+b|0;D[m|0]=G[m|0]^G[d+k|0];k=c|2;m=k+b|0;D[m|0]=G[m|0]^G[d+k|0];k=c|3;m=k+b|0;D[m|0]=G[m|0]^G[d+k|0];c=c+4|0;a=a+4|0;if((o|0)!=(a|0)){continue}break}}a=e&3;if(a){while(1){o=b+c|0;D[o|0]=G[o|0]^G[c+d|0];c=c+1|0;l=l+1|0;if((a|0)!=(l|0)){continue}break}}a=e;if(a>>>0>15){break a}}c=16-e|0;d=a;e=0-a&3;if(e){while(1){l=b+d|0;D[l|0]=c^G[l|0];d=d+1|0;n=n+1|0;if((e|0)!=(n|0)){continue}break}}if(a-13>>>0<3){break a}while(1){a=b+d|0;D[a|0]=c^G[a|0];D[a+1|0]=c^G[a+1|0];D[a+2|0]=c^G[a+2|0];D[a+3|0]=c^G[a+3|0];d=d+4|0;if((d|0)!=16){continue}break}}a=b+16|0;Jb(b,f,a);ia(a,240);ia(b,16);_=b+256|0;ka(j+32|0,32,h,i-8|0,g);b=F[j+84>>2];a=(h+i|0)-8|0;c=F[j+80>>2];D[a|0]=c;D[a+1|0]=c>>>8;D[a+2|0]=c>>>16;D[a+3|0]=c>>>24;D[a+4|0]=b;D[a+5|0]=b>>>8;D[a+6|0]=b>>>16;D[a+7|0]=b>>>24;ia(j,80);l=i}_=j+160|0;return l|0}function fb(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;F[a+16>>2]=0;F[a+20>>2]=0;F[a+12>>2]=c;F[a+8>>2]=b;F[a+4>>2]=0;E[a>>1]=0;F[a+24>>2]=0;F[a+28>>2]=0;a:{if(c>>>0<=d>>>0){break a}D[a|0]=G[b|0];c=c-d|0;if((c|0)==1){break a}h=b+c|0;c=b+1|0;while(1){d=c;e=c;if(G[c|0]==10){c=d+1|0;b=c;while(1){b:{if((b|0)==(h|0)){g=h;break b}e=D[b|0];g=b+1|0;b=g;if((e|0)<0){continue}}break}c:{if((c|0)==(g|0)){c=0;break c}e=(d^-1)+g|0;i=e&3;f=0;c=0;b=g;if((b-d|0)-2>>>0>=3){j=e&-4;e=0;while(1){c=(G[b-2|0]&127|(c<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;c=c|G[b|0]&127;e=e+4|0;if((j|0)!=(e|0)){continue}break}}if(i){while(1){b=b-1|0;c=G[b|0]&127|c<<7;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if(h-g>>>0>>0){break a}}F[a+20>>2]=c;F[a+16>>2]=g;e=c+g|0}if((e|0)==(h|0)){break a}d:{if(G[e|0]!=16){c=e;break d}g=e+1|0;b=g;while(1){e:{if((b|0)==(h|0)){c=h;break e}f=D[b|0];c=b+1|0;b=c;if((f|0)<0){continue}}break}f:{if((c|0)==(g|0)){f=0;break f}j=(e^-1)+c|0;i=j&3;g=0;f=0;b=c;if((b-e|0)-2>>>0>=3){j=j&-4;e=0;while(1){f=(G[b-2|0]&127|(f<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;f=f|G[b|0]&127;e=e+4|0;if((j|0)!=(e|0)){continue}break}}if(!i){break f}while(1){b=b-1|0;f=G[b|0]&127|f<<7;g=g+1|0;if((i|0)!=(g|0)){continue}break}}D[a+1|0]=1;F[a+4>>2]=f}if((c|0)==(h|0)){break a}if(G[c|0]==34){g=c+1|0;b=g;while(1){g:{if((b|0)==(h|0)){e=h;break g}f=D[b|0];e=b+1|0;b=e;if((f|0)<0){continue}}break}h:{if((e|0)==(g|0)){f=0;break h}j=(c^-1)+e|0;i=j&3;g=0;f=0;b=e;if((b-c|0)-2>>>0>=3){j=j&-4;c=0;while(1){f=(G[b-2|0]&127|(f<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;f=f|G[b|0]&127;c=c+4|0;if((j|0)!=(c|0)){continue}break}}if(i){while(1){b=b-1|0;f=G[b|0]&127|f<<7;g=g+1|0;if((i|0)!=(g|0)){continue}break}}if(h-e>>>0>>0){break a}}F[a+28>>2]=f;F[a+24>>2]=e;c=e+f|0}i:{if((c|0)==(h|0)|(c|0)!=(d|0)){break i}j:{switch(G[d|0]&7){case 0:while(1){k:{if((d|0)==(h|0)){b=h;break k}c=D[d|0];b=d+1|0;d=b;if((c|0)<0){continue}}break};while(1){if((b|0)==(h|0)){c=h;break i}d=D[b|0];c=b+1|0;b=c;if((d|0)<0){continue}break};break i;case 2:break j;default:break a}}while(1){l:{if((d|0)==(h|0)){c=h;break l}b=D[d|0];c=d+1|0;d=c;if((b|0)<0){continue}}break}b=c;while(1){m:{if((b|0)==(h|0)){g=h;break m}d=D[b|0];g=b+1|0;b=g;if((d|0)<0){continue}}break}if((c|0)==(g|0)){break i}i=g-c|0;e=i&3;f=0;d=0;b=g;if(b+(c^-1)>>>0>=3){i=i&-4;c=0;while(1){d=(G[b-2|0]&127|(d<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;d=d|G[b|0]&127;c=c+4|0;if((i|0)!=(c|0)){continue}break}}if(e){while(1){b=b-1|0;d=G[b|0]&127|d<<7;f=f+1|0;if((e|0)!=(f|0)){continue}break}}if(h-g>>>0>>0){break a}c=d+g|0}if((c|0)!=(h|0)){continue}break}}}function wa(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;F[a+80>>2]=0;F[a+84>>2]=0;b=F[a+4>>2];d=b;c=F[a>>2];g=b>>31>>>6|0;h=c+g|0;b=g>>>0>h>>>0?b+1|0:b;f=h;g=f&-67108864;i=c-g|0;F[a>>2]=i;h=d-((c>>>0>>0)+b|0)|0;F[a+4>>2]=h;c=b;b=b>>26;d=(c&67108863)<<6|f>>>26;c=d+F[a+8>>2]|0;b=b+F[a+12>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>7|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-33554432;F[d+8>>2]=c-e;F[d+12>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>25;d=(c&33554431)<<7|f>>>25;c=d+F[a+16>>2]|0;b=b+F[a+20>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>6|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-67108864;F[d+16>>2]=c-e;F[d+20>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>26;d=(c&67108863)<<6|f>>>26;c=d+F[a+24>>2]|0;b=b+F[a+28>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>7|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-33554432;F[d+24>>2]=c-e;F[d+28>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>25;d=(c&33554431)<<7|f>>>25;c=d+F[a+32>>2]|0;b=b+F[a+36>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>6|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-67108864;F[d+32>>2]=c-e;F[d+36>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>26;d=(c&67108863)<<6|f>>>26;c=d+F[a+40>>2]|0;b=b+F[a+44>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>7|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-33554432;F[d+40>>2]=c-e;F[d+44>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>25;d=(c&33554431)<<7|f>>>25;c=d+F[a+48>>2]|0;b=b+F[a+52>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>6|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-67108864;F[d+48>>2]=c-e;F[d+52>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>26;d=(c&67108863)<<6|f>>>26;c=d+F[a+56>>2]|0;b=b+F[a+60>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>7|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-33554432;F[d+56>>2]=c-e;F[d+60>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>25;d=(c&33554431)<<7|f>>>25;c=d+F[a+64>>2]|0;b=b+F[a+68>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>6|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-67108864;F[d+64>>2]=c-e;F[d+68>>2]=g-((c>>>0>>0)+b|0);c=b;b=b>>26;d=(c&67108863)<<6|f>>>26;c=d+F[a+72>>2]|0;b=b+F[a+76>>2]|0;b=c>>>0>>0?b+1|0:b;g=b;e=b>>31>>>7|0;f=e+c|0;b=f>>>0>>0?b+1|0:b;d=a;e=f&-33554432;F[d+72>>2]=c-e;F[d+76>>2]=g-((c>>>0>>0)+b|0);d=F[d+80>>2];c=F[a+84>>2];F[a+80>>2]=0;F[a+84>>2]=0;g=c;c=b;b=b>>25;e=d;d=(c&33554431)<<7|f>>>25;c=e+d|0;b=b+g|0;b=c>>>0>>0?b+1|0:b;d=c;g=c+i|0;c=b;b=b+h|0;h=se(d,c,18,0);c=h+g|0;b=$+(d>>>0>g>>>0?b+1|0:b)|0;b=c>>>0>>0?b+1|0:b;h=b;i=b>>31>>>6|0;d=i+c|0;b=d>>>0>>0?b+1|0:b;i=d&-67108864;F[a>>2]=c-i;F[a+4>>2]=h-((c>>>0>>0)+b|0);h=F[a+12>>2];c=a;a=b;b=b>>26;g=(a&67108863)<<6|d>>>26;a=g+F[c+8>>2]|0;b=b+h|0;F[c+8>>2]=a;F[c+12>>2]=a>>>0>>0?b+1|0:b}function ka(a,b,c,d,e){var f=0,g=0;f=_-384|0;_=f;F[f+128>>2]=0;F[f+132>>2]=0;F[f+136>>2]=0;F[f+140>>2]=0;F[f+144>>2]=0;F[f+148>>2]=0;F[f+152>>2]=0;F[f+156>>2]=0;F[f+160>>2]=0;F[f+164>>2]=0;F[f+168>>2]=0;F[f+172>>2]=0;F[f+112>>2]=0;F[f+116>>2]=0;F[f+120>>2]=0;F[f+124>>2]=0;a:{if(b>>>0>=65){g=f+176|0;F[g+80>>2]=1779033703;F[g+84>>2]=-1150833019;F[g+72>>2]=0;F[g+76>>2]=0;F[g+64>>2]=0;F[g+104>>2]=528734635;F[g+108>>2]=1541459225;F[g+96>>2]=1359893119;F[g+100>>2]=-1694144372;F[g+88>>2]=1013904242;F[g+92>>2]=-1521486534;ra(g,a,b);Ba(g,f+112|0);break a}ja(f+112|0,a,b)}a=F[f+172>>2];F[f+232>>2]=F[f+168>>2];F[f+236>>2]=a;a=F[f+164>>2];F[f+224>>2]=F[f+160>>2];F[f+228>>2]=a;a=F[f+156>>2];F[f+216>>2]=F[f+152>>2];F[f+220>>2]=a;a=F[f+148>>2];F[f+208>>2]=F[f+144>>2];F[f+212>>2]=a;a=F[f+140>>2];F[f+200>>2]=F[f+136>>2];F[f+204>>2]=a;a=F[f+132>>2];F[f+192>>2]=F[f+128>>2];F[f+196>>2]=a;a=F[f+124>>2];F[f+184>>2]=F[f+120>>2];F[f+188>>2]=a;a=F[f+116>>2];F[f+176>>2]=F[f+112>>2];F[f+180>>2]=a;b=0;while(1){a=f+176|0;g=a+b|0;D[g|0]=G[g|0]^54;g=a+(b|1)|0;D[g|0]=G[g|0]^54;g=a+(b|2)|0;D[g|0]=G[g|0]^54;a=a+(b|3)|0;D[a|0]=G[a|0]^54;b=b+4|0;if((b|0)!=64){continue}break}F[f+80>>2]=1779033703;F[f+84>>2]=-1150833019;F[f+72>>2]=0;F[f+76>>2]=0;F[f+64>>2]=0;F[f+104>>2]=528734635;F[f+108>>2]=1541459225;F[f+96>>2]=1359893119;F[f+100>>2]=-1694144372;F[f+88>>2]=1013904242;F[f+92>>2]=-1521486534;a=f+176|0;ra(f,a,64);ia(a,64);ra(f,c,d);a=F[f+172>>2];F[f+344>>2]=F[f+168>>2];F[f+348>>2]=a;a=F[f+164>>2];F[f+336>>2]=F[f+160>>2];F[f+340>>2]=a;a=F[f+156>>2];F[f+328>>2]=F[f+152>>2];F[f+332>>2]=a;a=F[f+148>>2];F[f+320>>2]=F[f+144>>2];F[f+324>>2]=a;a=F[f+140>>2];F[f+312>>2]=F[f+136>>2];F[f+316>>2]=a;a=F[f+132>>2];F[f+304>>2]=F[f+128>>2];F[f+308>>2]=a;a=F[f+124>>2];F[f+296>>2]=F[f+120>>2];F[f+300>>2]=a;a=F[f+116>>2];F[f+288>>2]=F[f+112>>2];F[f+292>>2]=a;b=0;while(1){a=f+288|0;c=a+b|0;D[c|0]=G[c|0]^92;c=a+(b|1)|0;D[c|0]=G[c|0]^92;c=a+(b|2)|0;D[c|0]=G[c|0]^92;a=a+(b|3)|0;D[a|0]=G[a|0]^92;b=b+4|0;if((b|0)!=64){continue}break}Ba(f,f+352|0);a=f+176|0;F[a+80>>2]=1779033703;F[a+84>>2]=-1150833019;F[a+72>>2]=0;F[a+76>>2]=0;F[a+64>>2]=0;F[a+104>>2]=528734635;F[a+108>>2]=1541459225;F[a+96>>2]=1359893119;F[a+100>>2]=-1694144372;F[a+88>>2]=1013904242;F[a+92>>2]=-1521486534;b=f+288|0;ra(a,b,96);Ba(a,e);ia(a,112);ia(b,96);ia(f+112|0,64);ia(f,112);_=f+384|0}function Ia(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0;e=F[b+44>>2];d=F[b+48>>2];g=F[b+52>>2];h=F[b+56>>2];i=F[b+60>>2];f=b- -64|0;j=F[f>>2];k=F[b+68>>2];l=F[b+72>>2];m=F[b+76>>2];n=F[b+4>>2];o=F[b+8>>2];p=F[b+12>>2];q=F[b+16>>2];r=F[b+20>>2];s=F[b+24>>2];t=F[b+28>>2];u=F[b+32>>2];v=F[b+36>>2];F[a>>2]=F[b>>2]+F[b+40>>2];F[a+36>>2]=m+v;F[a+32>>2]=l+u;F[a+28>>2]=k+t;F[a+24>>2]=j+s;F[a+20>>2]=i+r;F[a+16>>2]=h+q;F[a+12>>2]=g+p;F[a+8>>2]=d+o;F[a+4>>2]=e+n;d=F[b+44>>2];g=F[b+48>>2];h=F[b+52>>2];i=F[b+56>>2];j=F[b+60>>2];f=F[f>>2];e=F[b+68>>2];k=F[b+72>>2];l=F[b>>2];m=F[b+40>>2];n=F[b+4>>2];o=F[b+8>>2];p=F[b+12>>2];q=F[b+16>>2];r=F[b+20>>2];s=F[b+24>>2];t=F[b+28>>2];u=F[b+32>>2];F[a+76>>2]=F[b+76>>2]-F[b+36>>2];F[a+72>>2]=k-u;F[a+68>>2]=e-t;e=a- -64|0;F[e>>2]=f-s;F[a+60>>2]=j-r;F[a+56>>2]=i-q;F[a+52>>2]=h-p;F[a+48>>2]=g-o;F[a+44>>2]=d-n;F[a+40>>2]=m-l;ha(a+80|0,a,c);d=a+40|0;ha(d,d,c+40|0);ha(a+120|0,c+120|0,b+120|0);ha(a,b+80|0,c+80|0);b=F[a+44>>2];c=F[a+84>>2];d=F[a+48>>2];g=F[a+88>>2];h=F[a+52>>2];i=F[a+92>>2];f=F[a+56>>2];j=F[a+96>>2];k=F[a+60>>2];l=F[a+100>>2];m=F[e>>2];n=F[a+104>>2];o=F[a+68>>2];p=F[a+108>>2];q=F[a+72>>2];r=F[a+112>>2];u=F[a>>2];v=F[a+4>>2];y=F[a+8>>2];z=F[a+12>>2];A=F[a+16>>2];B=F[a+20>>2];C=F[a+24>>2];D=F[a+28>>2];E=F[a+32>>2];G=F[a+36>>2];s=F[a+40>>2];t=F[a+80>>2];w=F[a+76>>2];x=F[a+116>>2];F[a+76>>2]=w+x;F[a+72>>2]=q+r;F[a+68>>2]=o+p;F[e>>2]=m+n;F[a+60>>2]=k+l;F[a+56>>2]=f+j;F[a+52>>2]=h+i;F[a+48>>2]=d+g;F[a+44>>2]=b+c;F[a+40>>2]=s+t;F[a+36>>2]=x-w;F[a+32>>2]=r-q;F[a+28>>2]=p-o;F[a+24>>2]=n-m;F[a+20>>2]=l-k;F[a+16>>2]=j-f;F[a+12>>2]=i-h;F[a+8>>2]=g-d;F[a+4>>2]=c-b;F[a>>2]=t-s;b=G<<1;c=F[a+156>>2];F[a+156>>2]=b-c;e=E<<1;d=F[a+152>>2];F[a+152>>2]=e-d;g=D<<1;h=F[a+148>>2];F[a+148>>2]=g-h;i=C<<1;f=F[a+144>>2];F[a+144>>2]=i-f;j=B<<1;k=F[a+140>>2];F[a+140>>2]=j-k;l=A<<1;m=F[a+136>>2];F[a+136>>2]=l-m;n=z<<1;o=F[a+132>>2];F[a+132>>2]=n-o;p=y<<1;q=F[a+128>>2];F[a+128>>2]=p-q;r=v<<1;s=F[a+124>>2];F[a+124>>2]=r-s;t=u<<1;u=F[a+120>>2];F[a+120>>2]=t-u;F[a+112>>2]=d+e;F[a+108>>2]=g+h;F[a+104>>2]=i+f;F[a+100>>2]=j+k;F[a+96>>2]=l+m;F[a+92>>2]=n+o;F[a+88>>2]=p+q;F[a+84>>2]=r+s;F[a+80>>2]=t+u;F[a+116>>2]=b+c}function lb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0;e=F[b+44>>2];d=F[b+48>>2];g=F[b+52>>2];h=F[b+56>>2];i=F[b+60>>2];f=b- -64|0;j=F[f>>2];k=F[b+68>>2];l=F[b+72>>2];m=F[b+76>>2];n=F[b+4>>2];o=F[b+8>>2];p=F[b+12>>2];q=F[b+16>>2];r=F[b+20>>2];s=F[b+24>>2];t=F[b+28>>2];u=F[b+32>>2];v=F[b+36>>2];F[a>>2]=F[b>>2]+F[b+40>>2];F[a+36>>2]=m+v;F[a+32>>2]=l+u;F[a+28>>2]=k+t;F[a+24>>2]=j+s;F[a+20>>2]=i+r;F[a+16>>2]=h+q;F[a+12>>2]=g+p;F[a+8>>2]=d+o;F[a+4>>2]=e+n;d=F[b+44>>2];g=F[b+48>>2];h=F[b+52>>2];i=F[b+56>>2];j=F[b+60>>2];f=F[f>>2];e=F[b+68>>2];k=F[b+72>>2];l=F[b>>2];m=F[b+40>>2];n=F[b+4>>2];o=F[b+8>>2];p=F[b+12>>2];q=F[b+16>>2];r=F[b+20>>2];s=F[b+24>>2];t=F[b+28>>2];u=F[b+32>>2];F[a+76>>2]=F[b+76>>2]-F[b+36>>2];F[a+72>>2]=k-u;F[a+68>>2]=e-t;e=a- -64|0;F[e>>2]=f-s;F[a+60>>2]=j-r;F[a+56>>2]=i-q;F[a+52>>2]=h-p;F[a+48>>2]=g-o;F[a+44>>2]=d-n;F[a+40>>2]=m-l;ha(a+80|0,a,c);d=a+40|0;ha(d,d,c+40|0);ha(a+120|0,c+80|0,b+120|0);u=F[b+84>>2];v=F[b+88>>2];y=F[b+92>>2];z=F[b+96>>2];A=F[b+100>>2];B=F[b+104>>2];C=F[b+108>>2];D=F[b+112>>2];E=F[b+116>>2];c=F[a+44>>2];d=F[a+84>>2];g=F[a+48>>2];h=F[a+88>>2];i=F[a+52>>2];f=F[a+92>>2];j=F[a+56>>2];k=F[a+96>>2];l=F[a+60>>2];m=F[a+100>>2];n=F[e>>2];o=F[a+104>>2];p=F[a+68>>2];q=F[a+108>>2];r=F[a+72>>2];s=F[a+112>>2];G=F[b+80>>2];b=F[a+40>>2];t=F[a+80>>2];w=F[a+76>>2];x=F[a+116>>2];F[a+76>>2]=w+x;F[a+72>>2]=r+s;F[a+68>>2]=p+q;F[e>>2]=n+o;F[a+60>>2]=l+m;F[a+56>>2]=j+k;F[a+52>>2]=i+f;F[a+48>>2]=g+h;F[a+44>>2]=c+d;F[a+40>>2]=b+t;F[a+36>>2]=x-w;F[a+32>>2]=s-r;F[a+28>>2]=q-p;F[a+24>>2]=o-n;F[a+20>>2]=m-l;F[a+16>>2]=k-j;F[a+12>>2]=f-i;F[a+8>>2]=h-g;F[a+4>>2]=d-c;F[a>>2]=t-b;b=E<<1;c=F[a+156>>2];F[a+156>>2]=b-c;e=D<<1;d=F[a+152>>2];F[a+152>>2]=e-d;g=C<<1;h=F[a+148>>2];F[a+148>>2]=g-h;i=B<<1;f=F[a+144>>2];F[a+144>>2]=i-f;j=A<<1;k=F[a+140>>2];F[a+140>>2]=j-k;l=z<<1;m=F[a+136>>2];F[a+136>>2]=l-m;n=y<<1;o=F[a+132>>2];F[a+132>>2]=n-o;p=v<<1;q=F[a+128>>2];F[a+128>>2]=p-q;r=u<<1;s=F[a+124>>2];F[a+124>>2]=r-s;t=G<<1;u=F[a+120>>2];F[a+120>>2]=t-u;F[a+112>>2]=d+e;F[a+108>>2]=g+h;F[a+104>>2]=i+f;F[a+100>>2]=j+k;F[a+96>>2]=l+m;F[a+92>>2]=n+o;F[a+88>>2]=p+q;F[a+84>>2]=r+s;F[a+80>>2]=t+u;F[a+116>>2]=b+c}function Nb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;c=_-480|0;_=c;while(1){f=c+288|0;e=f+(d<<1)|0;k=G[b+d|0];D[e+1|0]=k>>>4;D[e|0]=k&15;e=d|1;f=f+(e<<1)|0;e=G[b+e|0];D[f+1|0]=e>>>4;D[f|0]=e&15;d=d+2|0;if((d|0)!=32){continue}break}b=0;while(1){d=b;b=(c+288|0)+g|0;f=d+G[b|0]|0;d=(f<<24)- -134217728|0;D[b|0]=f-(d>>24&240);f=G[b+1|0]+(d>>28)|0;d=(f<<24)- -134217728|0;D[b+1|0]=f-(d>>24&240);f=G[b+2|0]+(d>>28)|0;d=(f<<24)- -134217728|0;D[b+2|0]=f-(d>>24&240);b=d>>28;g=g+3|0;if((g|0)!=63){continue}break}D[c+351|0]=G[c+351|0]+b;F[a+32>>2]=0;F[a+36>>2]=0;F[a+24>>2]=0;F[a+28>>2]=0;F[a+16>>2]=0;F[a+20>>2]=0;F[a+8>>2]=0;F[a+12>>2]=0;F[a>>2]=0;F[a+4>>2]=0;F[a+44>>2]=0;F[a+48>>2]=0;F[a+40>>2]=1;F[a+52>>2]=0;F[a+56>>2]=0;F[a+60>>2]=0;F[a+64>>2]=0;F[a+68>>2]=0;F[a+72>>2]=0;F[a+76>>2]=0;F[a+80>>2]=1;qa(a+84|0,0,76);k=a+120|0;p=a+80|0;q=a+40|0;b=c+208|0;f=c+168|0;g=c+248|0;d=1;while(1){h=c+8|0;Mb(h,d>>>1|0,D[(c+288|0)+d|0]);e=c+128|0;lb(e,a,h);ha(a,e,g);ha(q,f,b);ha(p,b,g);ha(k,e,f);e=d>>>0<62;d=d+2|0;if(e){continue}break}d=F[a>>2];e=F[a+4>>2];h=F[a+8>>2];i=F[a+12>>2];j=F[a+16>>2];l=F[a+20>>2];m=F[a+24>>2];n=F[a+28>>2];o=F[a+36>>2];F[c+392>>2]=F[a+32>>2];F[c+396>>2]=o;F[c+384>>2]=m;F[c+388>>2]=n;F[c+376>>2]=j;F[c+380>>2]=l;F[c+368>>2]=h;F[c+372>>2]=i;F[c+360>>2]=d;F[c+364>>2]=e;d=F[a+48>>2];e=F[a+52>>2];h=F[a+56>>2];i=F[a+60>>2];j=a- -64|0;l=F[j>>2];j=F[j+4>>2];m=F[a+40>>2];n=F[a+44>>2];o=F[a+76>>2];F[c+432>>2]=F[a+72>>2];F[c+436>>2]=o;F[c+424>>2]=l;F[c+428>>2]=j;F[c+416>>2]=h;F[c+420>>2]=i;F[c+408>>2]=d;F[c+412>>2]=e;F[c+400>>2]=m;F[c+404>>2]=n;d=F[a+88>>2];e=F[a+92>>2];h=F[a+96>>2];i=F[a+100>>2];j=F[a+104>>2];l=F[a+108>>2];m=F[a+80>>2];n=F[a+84>>2];o=F[a+116>>2];F[c+472>>2]=F[a+112>>2];F[c+476>>2]=o;F[c+464>>2]=j;F[c+468>>2]=l;F[c+456>>2]=h;F[c+460>>2]=i;F[c+448>>2]=d;F[c+452>>2]=e;F[c+440>>2]=m;F[c+444>>2]=n;d=c+128|0;e=c+360|0;Sa(d,e);ha(e,d,g);h=c+400|0;ha(h,f,b);i=c+440|0;ha(i,b,g);Sa(d,e);ha(e,d,g);ha(h,f,b);ha(i,b,g);Sa(d,e);ha(e,d,g);ha(h,f,b);ha(i,b,g);Sa(d,e);ha(a,d,g);ha(q,f,b);ha(p,b,g);ha(k,d,f);d=0;while(1){h=c+8|0;Mb(h,d>>>1|0,D[(c+288|0)+d|0]);e=c+128|0;lb(e,a,h);ha(a,e,g);ha(q,f,b);ha(p,b,g);ha(k,e,f);e=d>>>0<62;d=d+2|0;if(e){continue}break}_=c+480|0}function Ec(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;n=a+3216|0;b=Ya(b,c,d,e,n);a:{b:{if((b|0)==-1){break b}m=_-16|0;_=m;f=b+d|0;b=va(d,f,m+12|0);c:{if(!b){d=0;break c}d=0;d:{c=F[m+12>>2];if((c|0)!=1){if((c|0)!=-2147483647){break d}p=1}c=a+3220|0;if(!(!b|(b|0)==(f|0))){D[c|0]=G[b|0]!=0;i=b+1|0}if(!i){break c}b=Oa(i,f,a+3221|0);if(!b){break c}b=Oa(b,f,a+3253|0);if(!b){break c}b=Oa(b,f,a+3285|0);if(!b){break c}o=_-16|0;_=o;b=Ta(b,f,a+12|0,32);e:{if(!b){break e}i=a;g=a+44|0;a=0;j=_-16|0;_=j;b=va(b,f,j+12|0);f:{if(!b){break f}l=g+4|0;k=g+104|0;while(1){c=F[j+12>>2];F[j+12>>2]=c-1;if((b|0)==(f|0)){a=b;break f}if(!c){a=b;break f}c=l;d=k;h=F[g>>2];if((d|0)!=(h|0)){d=h+100|0;F[g>>2]=d;c=h}d=d-100|0;if((d|0)!=(c|0)){while(1){h=d;d=d-100|0;ja(h,d,100);if((c|0)!=(d|0)){continue}break}}b=Ja(b,f,c);if(!b){break f}b=Ta(b,f,c+68|0,32);if(!b){break f}b=va(b,f,c- -64|0);if(b){continue}break}}_=j+16|0;b=a;if(!b){break e}g=i+148|0;a=0;j=_-16|0;_=j;b=va(b,f,j+12|0);g:{if(!b){break g}l=g+276|0;k=g+344|0;while(1){c=F[j+12>>2];F[j+12>>2]=c-1;if((b|0)==(f|0)){a=b;break g}if(!c){a=b;break g}c=l;d=k;h=F[g>>2];if((d|0)!=(h|0)){d=h+68|0;F[g>>2]=d;c=h}d=d-68|0;if((d|0)!=(c|0)){while(1){h=d;d=d-68|0;ja(h,d,68);if((c|0)!=(d|0)){continue}break}}b=Oa(b,f,c);if(!b){break g}b=Ta(b,f,c+36|0,32);if(!b){break g}b=va(b,f,c+32|0);if(b){continue}break}}_=j+16|0;b=a;if(!b){break e}k=i+492|0;a=0;g=_-16|0;_=g;c=va(b,f,g+12|0);h:{if(!c){break h}h=k+2656|0;l=k+2724|0;while(1){b=F[g+12>>2];F[g+12>>2]=b-1;if((c|0)==(f|0)){a=c;break h}if(!b){a=c;break h}b=h;d=l;i=F[k>>2];if((d|0)!=(i|0)){d=i+68|0;F[k>>2]=d;b=i}d=d-68|0;if((d|0)!=(b|0)){while(1){i=d;d=d-68|0;ja(i,d,68);if((b|0)!=(d|0)){continue}break}}c=Oa(c,f,b);if(!c){break h}c=Ta(c,f,b+36|0,32);if(!c){break h}c=va(c,f,b+32|0);if(c){continue}break}}_=g+16|0;b=a;if(!b){break e}if(p){b=va(b,f,o+12|0);if(!b){break e}}q=b}_=o+16|0;d=q;break c}F[a+3216>>2]=9}_=m+16|0;i:{if(!d){if(F[n>>2]){break b}a=10;break i}a=17;if((d|0)==(f|0)){break a}}F[n>>2]=a}e=-1}return e|0}function dd(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=b;b=F[b>>2]+7&-8;F[d>>2]=b+16;o=a;a=b;k=F[a>>2];b=F[a+4>>2];e=F[a+12>>2];m=e;g=_-32|0;_=g;e=e&2147483647;c=e-1006698496|0;f=e-1140785152|0;d=F[a+8>>2];a:{if((c|0)==(f|0)&d>>>0>>0|c>>>0>>0){a=d;d=m<<4|a>>>28;c=a<<4|b>>>28;e=d;a=b&268435455;b=a;if((a|0)==134217728&(k|0)!=0|a>>>0>134217728){a=e+1073741824|0;b=c+1|0;a=b?a:a+1|0;c=b;break a}a=e+1073741824|0;if(b^134217728|k){break a}b=c&1;e=b+c|0;c=e;a=b>>>0>c>>>0?a+1|0:a;break a}if(!(!d&(e|0)==2147418112?!(b|k):e>>>0<2147418112)){a=d;d=m<<4|a>>>28;c=a<<4|b>>>28;a=d&524287|2146959360;break a}c=0;a=2146435072;if(e>>>0>1140785151){break a}a=0;n=e>>>16|0;if(n>>>0<15249){break a}c=k;a=b;f=m&65535|65536;e=f;l=d;h=d;j=n-15233|0;b:{if(j&64){f=c;d=j+-64|0;c=d&31;if((d&63)>>>0>=32){a=f<>>32-c|a<>>0>=32){d=h<>>32-i|f<>>0>=32){d=0;h=a>>>i|0}else{d=a>>>i|0;h=((1<>>i}h=p|h;f=d|f;i=j&31;if((j&63)>>>0>=32){d=c<>>32-i|a<>2]=c;F[g+20>>2]=a;F[g+24>>2]=h;F[g+28>>2]=f;d=15361-n|0;c:{if(d&64){b=l;a=d+-64|0;f=a&31;if((a&63)>>>0>=32){d=0;k=e>>>f|0}else{d=e>>>f|0;k=((1<>>f}b=d;l=0;e=0;break c}if(!d){break c}f=l;a=64-d|0;c=a&31;if((a&63)>>>0>=32){a=f<>>32-c|e<>>0>=32){d=0;b=b>>>j|0}else{d=b>>>j|0;b=((1<>>j}k=h|b;b=d|f;d=l;f=a&31;if((a&63)>>>0>=32){a=0;l=e>>>f|0}else{a=e>>>f|0;l=((1<>>f}e=a}F[g>>2]=k;F[g+4>>2]=b;F[g+8>>2]=l;F[g+12>>2]=e;b=F[g+8>>2];e=F[g+4>>2];c=b<<4|e>>>28;a=F[g+12>>2]<<4|b>>>28;e=e&268435455;b=F[g>>2]|(F[g+16>>2]|F[g+24>>2]|(F[g+20>>2]|F[g+28>>2]))!=0;if((e|0)==134217728&(b|0)!=0|e>>>0>134217728){b=c+1|0;a=b?a:a+1|0;c=b;break a}if(e^134217728|b){break a}b=c+(c&1)|0;a=b>>>0>>0?a+1|0:a;c=b}_=g+32|0;x(0,c|0);x(1,m&-2147483648|a);K[o>>3]=z()}function wb(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0;F[d+4>>2]=0;F[d+8>>2]=0;D[d|0]=0;F[d+12>>2]=0;F[d+16>>2]=0;c=c- -64|0;if(c>>>0>>0){D[d|0]=G[a|0];b=b-c|0;a:{if((b|0)==1){break a}h=a+b|0;a=a+1|0;while(1){c=a;if(G[a|0]==8){f=c+1|0;b=f;while(1){b:{if((b|0)==(h|0)){a=h;break b}g=D[b|0];a=b+1|0;b=a;if((g|0)<0){continue}}break}c:{if((a|0)==(f|0)){e=0;break c}g=(c^-1)+a|0;i=g&3;f=0;e=0;b=a;if((b-c|0)-2>>>0>=3){k=g&-4;g=0;while(1){e=(G[b-2|0]&127|(e<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;e=e|G[b|0]&127;g=g+4|0;if((k|0)!=(g|0)){continue}break}}if(!i){break c}while(1){b=b-1|0;e=G[b|0]&127|e<<7;f=f+1|0;if((i|0)!=(f|0)){continue}break}}F[d+4>>2]=e;k=1}if((a|0)==(h|0)){break a}if(G[a|0]==18){f=a+1|0;b=f;while(1){d:{if((b|0)==(h|0)){g=h;break d}e=D[b|0];g=b+1|0;b=g;if((e|0)<0){continue}}break}e:{if((g|0)==(f|0)){e=0;break e}j=(a^-1)+g|0;i=j&3;f=0;e=0;b=g;if((b-a|0)-2>>>0>=3){j=j&-4;a=0;while(1){e=(G[b-2|0]&127|(e<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;e=e|G[b|0]&127;a=a+4|0;if((j|0)!=(a|0)){continue}break}}if(i){while(1){b=b-1|0;e=G[b|0]&127|e<<7;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if(h-g>>>0>>0){break a}}F[d+16>>2]=e;F[d+12>>2]=g;a=e+g|0}f:{if((a|0)==(h|0)|(a|0)!=(c|0)){break f}g:{switch(G[c|0]&7){case 0:while(1){h:{if((c|0)==(h|0)){b=h;break h}a=D[c|0];b=c+1|0;c=b;if((a|0)<0){continue}}break};while(1){if((b|0)==(h|0)){a=h;break f}c=D[b|0];a=b+1|0;b=a;if((c|0)<0){continue}break};break f;case 2:break g;default:break a}}while(1){i:{if((c|0)==(h|0)){a=h;break i}b=D[c|0];a=c+1|0;c=a;if((b|0)<0){continue}}break}b=a;while(1){j:{if((b|0)==(h|0)){f=h;break j}c=D[b|0];f=b+1|0;b=f;if((c|0)<0){continue}}break}if((a|0)==(f|0)){break f}i=f-a|0;g=i&3;e=0;c=0;b=f;if(b+(a^-1)>>>0>=3){i=i&-4;a=0;while(1){c=(G[b-2|0]&127|(c<<14|(G[b-1|0]&127)<<7))<<14|(G[b-3|0]&127)<<7;b=b-4|0;c=c|G[b|0]&127;a=a+4|0;if((i|0)!=(a|0)){continue}break}}if(g){while(1){b=b-1|0;c=G[b|0]&127|c<<7;e=e+1|0;if((g|0)!=(e|0)){continue}break}}if(h-f>>>0>>0){break a}a=c+f|0}if((a|0)!=(h|0)){continue}break}}F[d+8>>2]=k}}function Ja(a,b,c){var d=0,e=0,f=0,g=0;a:{if(!a){break a}d=a+32|0;if(d>>>0>b>>>0){break a}f=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);g=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);D[c|0]=g;D[c+1|0]=g>>>8;D[c+2|0]=g>>>16;D[c+3|0]=g>>>24;D[c+4|0]=f;D[c+5|0]=f>>>8;D[c+6|0]=f>>>16;D[c+7|0]=f>>>24;f=G[a+28|0]|G[a+29|0]<<8|(G[a+30|0]<<16|G[a+31|0]<<24);g=G[a+24|0]|G[a+25|0]<<8|(G[a+26|0]<<16|G[a+27|0]<<24);D[c+24|0]=g;D[c+25|0]=g>>>8;D[c+26|0]=g>>>16;D[c+27|0]=g>>>24;D[c+28|0]=f;D[c+29|0]=f>>>8;D[c+30|0]=f>>>16;D[c+31|0]=f>>>24;f=G[a+20|0]|G[a+21|0]<<8|(G[a+22|0]<<16|G[a+23|0]<<24);g=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);D[c+16|0]=g;D[c+17|0]=g>>>8;D[c+18|0]=g>>>16;D[c+19|0]=g>>>24;D[c+20|0]=f;D[c+21|0]=f>>>8;D[c+22|0]=f>>>16;D[c+23|0]=f>>>24;f=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);g=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);D[c+8|0]=g;D[c+9|0]=g>>>8;D[c+10|0]=g>>>16;D[c+11|0]=g>>>24;D[c+12|0]=f;D[c+13|0]=f>>>8;D[c+14|0]=f>>>16;D[c+15|0]=f>>>24;a=a- -64|0;if(a>>>0>b>>>0){break a}e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);b=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);D[c+32|0]=b;D[c+33|0]=b>>>8;D[c+34|0]=b>>>16;D[c+35|0]=b>>>24;D[c+36|0]=e;D[c+37|0]=e>>>8;D[c+38|0]=e>>>16;D[c+39|0]=e>>>24;e=G[d+28|0]|G[d+29|0]<<8|(G[d+30|0]<<16|G[d+31|0]<<24);b=G[d+24|0]|G[d+25|0]<<8|(G[d+26|0]<<16|G[d+27|0]<<24);D[c+56|0]=b;D[c+57|0]=b>>>8;D[c+58|0]=b>>>16;D[c+59|0]=b>>>24;D[c+60|0]=e;D[c+61|0]=e>>>8;D[c+62|0]=e>>>16;D[c+63|0]=e>>>24;e=G[d+20|0]|G[d+21|0]<<8|(G[d+22|0]<<16|G[d+23|0]<<24);b=G[d+16|0]|G[d+17|0]<<8|(G[d+18|0]<<16|G[d+19|0]<<24);D[c+48|0]=b;D[c+49|0]=b>>>8;D[c+50|0]=b>>>16;D[c+51|0]=b>>>24;D[c+52|0]=e;D[c+53|0]=e>>>8;D[c+54|0]=e>>>16;D[c+55|0]=e>>>24;e=G[d+12|0]|G[d+13|0]<<8|(G[d+14|0]<<16|G[d+15|0]<<24);b=G[d+8|0]|G[d+9|0]<<8|(G[d+10|0]<<16|G[d+11|0]<<24);D[c+40|0]=b;D[c+41|0]=b>>>8;D[c+42|0]=b>>>16;D[c+43|0]=b>>>24;D[c+44|0]=e;D[c+45|0]=e>>>8;D[c+46|0]=e>>>16;D[c+47|0]=e>>>24;e=a}return e}function Na(a,b){var c=0,d=0;c=G[b+4|0]|G[b+5|0]<<8|(G[b+6|0]<<16|G[b+7|0]<<24);d=G[b|0]|G[b+1|0]<<8|(G[b+2|0]<<16|G[b+3|0]<<24);D[a|0]=d;D[a+1|0]=d>>>8;D[a+2|0]=d>>>16;D[a+3|0]=d>>>24;D[a+4|0]=c;D[a+5|0]=c>>>8;D[a+6|0]=c>>>16;D[a+7|0]=c>>>24;c=G[b+28|0]|G[b+29|0]<<8|(G[b+30|0]<<16|G[b+31|0]<<24);d=G[b+24|0]|G[b+25|0]<<8|(G[b+26|0]<<16|G[b+27|0]<<24);D[a+24|0]=d;D[a+25|0]=d>>>8;D[a+26|0]=d>>>16;D[a+27|0]=d>>>24;D[a+28|0]=c;D[a+29|0]=c>>>8;D[a+30|0]=c>>>16;D[a+31|0]=c>>>24;c=G[b+20|0]|G[b+21|0]<<8|(G[b+22|0]<<16|G[b+23|0]<<24);d=G[b+16|0]|G[b+17|0]<<8|(G[b+18|0]<<16|G[b+19|0]<<24);D[a+16|0]=d;D[a+17|0]=d>>>8;D[a+18|0]=d>>>16;D[a+19|0]=d>>>24;D[a+20|0]=c;D[a+21|0]=c>>>8;D[a+22|0]=c>>>16;D[a+23|0]=c>>>24;c=G[b+12|0]|G[b+13|0]<<8|(G[b+14|0]<<16|G[b+15|0]<<24);d=G[b+8|0]|G[b+9|0]<<8|(G[b+10|0]<<16|G[b+11|0]<<24);D[a+8|0]=d;D[a+9|0]=d>>>8;D[a+10|0]=d>>>16;D[a+11|0]=d>>>24;D[a+12|0]=c;D[a+13|0]=c>>>8;D[a+14|0]=c>>>16;D[a+15|0]=c>>>24;c=G[b+36|0]|G[b+37|0]<<8|(G[b+38|0]<<16|G[b+39|0]<<24);d=G[b+32|0]|G[b+33|0]<<8|(G[b+34|0]<<16|G[b+35|0]<<24);D[a+32|0]=d;D[a+33|0]=d>>>8;D[a+34|0]=d>>>16;D[a+35|0]=d>>>24;D[a+36|0]=c;D[a+37|0]=c>>>8;D[a+38|0]=c>>>16;D[a+39|0]=c>>>24;c=G[b+44|0]|G[b+45|0]<<8|(G[b+46|0]<<16|G[b+47|0]<<24);d=G[b+40|0]|G[b+41|0]<<8|(G[b+42|0]<<16|G[b+43|0]<<24);D[a+40|0]=d;D[a+41|0]=d>>>8;D[a+42|0]=d>>>16;D[a+43|0]=d>>>24;D[a+44|0]=c;D[a+45|0]=c>>>8;D[a+46|0]=c>>>16;D[a+47|0]=c>>>24;c=G[b+52|0]|G[b+53|0]<<8|(G[b+54|0]<<16|G[b+55|0]<<24);d=G[b+48|0]|G[b+49|0]<<8|(G[b+50|0]<<16|G[b+51|0]<<24);D[a+48|0]=d;D[a+49|0]=d>>>8;D[a+50|0]=d>>>16;D[a+51|0]=d>>>24;D[a+52|0]=c;D[a+53|0]=c>>>8;D[a+54|0]=c>>>16;D[a+55|0]=c>>>24;c=G[b+60|0]|G[b+61|0]<<8|(G[b+62|0]<<16|G[b+63|0]<<24);b=G[b+56|0]|G[b+57|0]<<8|(G[b+58|0]<<16|G[b+59|0]<<24);D[a+56|0]=b;D[a+57|0]=b>>>8;D[a+58|0]=b>>>16;D[a+59|0]=b>>>24;D[a+60|0]=c;D[a+61|0]=c>>>8;D[a+62|0]=c>>>16;D[a+63|0]=c>>>24;return a- -64|0}function jc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;if(c>>>0<43){F[a+3216>>2]=2;return-1}c=_-96|0;_=c;d=a+3245|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+24>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+28>>2]=e;d=a+3237|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+16>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+20>>2]=e;d=G[a+3225|0]|G[a+3226|0]<<8|(G[a+3227|0]<<16|G[a+3228|0]<<24);F[c>>2]=G[a+3221|0]|G[a+3222|0]<<8|(G[a+3223|0]<<16|G[a+3224|0]<<24);F[c+4>>2]=d;d=a+3229|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+8>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+12>>2]=e;d=a+3261|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+40>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+44>>2]=e;d=a+3269|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+48>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+52>>2]=e;d=a+3277|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+56>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+60>>2]=e;d=G[a+3257|0]|G[a+3258|0]<<8|(G[a+3259|0]<<16|G[a+3260|0]<<24);F[c+32>>2]=G[a+3253|0]|G[a+3254|0]<<8|(G[a+3255|0]<<16|G[a+3256|0]<<24);F[c+36>>2]=d;d=a+3293|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+72>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+76>>2]=e;d=a+3301|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+80>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+84>>2]=e;d=a+3309|0;e=G[d+4|0]|G[d+5|0]<<8|(G[d+6|0]<<16|G[d+7|0]<<24);F[c+88>>2]=G[d|0]|G[d+1|0]<<8|(G[d+2|0]<<16|G[d+3|0]<<24);F[c+92>>2]=e;d=G[a+3289|0]|G[a+3290|0]<<8|(G[a+3291|0]<<16|G[a+3292|0]<<24);F[c+64>>2]=G[a+3285|0]|G[a+3286|0]<<8|(G[a+3287|0]<<16|G[a+3288|0]<<24);F[c+68>>2]=d;Kb(c,96,b+11|0);_=c+96|0;ma(b+11|0,32,b);return 43}function Fc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;l=a+7516|0;c=Ya(b,c,d,e,l);a:{b:{if((c|0)==-1){break b}f=a;b=0;h=_-16|0;_=h;g=c+d|0;a=va(d,g,h+12|0);c:{if(!a){break c}d:{switch(F[h+12>>2]-1|0){case 0:F[f+7516>>2]=13;break c;default:F[f+7516>>2]=9;break c;case 1:case 2:case 3:break d}}a=rb(a,g,f);if(!a){break c}a=Ja(a,g,f+96|0);if(!a){break c}k=f+160|0;i=_-16|0;_=i;c=va(a,g,i+12|0);e:{if(!c){break e}n=k+7132|0;o=k+7204|0;while(1){a=F[i+12>>2];F[i+12>>2]=a-1;if((c|0)==(g|0)){b=c;break e}if(!a){b=c;break e}a=n;d=o;j=F[k>>2];if((d|0)!=(j|0)){d=j+72|0;F[k>>2]=d;a=j}d=d-72|0;if((d|0)!=(a|0)){while(1){j=d;d=d-72|0;ja(j,d,72);if((a|0)!=(d|0)){continue}break}}d=va(c,g,a);if(!d){break e}c=0;if(!(!d|(d|0)==(g|0))){D[a+4|0]=G[d|0]!=0;c=d+1|0}if(!c){break e}c=Ja(c,g,a+5|0);if(c){continue}break}}_=i+16|0;a=b;if(!a){break c}b=F[h+12>>2];f:{if(b>>>0<=2){D[f+7364|0]=0;break f}g:{if((b|0)==3){a=va(a,g,f+7368|0);if(!a){break c}b=f+7372|0;c=0;if(!(!a|(a|0)==(g|0))){D[b|0]=G[a|0]!=0;c=a+1|0}if(!c){break c}a=Ja(c,g,f+7373|0);if(!a){break c}a=va(a,g,f+7440|0);if(!a){break c}d=f+7444|0;c=0;if(!(!a|(a|0)==(g|0))){D[d|0]=G[a|0]!=0;c=a+1|0}if(!c){break c}a=Ja(c,g,f+7445|0);if(!a){break c}if(G[b|0]){if(!G[f+7444|0]){break g}D[f+7364|0]=2;break f}D[f+7364|0]=0;break f}c=f+7364|0;b=0;if(!a|(a|0)==(g|0)){a=b}else{D[c|0]=G[a|0];a=a+1|0}if(!a){break c}if(!G[c|0]){break f}a=vb(a,g,f+7368|0);if(!a){break c}if(G[c|0]<2){break f}a=vb(a,g,f+7440|0);if(!a){break c}if(G[c|0]<3){break f}F[f+7516>>2]=10;break c}D[f+7364|0]=1}m=va(a,g,f+7512|0)}_=h+16|0;h:{if(!m){if(F[l>>2]){break b}a=10;break h}a=17;if((g|0)==(m|0)){break a}}F[l>>2]=a}e=-1}return e|0}function Ea(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;o=F[b>>2];d=F[a>>2];p=F[b+4>>2];e=F[a+4>>2];q=F[b+8>>2];f=F[a+8>>2];r=F[b+12>>2];g=F[a+12>>2];s=F[b+16>>2];h=F[a+16>>2];m=F[b+20>>2];i=F[a+20>>2];t=F[b+24>>2];j=F[a+24>>2];u=F[b+28>>2];k=F[a+28>>2];v=F[b+32>>2];l=F[a+32>>2];c=0-c|0;n=F[a+36>>2];F[a+36>>2]=c&(n^F[b+36>>2])^n;F[a+32>>2]=l^c&(l^v);F[a+28>>2]=k^c&(k^u);F[a+24>>2]=j^c&(j^t);F[a+20>>2]=i^c&(i^m);F[a+16>>2]=h^c&(h^s);F[a+12>>2]=g^c&(g^r);F[a+8>>2]=f^c&(f^q);F[a+4>>2]=e^c&(e^p);F[a>>2]=d^c&(d^o);d=F[a+44>>2];o=F[b+44>>2];e=F[a+48>>2];p=F[b+48>>2];f=F[a+52>>2];q=F[b+52>>2];g=F[a+56>>2];r=F[b+56>>2];h=F[a+60>>2];s=F[b+60>>2];m=a- -64|0;i=F[m>>2];t=F[b- -64>>2];j=F[a+68>>2];u=F[b+68>>2];k=F[a+72>>2];v=F[b+72>>2];l=F[a+40>>2];n=F[b+40>>2];w=F[a+76>>2];F[a+76>>2]=w^c&(F[b+76>>2]^w);F[a+72>>2]=k^c&(k^v);F[a+68>>2]=j^c&(j^u);F[m>>2]=i^c&(i^t);F[a+60>>2]=h^c&(h^s);F[a+56>>2]=g^c&(g^r);F[a+52>>2]=f^c&(f^q);F[a+48>>2]=e^c&(e^p);F[a+44>>2]=d^c&(d^o);F[a+40>>2]=l^c&(l^n);d=F[a+84>>2];o=F[b+84>>2];e=F[a+88>>2];p=F[b+88>>2];f=F[a+92>>2];q=F[b+92>>2];g=F[a+96>>2];r=F[b+96>>2];h=F[a+100>>2];s=F[b+100>>2];i=F[a+104>>2];m=F[b+104>>2];j=F[a+108>>2];t=F[b+108>>2];k=F[a+112>>2];u=F[b+112>>2];l=F[a+80>>2];v=F[b+80>>2];n=F[b+116>>2];b=F[a+116>>2];F[a+116>>2]=c&(n^b)^b;F[a+112>>2]=k^c&(k^u);F[a+108>>2]=j^c&(j^t);F[a+104>>2]=i^c&(i^m);F[a+100>>2]=h^c&(h^s);F[a+96>>2]=g^c&(g^r);F[a+92>>2]=f^c&(f^q);F[a+88>>2]=e^c&(e^p);F[a+84>>2]=d^c&(d^o);F[a+80>>2]=l^c&(l^v)}function nb(a,b){var c=0,d=0,e=0;c=_-192|0;_=c;e=c+144|0;fa(e,b);d=c+96|0;fa(d,e);fa(d,d);ha(d,b,d);ha(e,e,d);b=c+48|0;fa(b,e);ha(d,d,b);fa(b,d);fa(b,b);fa(b,b);fa(b,b);fa(b,b);ha(d,b,d);fa(b,d);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);ha(b,b,d);fa(c,b);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);fa(c,c);ha(b,c,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);ha(d,b,d);fa(b,d);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);ha(b,b,d);fa(c,b);b=1;while(1){fa(c,c);b=b+1|0;if((b|0)!=100){continue}break}b=c+48|0;ha(b,c,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);fa(b,b);d=c+96|0;ha(d,b,d);fa(d,d);fa(d,d);fa(d,d);fa(d,d);fa(d,d);ha(a,d,c+144|0);_=c+192|0}function kb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;f=_-336|0;_=f;i=b+32|0;g=32;c=_-208|0;_=c;d=c- -64|0;F[d>>2]=327033209;F[d+4>>2]=1541459225;F[c+56>>2]=-79577749;F[c+60>>2]=528734635;F[c+48>>2]=725511199;F[c+52>>2]=-1694144372;F[c+40>>2]=-1377402159;F[c+44>>2]=1359893119;F[c+32>>2]=1595750129;F[c+36>>2]=-1521486534;F[c+24>>2]=-23791573;F[c+28>>2]=1013904242;F[c+16>>2]=-2067093701;F[c+20>>2]=-1150833019;F[c+8>>2]=-205731576;F[c+12>>2]=1779033703;F[c>>2]=0;F[c+4>>2]=0;F[c+72>>2]=0;if(a){j=c+76|0;while(1){a:{if(!(g>>>0<128|e)){ua(c,a);d=F[c+4>>2];e=F[c>>2]+1024|0;d=e>>>0<1024?d+1|0:d;F[c>>2]=e;F[c+4>>2]=d;g=g-128|0;a=a+128|0;break a}d=128-e|0;h=d>>>0>g>>>0?g:d;b:{if(!h){break b}m=h&3;k=0;c:{if(h-1>>>0<3){d=0;break c}n=h&-4;d=0;l=0;while(1){D[(d+e|0)+j|0]=G[a+d|0];e=d|1;D[(e+F[c+72>>2]|0)+j|0]=G[a+e|0];e=d|2;D[(e+F[c+72>>2]|0)+j|0]=G[a+e|0];e=d|3;D[(e+F[c+72>>2]|0)+j|0]=G[a+e|0];d=d+4|0;e=F[c+72>>2];l=l+4|0;if((n|0)!=(l|0)){continue}break}}if(!m){break b}while(1){D[(c+(d+e|0)|0)+76|0]=G[a+d|0];d=d+1|0;e=F[c+72>>2];k=k+1|0;if((k|0)!=(m|0)){continue}break}}g=g-h|0;a=a+h|0;d=e+h|0;F[c+72>>2]=d;if((d|0)!=128){break a}ua(c,j);F[c+72>>2]=0;d=F[c+4>>2];e=F[c>>2]+1024|0;d=e>>>0<1024?d+1|0:d;F[c>>2]=e;F[c+4>>2]=d}if(g){e=F[c+72>>2];continue}break}db(c,i)}_=c+208|0;D[i|0]=G[i|0]&248;D[i+31|0]=G[i+31|0]&63|64;Nb(f,i);a=f+256|0;nb(a,f+80|0);c=f+208|0;ha(c,f,a);d=f+160|0;ha(d,f+40|0,a);Ga(b,d);Ga(f+304|0,c);D[b+31|0]=G[b+31|0]^G[f+304|0]<<7;_=f+336|0}function Mb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;d=_-128|0;_=d;F[a+4>>2]=0;F[a+8>>2]=0;F[a>>2]=1;F[a+12>>2]=0;F[a+16>>2]=0;F[a+20>>2]=0;F[a+24>>2]=0;F[a+28>>2]=0;F[a+32>>2]=0;F[a+36>>2]=0;F[a+40>>2]=1;qa(a+44|0,0,76);e=L(b,960);f=c-((c>>7&c)<<1)|0;b=0-!((f^1)&255)|0;Ea(a,e+6640|0,b>>>31|0);b=0-!((f^2)&255)|0;Ea(a,e+6760|0,b>>>31|0);b=0-!((f^3)&255)|0;Ea(a,e+6880|0,b>>>31|0);b=0-!((f^4)&255)|0;Ea(a,e+7e3|0,b>>>31|0);b=0-!((f^5)&255)|0;Ea(a,e+7120|0,b>>>31|0);b=0-!((f^6)&255)|0;Ea(a,e+7240|0,b>>>31|0);b=0-!((f^7)&255)|0;Ea(a,e+7360|0,b>>>31|0);b=0-!((f^8)&255)|0;Ea(a,e+7480|0,b>>>31|0);g=F[a+48>>2];h=F[a+52>>2];i=F[a+56>>2];j=F[a+60>>2];b=a- -64|0;k=F[b>>2];e=F[b+4>>2];f=F[a+40>>2];l=F[a+44>>2];b=F[a+76>>2];F[d+40>>2]=F[a+72>>2];F[d+44>>2]=b;F[d+32>>2]=k;F[d+36>>2]=e;F[d+24>>2]=i;F[d+28>>2]=j;F[d+16>>2]=g;F[d+20>>2]=h;F[d+8>>2]=f;F[d+12>>2]=l;g=F[a>>2];h=F[a+4>>2];i=F[a+8>>2];j=F[a+12>>2];k=F[a+16>>2];e=F[a+20>>2];f=F[a+24>>2];l=F[a+28>>2];b=F[a+36>>2];F[d+80>>2]=F[a+32>>2];F[d+84>>2]=b;F[d+72>>2]=f;F[d+76>>2]=l;b=d- -64|0;F[b>>2]=k;F[b+4>>2]=e;F[d+56>>2]=i;F[d+60>>2]=j;F[d+48>>2]=g;F[d+52>>2]=h;g=F[a+116>>2];h=F[a+84>>2];i=F[a+88>>2];j=F[a+92>>2];k=F[a+96>>2];e=F[a+100>>2];f=F[a+104>>2];l=F[a+108>>2];b=F[a+80>>2];F[d+120>>2]=0-F[a+112>>2];F[d+116>>2]=0-l;F[d+112>>2]=0-f;F[d+108>>2]=0-e;F[d+104>>2]=0-k;F[d+100>>2]=0-j;F[d+96>>2]=0-i;F[d+92>>2]=0-h;F[d+124>>2]=0-g;F[d+88>>2]=0-b;Ea(a,d+8|0,(c&128)>>>7|0);_=d+128|0}function Pd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=_-240|0;_=d;e=oa(c);a:{if((e|0)!=229){c=-1;if((e|0)==-1){F[a+300>>2]=7;break a}F[a+300>>2]=11;break a}Pa(b,c,d);b:{if(G[d|0]==2){c=d|5;b=G[d+1|0]|G[d+2|0]<<8|(G[d+3|0]<<16|G[d+4|0]<<24);b=b<<24|b<<8&16711680|(b>>>8&65280|b>>>24);$a(a,c,b);$a(a+132|0,c,b);b=G[d+161|0]|G[d+162|0]<<8|(G[d+163|0]<<16|G[d+164|0]<<24);c=G[d+157|0]|G[d+158|0]<<8|(G[d+159|0]<<16|G[d+160|0]<<24);D[a+288|0]=c;D[a+289|0]=c>>>8;D[a+290|0]=c>>>16;D[a+291|0]=c>>>24;D[a+292|0]=b;D[a+293|0]=b>>>8;D[a+294|0]=b>>>16;D[a+295|0]=b>>>24;b=G[d+153|0]|G[d+154|0]<<8|(G[d+155|0]<<16|G[d+156|0]<<24);c=G[d+149|0]|G[d+150|0]<<8|(G[d+151|0]<<16|G[d+152|0]<<24);D[a+280|0]=c;D[a+281|0]=c>>>8;D[a+282|0]=c>>>16;D[a+283|0]=c>>>24;D[a+284|0]=b;D[a+285|0]=b>>>8;D[a+286|0]=b>>>16;D[a+287|0]=b>>>24;b=G[d+145|0]|G[d+146|0]<<8|(G[d+147|0]<<16|G[d+148|0]<<24);c=G[d+141|0]|G[d+142|0]<<8|(G[d+143|0]<<16|G[d+144|0]<<24);D[a+272|0]=c;D[a+273|0]=c>>>8;D[a+274|0]=c>>>16;D[a+275|0]=c>>>24;D[a+276|0]=b;D[a+277|0]=b>>>8;D[a+278|0]=b>>>16;D[a+279|0]=b>>>24;b=G[d+137|0]|G[d+138|0]<<8|(G[d+139|0]<<16|G[d+140|0]<<24);c=G[d+133|0]|G[d+134|0]<<8|(G[d+135|0]<<16|G[d+136|0]<<24);D[a+264|0]=c;D[a+265|0]=c>>>8;D[a+266|0]=c>>>16;D[a+267|0]=c>>>24;D[a+268|0]=b;D[a+269|0]=b>>>8;D[a+270|0]=b>>>16;D[a+271|0]=b>>>24;if(!hb(a+264|0,d,165,d+165|0)){F[a+300>>2]=14;c=-1;break b}F[a+296>>2]=1;c=0;break b}F[a+300>>2]=11;c=-1}ia(d,229)}_=d+240|0;return c|0}function Fd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;f=_-144|0;_=f;a:{if(c>>>0<220){F[a+300>>2]=2;a=-1;break a}b:{c:{if((d-F[a+260>>2]|0)>=0){c=a+132|0;cb(c,d);ja(f+8|0,c,132);break c}if((d-F[a+128>>2]|0)<0){break b}c=f+8|0;ja(c,a,132);cb(c,d)}c=b+55|0;D[c+1|0]=d>>>24;D[c|0]=1;D[c+4|0]=d;D[c+3|0]=d>>>8;D[c+2|0]=d>>>16;ja(c+5|0,f+8|0,128);d=G[a+292|0]|G[a+293|0]<<8|(G[a+294|0]<<16|G[a+295|0]<<24);e=G[a+288|0]|G[a+289|0]<<8|(G[a+290|0]<<16|G[a+291|0]<<24);D[c+157|0]=e;D[c+158|0]=e>>>8;D[c+159|0]=e>>>16;D[c+160|0]=e>>>24;D[c+161|0]=d;D[c+162|0]=d>>>8;D[c+163|0]=d>>>16;D[c+164|0]=d>>>24;d=G[a+284|0]|G[a+285|0]<<8|(G[a+286|0]<<16|G[a+287|0]<<24);e=G[a+280|0]|G[a+281|0]<<8|(G[a+282|0]<<16|G[a+283|0]<<24);D[c+149|0]=e;D[c+150|0]=e>>>8;D[c+151|0]=e>>>16;D[c+152|0]=e>>>24;D[c+153|0]=d;D[c+154|0]=d>>>8;D[c+155|0]=d>>>16;D[c+156|0]=d>>>24;d=G[a+276|0]|G[a+277|0]<<8|(G[a+278|0]<<16|G[a+279|0]<<24);e=G[a+272|0]|G[a+273|0]<<8|(G[a+274|0]<<16|G[a+275|0]<<24);D[c+141|0]=e;D[c+142|0]=e>>>8;D[c+143|0]=e>>>16;D[c+144|0]=e>>>24;D[c+145|0]=d;D[c+146|0]=d>>>8;D[c+147|0]=d>>>16;D[c+148|0]=d>>>24;d=G[a+268|0]|G[a+269|0]<<8|(G[a+270|0]<<16|G[a+271|0]<<24);a=G[a+264|0]|G[a+265|0]<<8|(G[a+266|0]<<16|G[a+267|0]<<24);D[c+133|0]=a;D[c+134|0]=a>>>8;D[c+135|0]=a>>>16;D[c+136|0]=a>>>24;D[c+137|0]=d;D[c+138|0]=d>>>8;D[c+139|0]=d>>>16;D[c+140|0]=d>>>24;a=Ca(c,165,b);break a}F[a+300>>2]=12;a=-1}_=f+144|0;return a|0}function Od(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=_-176|0;_=d;e=oa(c);a:{if((e|0)!=165){c=-1;if((e|0)==-1){F[a+300>>2]=7;break a}F[a+300>>2]=11;break a}Pa(b,c,d);b:{if(G[d|0]==1){c=d|5;b=G[d+1|0]|G[d+2|0]<<8|(G[d+3|0]<<16|G[d+4|0]<<24);b=b<<24|b<<8&16711680|(b>>>8&65280|b>>>24);$a(a,c,b);$a(a+132|0,c,b);b=G[d+161|0]|G[d+162|0]<<8|(G[d+163|0]<<16|G[d+164|0]<<24);c=G[d+157|0]|G[d+158|0]<<8|(G[d+159|0]<<16|G[d+160|0]<<24);D[a+288|0]=c;D[a+289|0]=c>>>8;D[a+290|0]=c>>>16;D[a+291|0]=c>>>24;D[a+292|0]=b;D[a+293|0]=b>>>8;D[a+294|0]=b>>>16;D[a+295|0]=b>>>24;b=G[d+153|0]|G[d+154|0]<<8|(G[d+155|0]<<16|G[d+156|0]<<24);c=G[d+149|0]|G[d+150|0]<<8|(G[d+151|0]<<16|G[d+152|0]<<24);D[a+280|0]=c;D[a+281|0]=c>>>8;D[a+282|0]=c>>>16;D[a+283|0]=c>>>24;D[a+284|0]=b;D[a+285|0]=b>>>8;D[a+286|0]=b>>>16;D[a+287|0]=b>>>24;b=G[d+145|0]|G[d+146|0]<<8|(G[d+147|0]<<16|G[d+148|0]<<24);c=G[d+141|0]|G[d+142|0]<<8|(G[d+143|0]<<16|G[d+144|0]<<24);D[a+272|0]=c;D[a+273|0]=c>>>8;D[a+274|0]=c>>>16;D[a+275|0]=c>>>24;D[a+276|0]=b;D[a+277|0]=b>>>8;D[a+278|0]=b>>>16;D[a+279|0]=b>>>24;b=G[d+137|0]|G[d+138|0]<<8|(G[d+139|0]<<16|G[d+140|0]<<24);c=G[d+133|0]|G[d+134|0]<<8|(G[d+135|0]<<16|G[d+136|0]<<24);D[a+264|0]=c;D[a+265|0]=c>>>8;D[a+266|0]=c>>>16;D[a+267|0]=c>>>24;D[a+268|0]=b;D[a+269|0]=b>>>8;D[a+270|0]=b>>>16;D[a+271|0]=b>>>24;c=0;break b}F[a+300>>2]=11;c=-1}ia(d,165)}_=d+176|0;return c|0}function Ba(a,b){var c=0,d=0,e=0;c=F[a+64>>2];D[c+a|0]=128;d=c+1|0;a:{if(c>>>0<=55){if(d>>>0>55){break a}qa(a+d|0,0,55-c|0);break a}if(d>>>0<=63){qa(a+d|0,0,63-c|0)}gb(a,a);F[a+48>>2]=0;F[a+52>>2]=0;F[a+40>>2]=0;F[a+44>>2]=0;F[a+32>>2]=0;F[a+36>>2]=0;F[a+24>>2]=0;F[a+28>>2]=0;F[a+16>>2]=0;F[a+20>>2]=0;F[a+8>>2]=0;F[a+12>>2]=0;F[a>>2]=0;F[a+4>>2]=0}c=F[a+76>>2];d=F[a+64>>2]<<3;e=d+F[a+72>>2]|0;c=e>>>0>>0?c+1|0:c;d=e;F[a+72>>2]=d;F[a+76>>2]=c;D[a+63|0]=d;D[a+62|0]=(c&255)<<24|d>>>8;D[a+61|0]=(c&65535)<<16|d>>>16;D[a+60|0]=(c&16777215)<<8|d>>>24;D[a+59|0]=c;D[a+58|0]=c>>>8;D[a+57|0]=c>>>16;D[a+56|0]=c>>>24;gb(a,a);D[b|0]=G[a+83|0];D[b+4|0]=G[a+87|0];D[b+8|0]=G[a+91|0];D[b+12|0]=G[a+95|0];D[b+16|0]=G[a+99|0];D[b+20|0]=G[a+103|0];D[b+24|0]=G[a+107|0];D[b+28|0]=G[a+111|0];D[b+1|0]=H[a+82>>1];D[b+5|0]=H[a+86>>1];D[b+9|0]=H[a+90>>1];D[b+13|0]=H[a+94>>1];D[b+17|0]=H[a+98>>1];D[b+21|0]=H[a+102>>1];D[b+25|0]=H[a+106>>1];D[b+29|0]=H[a+110>>1];D[b+2|0]=F[a+80>>2]>>>8;D[b+6|0]=F[a+84>>2]>>>8;D[b+10|0]=F[a+88>>2]>>>8;D[b+14|0]=F[a+92>>2]>>>8;D[b+18|0]=F[a+96>>2]>>>8;D[b+22|0]=F[a+100>>2]>>>8;D[b+26|0]=F[a+104>>2]>>>8;D[b+30|0]=F[a+108>>2]>>>8;D[b+3|0]=F[a+80>>2];D[b+7|0]=F[a+84>>2];D[b+11|0]=F[a+88>>2];D[b+15|0]=F[a+92>>2];D[b+19|0]=F[a+96>>2];D[b+23|0]=F[a+100>>2];D[b+27|0]=F[a+104>>2];D[b+31|0]=F[a+108>>2]}function qd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;if(c>>>0<306){F[a+228>>2]=2;return-1}c=b+77|0;D[c|0]=2;d=F[a+128>>2];d=d<<24|d<<8&16711680|(d>>>8&65280|d>>>24);D[c+1|0]=d;D[c+2|0]=d>>>8;D[c+3|0]=d>>>16;D[c+4|0]=d>>>24;ja(c+5|0,a,128);d=G[a+160|0]|G[a+161|0]<<8|(G[a+162|0]<<16|G[a+163|0]<<24);e=G[a+156|0]|G[a+157|0]<<8|(G[a+158|0]<<16|G[a+159|0]<<24);D[c+157|0]=e;D[c+158|0]=e>>>8;D[c+159|0]=e>>>16;D[c+160|0]=e>>>24;D[c+161|0]=d;D[c+162|0]=d>>>8;D[c+163|0]=d>>>16;D[c+164|0]=d>>>24;d=G[a+152|0]|G[a+153|0]<<8|(G[a+154|0]<<16|G[a+155|0]<<24);e=G[a+148|0]|G[a+149|0]<<8|(G[a+150|0]<<16|G[a+151|0]<<24);D[c+149|0]=e;D[c+150|0]=e>>>8;D[c+151|0]=e>>>16;D[c+152|0]=e>>>24;D[c+153|0]=d;D[c+154|0]=d>>>8;D[c+155|0]=d>>>16;D[c+156|0]=d>>>24;d=G[a+144|0]|G[a+145|0]<<8|(G[a+146|0]<<16|G[a+147|0]<<24);e=G[a+140|0]|G[a+141|0]<<8|(G[a+142|0]<<16|G[a+143|0]<<24);D[c+141|0]=e;D[c+142|0]=e>>>8;D[c+143|0]=e>>>16;D[c+144|0]=e>>>24;D[c+145|0]=d;D[c+146|0]=d>>>8;D[c+147|0]=d>>>16;D[c+148|0]=d>>>24;d=G[a+136|0]|G[a+137|0]<<8|(G[a+138|0]<<16|G[a+139|0]<<24);e=G[a+132|0]|G[a+133|0]<<8|(G[a+134|0]<<16|G[a+135|0]<<24);D[c+133|0]=e;D[c+134|0]=e>>>8;D[c+135|0]=e>>>16;D[c+136|0]=e>>>24;D[c+137|0]=d;D[c+138|0]=d>>>8;D[c+139|0]=d>>>16;D[c+140|0]=d>>>24;bb(a+132|0,c,165,c+165|0);return Ca(c,229,b)|0}function xa(a){var b=0,c=0,d=0,e=0;b=L(G[a+12|0],6);c=L(G[a+8|0],6);d=L(G[a+4|0],6);e=L(G[a|0],6);D[a+12|0]=G[b+3653|0]^(G[c+3650|0]^(G[d+3652|0]^G[e+3651|0]));D[a+8|0]=G[b+3651|0]^(G[c+3653|0]^(G[d+3650|0]^G[e+3652|0]));D[a+4|0]=G[b+3652|0]^(G[c+3651|0]^(G[d+3653|0]^G[e+3650|0]));D[a|0]=G[b+3650|0]^(G[c+3652|0]^(G[d+3651|0]^G[e+3653|0]));b=L(G[a+13|0],6);c=L(G[a+9|0],6);d=L(G[a+5|0],6);e=L(G[a+1|0],6);D[a+1|0]=G[b+3650|0]^(G[c+3652|0]^(G[d+3651|0]^G[e+3653|0]));D[a+5|0]=G[b+3652|0]^(G[c+3651|0]^(G[d+3653|0]^G[e+3650|0]));D[a+9|0]=G[b+3651|0]^(G[c+3653|0]^(G[d+3650|0]^G[e+3652|0]));D[a+13|0]=G[b+3653|0]^(G[c+3650|0]^(G[d+3652|0]^G[e+3651|0]));b=L(G[a+14|0],6);c=L(G[a+10|0],6);d=L(G[a+6|0],6);e=L(G[a+2|0],6);D[a+2|0]=G[b+3650|0]^(G[c+3652|0]^(G[d+3651|0]^G[e+3653|0]));D[a+14|0]=G[b+3653|0]^(G[c+3650|0]^(G[d+3652|0]^G[e+3651|0]));D[a+10|0]=G[b+3651|0]^(G[c+3653|0]^(G[d+3650|0]^G[e+3652|0]));D[a+6|0]=G[b+3652|0]^(G[c+3651|0]^(G[d+3653|0]^G[e+3650|0]));b=L(G[a+15|0],6);c=L(G[a+11|0],6);d=L(G[a+7|0],6);e=L(G[a+3|0],6);D[a+15|0]=G[b+3653|0]^(G[c+3650|0]^(G[d+3652|0]^G[e+3651|0]));D[a+11|0]=G[b+3651|0]^(G[c+3653|0]^(G[d+3650|0]^G[e+3652|0]));D[a+7|0]=G[b+3652|0]^(G[c+3651|0]^(G[d+3653|0]^G[e+3650|0]));D[a+3|0]=G[b+3650|0]^(G[c+3652|0]^(G[d+3651|0]^G[e+3653|0]))}function Hb(a,b){var c=0,d=0;c=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);F[b>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);c=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);F[b+4>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);c=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);F[b+8>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);c=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);F[b+12>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);c=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);F[b+16>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);c=G[a+20|0]|G[a+21|0]<<8|(G[a+22|0]<<16|G[a+23|0]<<24);F[b+20>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);c=G[a+24|0]|G[a+25|0]<<8|(G[a+26|0]<<16|G[a+27|0]<<24);F[b+24>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);a=G[a+28|0]|G[a+29|0]<<8|(G[a+30|0]<<16|G[a+31|0]<<24);F[b+28>>2]=a<<24|a<<8&16711680|(a>>>8&65280|a>>>24);c=F[b+28>>2];a=8;while(1){d=a&7;a:{if(!d){d=F[(a-1>>>3<<2)+3328>>2];c=ue(c,8);c=d^(G[(c>>>8&255)+3072|0]<<8|G[(c&255)+3072|0]|G[(c>>>16&255)+3072|0]<<16|G[(c>>>24|0)+3072|0]<<24);break a}if((d|0)!=4){break a}c=G[(c&255)+3072|0]|G[(c>>>8&255)+3072|0]<<8|G[(c>>>16&255)+3072|0]<<16|G[(c>>>24|0)+3072|0]<<24}c=F[(a-8<<2)+b>>2]^c;F[(a<<2)+b>>2]=c;a=a+1|0;if((a|0)!=60){continue}break}}function Ha(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;d=F[b+44>>2];e=F[b+48>>2];f=F[b+52>>2];g=F[b+56>>2];h=F[b+60>>2];c=b- -64|0;i=F[c>>2];j=F[b+68>>2];k=F[b+72>>2];l=F[b+76>>2];m=F[b+4>>2];n=F[b+8>>2];o=F[b+12>>2];p=F[b+16>>2];q=F[b+20>>2];r=F[b+24>>2];s=F[b+28>>2];t=F[b+32>>2];u=F[b+36>>2];F[a>>2]=F[b>>2]+F[b+40>>2];F[a+36>>2]=l+u;F[a+32>>2]=k+t;F[a+28>>2]=j+s;F[a+24>>2]=i+r;F[a+20>>2]=h+q;F[a+16>>2]=g+p;F[a+12>>2]=f+o;F[a+8>>2]=e+n;F[a+4>>2]=d+m;d=F[b+44>>2];e=F[b+48>>2];f=F[b+52>>2];g=F[b+56>>2];h=F[b+60>>2];c=F[c>>2];i=F[b+68>>2];j=F[b+72>>2];k=F[b>>2];l=F[b+40>>2];m=F[b+4>>2];n=F[b+8>>2];o=F[b+12>>2];p=F[b+16>>2];q=F[b+20>>2];r=F[b+24>>2];s=F[b+28>>2];t=F[b+32>>2];F[a+76>>2]=F[b+76>>2]-F[b+36>>2];F[a+72>>2]=j-t;F[a+68>>2]=i-s;F[a- -64>>2]=c-r;F[a+60>>2]=h-q;F[a+56>>2]=g-p;F[a+52>>2]=f-o;F[a+48>>2]=e-n;F[a+44>>2]=d-m;F[a+40>>2]=l-k;d=F[b+88>>2];e=F[b+92>>2];f=F[b+96>>2];g=F[b+100>>2];h=F[b+104>>2];c=F[b+108>>2];i=F[b+80>>2];j=F[b+84>>2];k=F[b+116>>2];F[a+112>>2]=F[b+112>>2];F[a+116>>2]=k;F[a+104>>2]=h;F[a+108>>2]=c;F[a+96>>2]=f;F[a+100>>2]=g;F[a+88>>2]=d;F[a+92>>2]=e;F[a+80>>2]=i;F[a+84>>2]=j;ha(a+120|0,b+120|0,2032)}function cb(a,b){var c=0,d=0;a:{b:{c:{d:{d=F[a+128>>2];c=(b>>>24)-(d>>>24)&255;switch(c|0){case 1:break b;case 0:break d;default:break c}}c=256;if(b>>>0>=d>>>0){break a}}while(1){ka(a,32,37364,1,a);c=c-1|0;if(c>>>0>1){continue}break}}ka(a,32,37367,1,a+96|0);ka(a,32,37366,1,a- -64|0);ka(a,32,37365,1,a+32|0);ka(a,32,37364,1,a);d=b&-16777216;F[a+128>>2]=d}e:{f:{g:{h:{c=(b>>>16)-(d>>>16)&255;switch(c|0){case 1:break f;case 0:break h;default:break g}}c=256;if(b>>>0>=d>>>0){break e}}d=a+32|0;while(1){ka(d,32,37365,1,d);c=c-1|0;if(c>>>0>1){continue}break}}c=a+32|0;ka(c,32,37367,1,a+96|0);ka(c,32,37366,1,a- -64|0);ka(c,32,37365,1,c);d=b&-65536;F[a+128>>2]=d}i:{j:{k:{l:{c=(b>>>8)-(d>>>8)&255;switch(c|0){case 1:break j;case 0:break l;default:break k}}c=256;if(b>>>0>=d>>>0){break i}}d=a- -64|0;while(1){ka(d,32,37366,1,d);c=c-1|0;if(c>>>0>1){continue}break}}c=a- -64|0;ka(c,32,37367,1,a+96|0);ka(c,32,37366,1,c);d=b&-256;F[a+128>>2]=d}m:{n:{o:{p:{c=b-d&255;switch(c|0){case 1:break n;case 0:break p;default:break o}}c=256;if(b>>>0>=d>>>0){break m}}d=a+96|0;while(1){ka(d,32,37367,1,d);c=c-1|0;if(c>>>0>1){continue}break}}c=a+96|0;ka(c,32,37367,1,c);F[a+128>>2]=b}}function xc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0;g=_-16|0;_=g;a:{b:{e=a+164|0;h=F[a+160>>2];if((e|0)==(h|0)){break b}i=1;d=e;while(1){if(G[d+4|0]){d=d+72|0;if((h|0)!=(d|0)){continue}d=16;if(!i){break a}break b}f=f+55|0;i=0;d=d+72|0;if((h|0)!=(d|0)){continue}break}d=16;break a}d=17}c:{if(d+f>>>0>c>>>0){F[a+7516>>2]=2;a=-1;break c}f=123;D[b|0]=123;d=G[1495]|G[1496]<<8|(G[1497]<<16|G[1498]<<24);c=G[1491]|G[1492]<<8|(G[1493]<<16|G[1494]<<24);D[b+6|0]=c;D[b+7|0]=c>>>8;D[b+8|0]=c>>>16;D[b+9|0]=c>>>24;D[b+10|0]=d;D[b+11|0]=d>>>8;D[b+12|0]=d>>>16;D[b+13|0]=d>>>24;c=G[1490]|G[1491]<<8|(G[1492]<<16|G[1493]<<24);d=G[1486]|G[1487]<<8|(G[1488]<<16|G[1489]<<24);D[b+1|0]=d;D[b+2|0]=d>>>8;D[b+3|0]=d>>>16;D[b+4|0]=d>>>24;D[b+5|0]=c;D[b+6|0]=c>>>8;D[b+7|0]=c>>>16;D[b+8|0]=c>>>24;d=b+14|0;c=F[a+160>>2];d:{if((c|0)!=(e|0)){while(1){if(!G[e+4|0]){D[d+1|0]=34;D[d|0]=f;a=g+12|0;la(a,F[e>>2]);a=ma(a,4,d+2|0);D[a+2|0]=34;D[a|0]=34;D[a+1|0]=58;a=ma(e+5|0,32,a+3|0);D[a|0]=34;f=44;d=a+1|0}e=e+72|0;if((c|0)!=(e|0)){continue}break}if((f&255)==44){break d}}D[d|0]=f;d=d+1|0}D[d|0]=125;D[d+1|0]=125;a=(d-b|0)+2|0}_=g+16|0;return a|0}function Md(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=a+264|0;g=a+132|0;if(Da(301)>>>0>e>>>0){F[a+300>>2]=2;return-1}e=jb(g,jb(a,la(_a(d,301),2)));h=G[f+4|0]|G[f+5|0]<<8|(G[f+6|0]<<16|G[f+7|0]<<24);g=G[f|0]|G[f+1|0]<<8|(G[f+2|0]<<16|G[f+3|0]<<24);D[e|0]=g;D[e+1|0]=g>>>8;D[e+2|0]=g>>>16;D[e+3|0]=g>>>24;D[e+4|0]=h;D[e+5|0]=h>>>8;D[e+6|0]=h>>>16;D[e+7|0]=h>>>24;h=G[f+28|0]|G[f+29|0]<<8|(G[f+30|0]<<16|G[f+31|0]<<24);g=G[f+24|0]|G[f+25|0]<<8|(G[f+26|0]<<16|G[f+27|0]<<24);D[e+24|0]=g;D[e+25|0]=g>>>8;D[e+26|0]=g>>>16;D[e+27|0]=g>>>24;D[e+28|0]=h;D[e+29|0]=h>>>8;D[e+30|0]=h>>>16;D[e+31|0]=h>>>24;h=G[f+20|0]|G[f+21|0]<<8|(G[f+22|0]<<16|G[f+23|0]<<24);g=G[f+16|0]|G[f+17|0]<<8|(G[f+18|0]<<16|G[f+19|0]<<24);D[e+16|0]=g;D[e+17|0]=g>>>8;D[e+18|0]=g>>>16;D[e+19|0]=g>>>24;D[e+20|0]=h;D[e+21|0]=h>>>8;D[e+22|0]=h>>>16;D[e+23|0]=h>>>24;g=G[f+12|0]|G[f+13|0]<<8|(G[f+14|0]<<16|G[f+15|0]<<24);f=G[f+8|0]|G[f+9|0]<<8|(G[f+10|0]<<16|G[f+11|0]<<24);D[e+8|0]=f;D[e+9|0]=f>>>8;D[e+10|0]=f>>>16;D[e+11|0]=f>>>24;D[e+12|0]=g;D[e+13|0]=g>>>8;D[e+14|0]=g>>>16;D[e+15|0]=g>>>24;D[e+32|0]=F[a+296>>2]!=0;return Za(b,c,d,301)|0}function ja(a,b,c){var d=0,e=0,f=0;if(c>>>0>=512){Z(a|0,b|0,c|0);return a}e=a+c|0;a:{if(!((a^b)&3)){b:{if(!(a&3)){c=a;break b}if(!c){c=a;break b}c=a;while(1){D[c|0]=G[b|0];b=b+1|0;c=c+1|0;if(!(c&3)){break b}if(c>>>0>>0){continue}break}}d=e&-4;c:{if(d>>>0<64){break c}f=d+-64|0;if(f>>>0>>0){break c}while(1){F[c>>2]=F[b>>2];F[c+4>>2]=F[b+4>>2];F[c+8>>2]=F[b+8>>2];F[c+12>>2]=F[b+12>>2];F[c+16>>2]=F[b+16>>2];F[c+20>>2]=F[b+20>>2];F[c+24>>2]=F[b+24>>2];F[c+28>>2]=F[b+28>>2];F[c+32>>2]=F[b+32>>2];F[c+36>>2]=F[b+36>>2];F[c+40>>2]=F[b+40>>2];F[c+44>>2]=F[b+44>>2];F[c+48>>2]=F[b+48>>2];F[c+52>>2]=F[b+52>>2];F[c+56>>2]=F[b+56>>2];F[c+60>>2]=F[b+60>>2];b=b- -64|0;c=c- -64|0;if(f>>>0>=c>>>0){continue}break}}if(c>>>0>=d>>>0){break a}while(1){F[c>>2]=F[b>>2];b=b+4|0;c=c+4|0;if(d>>>0>c>>>0){continue}break}break a}if(e>>>0<4){c=a;break a}d=e-4|0;if(d>>>0>>0){c=a;break a}c=a;while(1){D[c|0]=G[b|0];D[c+1|0]=G[b+1|0];D[c+2|0]=G[b+2|0];D[c+3|0]=G[b+3|0];b=b+4|0;c=c+4|0;if(d>>>0>=c>>>0){continue}break}}if(c>>>0>>0){while(1){D[c|0]=G[b|0];b=b+1|0;c=c+1|0;if((e|0)!=(c|0)){continue}break}}return a}function td(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;j=_-16|0;_=j;g=F[9340];g=aa[F[F[g>>2]+4>>2]](g,c)|0;f=F[9340];f=aa[F[F[f>>2]>>2]](f)|0;k=xb(F[a+128>>2],g,f);f=k+2|0;g=(f>>>0)/3|0;a:{if(((f-L(g,3)|0)+(g<<2)|0)-2>>>0>e>>>0){F[a+228>>2]=2;e=-1;break a}e=F[9340];g=aa[F[F[e>>2]+4>>2]](e,c)|0;e=F[9340];l=aa[F[F[e>>2]>>2]](e)|0;e=F[a+128>>2];h=k+2|0;f=(h>>>0)/3|0;h=((((h-L(f,3)|0)+(f<<2)|0)-2|0)+d|0)-k|0;D[h+1|0]=8;D[h|0]=3;f=h+2|0;if(e>>>0>=128){while(1){D[f|0]=e|128;f=f+1|0;i=e>>>0>16383;e=e>>>7|0;if(i){continue}break}}D[f+1|0]=18;D[f|0]=e;f=f+2|0;b:{if(g>>>0<128){e=g;break b}e=g;while(1){D[f|0]=e|128;f=f+1|0;i=e>>>0>16383;e=e>>>7|0;if(i){continue}break}}D[f|0]=e;f=f+1|0;F[j+12>>2]=f;i=F[9340];m=g;g=((f+g|0)-h|0)+l|0;e=-1;if((aa[F[F[i>>2]+8>>2]](i,a,128,b,c,F[j+12>>2],m,h,g)|0)==-1){break a}c=F[a+128>>2]+1|0;F[a+128>>2]=c;b=0;c:{if(!(c&16777215)){break c}b=1;if(!(c&65535)){break c}b=c&255?3:2}c=b;e=(c<<5)+a|0;b=3;while(1){ka(e,32,b+37364|0,1,(b<<5)+a|0);f=b>>>0>c>>>0;b=b-1|0;if(f){continue}break}bb(a+132|0,h,g,g+h|0);e=Ca(h,k,d)}_=j+16|0;return e|0}function Ga(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;c=F[b>>2];e=c;g=F[b+36>>2];h=F[b+32>>2];i=F[b+28>>2];j=F[b+24>>2];k=F[b+20>>2];l=F[b+16>>2];f=F[b+12>>2];d=F[b+8>>2];m=(L(g,19)+16777216>>25)+c>>26;c=F[b+4>>2];b=e+L(g+(h+(i+(j+(k+(l+(f+(d+(m+c>>25)>>26)>>25)>>26)>>25)>>26)>>25)>>26)>>25,19)|0;D[a|0]=b;D[a+2|0]=b>>>16;D[a+1|0]=b>>>8;c=c+(b>>26)|0;D[a+5|0]=c>>>14;D[a+4|0]=c>>>6;d=d+(c>>25)|0;D[a+8|0]=d>>>13;D[a+7|0]=d>>>5;e=b>>>24&3;b=c&33554431;D[a+3|0]=e|b<<2;c=(d>>26)+f|0;D[a+11|0]=c>>>11;D[a+10|0]=c>>>3;d=d&67108863;D[a+6|0]=d<<3|b>>>22;b=l+(c>>25)|0;D[a+15|0]=b>>>18;D[a+14|0]=b>>>10;D[a+13|0]=b>>>2;f=c&33554431;D[a+9|0]=f<<5|d>>>21;c=(b>>26)+k|0;D[a+16|0]=c;D[a+12|0]=b<<6|f>>>19;D[a+18|0]=c>>>16;D[a+17|0]=c>>>8;b=(c>>25)+j|0;D[a+21|0]=b>>>15;D[a+20|0]=b>>>7;d=(b>>26)+i|0;D[a+24|0]=d>>>13;D[a+23|0]=d>>>5;e=c>>>24&1;c=b&67108863;D[a+19|0]=e|c<<1;b=(d>>25)+h|0;D[a+27|0]=b>>>12;D[a+26|0]=b>>>4;d=d&33554431;D[a+22|0]=d<<3|c>>>23;c=(b>>26)+g|0;D[a+30|0]=c>>>10;D[a+29|0]=c>>>2;b=b&67108863;D[a+25|0]=b<<4|d>>>21;c=c&33554431;D[a+31|0]=c>>>18;D[a+28|0]=c<<6|b>>>20}function ya(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;e=G[a+12|0];c=L(e,6);g=G[a|0];f=L(g,6);d=G[a+8|0];b=G[a+4|0];D[a+12|0]=G[c+3648|0]^(G[f+3649|0]^(d^b));h=L(d,6);D[a+8|0]=G[c+3649|0]^(G[h+3648|0]^(b^g));i=L(b,6);D[a|0]=G[i+3649|0]^(G[f+3648|0]^(d^e));d=G[a+5|0];j=L(d,6);b=G[a+1|0];k=L(b,6);c=G[a+13|0];f=G[a+9|0];D[a+1|0]=G[j+3649|0]^(G[k+3648|0]^(c^f));l=L(c,6);D[a+13|0]=G[l+3648|0]^(G[k+3649|0]^(d^f));D[a+4|0]=G[h+3649|0]^(e^(g^G[i+3648|0]));e=L(f,6);D[a+9|0]=G[l+3649|0]^(G[e+3648|0]^(b^d));D[a+5|0]=G[e+3649|0]^(c^(b^G[j+3648|0]));e=G[a+6|0];c=L(e,6);g=G[a+2|0];f=L(g,6);d=G[a+14|0];b=G[a+10|0];D[a+2|0]=G[c+3649|0]^(G[f+3648|0]^(d^b));h=L(d,6);D[a+14|0]=G[h+3648|0]^(G[f+3649|0]^(b^e));b=L(b,6);D[a+10|0]=G[h+3649|0]^(G[b+3648|0]^(e^g));D[a+6|0]=G[b+3649|0]^(d^(g^G[c+3648|0]));e=G[a+15|0];c=L(e,6);g=G[a+3|0];f=L(g,6);d=G[a+11|0];b=G[a+7|0];D[a+15|0]=G[c+3648|0]^(G[f+3649|0]^(d^b));h=G[c+3649|0];c=L(d,6);D[a+11|0]=h^(G[c+3648|0]^(b^g));b=L(b,6);D[a+3|0]=G[b+3649|0]^(G[f+3648|0]^(d^e));D[a+7|0]=G[c+3649|0]^(e^(g^G[b+3648|0]))}function ce(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;if(c>>>0<=31){F[a>>2]=2;return-1}c=G[a+64|0]|G[a+65|0]<<8|(G[a+66|0]<<16|G[a+67|0]<<24);d=G[a+60|0]|G[a+61|0]<<8|(G[a+62|0]<<16|G[a+63|0]<<24);D[b+24|0]=d;D[b+25|0]=d>>>8;D[b+26|0]=d>>>16;D[b+27|0]=d>>>24;D[b+28|0]=c;D[b+29|0]=c>>>8;D[b+30|0]=c>>>16;D[b+31|0]=c>>>24;c=G[a+56|0]|G[a+57|0]<<8|(G[a+58|0]<<16|G[a+59|0]<<24);d=G[a+52|0]|G[a+53|0]<<8|(G[a+54|0]<<16|G[a+55|0]<<24);D[b+16|0]=d;D[b+17|0]=d>>>8;D[b+18|0]=d>>>16;D[b+19|0]=d>>>24;D[b+20|0]=c;D[b+21|0]=c>>>8;D[b+22|0]=c>>>16;D[b+23|0]=c>>>24;c=G[a+48|0]|G[a+49|0]<<8|(G[a+50|0]<<16|G[a+51|0]<<24);d=G[a+44|0]|G[a+45|0]<<8|(G[a+46|0]<<16|G[a+47|0]<<24);D[b+8|0]=d;D[b+9|0]=d>>>8;D[b+10|0]=d>>>16;D[b+11|0]=d>>>24;D[b+12|0]=c;D[b+13|0]=c>>>8;D[b+14|0]=c>>>16;D[b+15|0]=c>>>24;c=G[a+40|0]|G[a+41|0]<<8|(G[a+42|0]<<16|G[a+43|0]<<24);a=G[a+36|0]|G[a+37|0]<<8|(G[a+38|0]<<16|G[a+39|0]<<24);D[b|0]=a;D[b+1|0]=a>>>8;D[b+2|0]=a>>>16;D[b+3|0]=a>>>24;D[b+4|0]=c;D[b+5|0]=c>>>8;D[b+6|0]=c>>>16;D[b+7|0]=c>>>24;return 32}function Oa(a,b,c){var d=0,e=0;a:{if(!a){break a}e=b;b=a+32|0;if(e>>>0>>0){break a}d=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);e=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);D[c|0]=e;D[c+1|0]=e>>>8;D[c+2|0]=e>>>16;D[c+3|0]=e>>>24;D[c+4|0]=d;D[c+5|0]=d>>>8;D[c+6|0]=d>>>16;D[c+7|0]=d>>>24;d=G[a+28|0]|G[a+29|0]<<8|(G[a+30|0]<<16|G[a+31|0]<<24);e=G[a+24|0]|G[a+25|0]<<8|(G[a+26|0]<<16|G[a+27|0]<<24);D[c+24|0]=e;D[c+25|0]=e>>>8;D[c+26|0]=e>>>16;D[c+27|0]=e>>>24;D[c+28|0]=d;D[c+29|0]=d>>>8;D[c+30|0]=d>>>16;D[c+31|0]=d>>>24;d=G[a+20|0]|G[a+21|0]<<8|(G[a+22|0]<<16|G[a+23|0]<<24);e=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);D[c+16|0]=e;D[c+17|0]=e>>>8;D[c+18|0]=e>>>16;D[c+19|0]=e>>>24;D[c+20|0]=d;D[c+21|0]=d>>>8;D[c+22|0]=d>>>16;D[c+23|0]=d>>>24;d=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);a=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);D[c+8|0]=a;D[c+9|0]=a>>>8;D[c+10|0]=a>>>16;D[c+11|0]=a>>>24;D[c+12|0]=d;D[c+13|0]=d>>>8;D[c+14|0]=d>>>16;D[c+15|0]=d>>>24;d=b}return d}function Fa(a,b){var c=0,d=0;c=G[a+4|0]|G[a+5|0]<<8|(G[a+6|0]<<16|G[a+7|0]<<24);d=G[a|0]|G[a+1|0]<<8|(G[a+2|0]<<16|G[a+3|0]<<24);D[b+32|0]=d;D[b+33|0]=d>>>8;D[b+34|0]=d>>>16;D[b+35|0]=d>>>24;D[b+36|0]=c;D[b+37|0]=c>>>8;D[b+38|0]=c>>>16;D[b+39|0]=c>>>24;c=G[a+28|0]|G[a+29|0]<<8|(G[a+30|0]<<16|G[a+31|0]<<24);d=G[a+24|0]|G[a+25|0]<<8|(G[a+26|0]<<16|G[a+27|0]<<24);D[b+56|0]=d;D[b+57|0]=d>>>8;D[b+58|0]=d>>>16;D[b+59|0]=d>>>24;D[b+60|0]=c;D[b+61|0]=c>>>8;D[b+62|0]=c>>>16;D[b+63|0]=c>>>24;c=G[a+20|0]|G[a+21|0]<<8|(G[a+22|0]<<16|G[a+23|0]<<24);d=G[a+16|0]|G[a+17|0]<<8|(G[a+18|0]<<16|G[a+19|0]<<24);D[b+48|0]=d;D[b+49|0]=d>>>8;D[b+50|0]=d>>>16;D[b+51|0]=d>>>24;D[b+52|0]=c;D[b+53|0]=c>>>8;D[b+54|0]=c>>>16;D[b+55|0]=c>>>24;c=G[a+12|0]|G[a+13|0]<<8|(G[a+14|0]<<16|G[a+15|0]<<24);a=G[a+8|0]|G[a+9|0]<<8|(G[a+10|0]<<16|G[a+11|0]<<24);D[b+40|0]=a;D[b+41|0]=a>>>8;D[b+42|0]=a>>>16;D[b+43|0]=a>>>24;D[b+44|0]=c;D[b+45|0]=c>>>8;D[b+46|0]=c>>>16;D[b+47|0]=c>>>24;Gb(b,b+32|0,1824)}function ic(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0;g=_-48|0;_=g;a:{if((c|0)<=0){break a}D[b|0]=0;if(c>>>0<23){break a}F[g+32>>2]=F[a+112>>2];d=Xa(b,c,1535,g+32|0);h=b+c|0;b:{if((d|0)>(c|0)){break b}if((d|0)<=0){break a}f=b+d|0;e=c-d|0;d=Xa(f,e,1462,0);h=b+c|0;if((d|0)>(e|0)){break b}if((d|0)<=0){break a}b=e-d|0;c=d+f|0;c:{e=a+152|0;if((e|0)!=F[a+148>>2]){d=0;while(1){F[g+16>>2]=F[(L(d,68)+a|0)+184>>2];f=Xa(c,b,1068,g+16|0);if((f|0)>(b|0)){break c}if((f|0)<=0){break a}b=b-f|0;c=c+f|0;d=d+1|0;if(d>>>0<(F[a+148>>2]-e|0)/68>>>0){continue}break}}d=Xa(c,b,1439,0);if((d|0)>(b|0)){break c}if((d|0)<=0){break a}f=a+496|0;if((f|0)==F[a+492>>2]){break a}c=c+d|0;b=b-d|0;d=0;while(1){F[g>>2]=F[(L(d,68)+a|0)+528>>2];e=Xa(c,b,1068,g);h=b+c|0;if((e|0)>(b|0)){break b}if((e|0)<=0){break a}b=b-e|0;c=c+e|0;d=d+1|0;if(d>>>0<(F[a+492>>2]-f|0)/68>>>0){continue}break}break a}h=b+c|0}a=h-4|0;D[a|0]=46;D[a+1|0]=46;D[a+2|0]=46;D[a+3|0]=0}_=g+48|0}function gb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;f=_-256|0;_=f;while(1){F[(d<<2)+f>>2]=G[(c|3)+b|0]|(G[(c|1)+b|0]<<16|G[b+c|0]<<24|G[(c|2)+b|0]<<8);c=c+4|0;d=d+1|0;if((d|0)!=16){continue}break}b=16;c=F[f>>2];while(1){e=c;c=(b<<2)+f|0;d=F[c-8>>2];d=e+(F[c-28>>2]+(ue(d,15)^ue(d,13)^d>>>10)|0)|0;e=c;c=F[c-60>>2];F[e>>2]=(ue(c,25)^ue(c,14)^c>>>3)+d;b=b+1|0;if((b|0)!=64){continue}break}n=F[a+80>>2];i=n;o=F[a+84>>2];b=o;p=F[a+108>>2];g=p;q=F[a+104>>2];c=q;r=F[a+100>>2];e=r;s=F[a+96>>2];j=s;t=F[a+92>>2];k=t;u=F[a+88>>2];d=u;while(1){l=d;d=b;b=m<<2;h=j;g=(F[b+2816>>2]+((((ue(h,26)^ue(h,21)^ue(h,7))+(h&e)|0)+g|0)+((h^-1)&c)|0)|0)+F[b+f>>2]|0;b=i;i=g+((ue(b,30)^ue(b,19)^ue(b,10))+((d^l)&b^d&l)|0)|0;j=g+k|0;g=c;c=e;e=h;k=l;m=m+1|0;if((m|0)!=64){continue}break}F[a+108>>2]=g+p;F[a+104>>2]=c+q;F[a+100>>2]=e+r;F[a+96>>2]=j+s;F[a+92>>2]=k+t;F[a+88>>2]=d+u;F[a+84>>2]=b+o;F[a+80>>2]=i+n;_=f+256|0}function Bc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;a:{if(c>>>0<116){F[a+7516>>2]=2;a=-1;break a}D[b|0]=123;c=G[1490]|G[1491]<<8|(G[1492]<<16|G[1493]<<24);d=G[1486]|G[1487]<<8|(G[1488]<<16|G[1489]<<24);D[b+1|0]=d;D[b+2|0]=d>>>8;D[b+3|0]=d>>>16;D[b+4|0]=d>>>24;D[b+5|0]=c;D[b+6|0]=c>>>8;D[b+7|0]=c>>>16;D[b+8|0]=c>>>24;c=G[1495]|G[1496]<<8|(G[1497]<<16|G[1498]<<24);d=G[1491]|G[1492]<<8|(G[1493]<<16|G[1494]<<24);D[b+6|0]=d;D[b+7|0]=d>>>8;D[b+8|0]=d>>>16;D[b+9|0]=d>>>24;D[b+10|0]=c;D[b+11|0]=c>>>8;D[b+12|0]=c>>>16;D[b+13|0]=c>>>24;D[b+14|0]=34;c=ma(a+96|0,32,b+15|0);D[c|0]=34;D[c+1|0]=44;D[c+12|0]=34;d=G[1504]|G[1505]<<8|(G[1506]<<16|G[1507]<<24);e=G[1500]|G[1501]<<8|(G[1502]<<16|G[1503]<<24);D[c+2|0]=e;D[c+3|0]=e>>>8;D[c+4|0]=e>>>16;D[c+5|0]=e>>>24;D[c+6|0]=d;D[c+7|0]=d>>>8;D[c+8|0]=d>>>16;D[c+9|0]=d>>>24;d=G[1508]|G[1509]<<8;D[c+10|0]=d;D[c+11|0]=d>>>8;a=ma(a,32,c+13|0);D[a|0]=34;D[a+1|0]=125;a=(a-b|0)+2|0}return a|0}function te(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;d=a;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{if(b){if(!c){break j}break i}a=(d>>>0)/(c>>>0)|0;$=0;break a}if(!d){break h}break g}if(!(c-1&c)){break f}g=(O(c)+33|0)-O(b)|0;e=0-g|0;break d}a=(b>>>0)/0|0;$=0;break a}a=32-O(b)|0;if(a>>>0<31){break e}break c}if((c|0)==1){break b}a=c?31-O(c-1^c)|0:32;c=a&31;if((a&63)>>>0>=32){a=0;b=b>>>c|0}else{a=b>>>c|0;b=((1<>>c}$=a;a=b;break a}g=a+1|0;e=63-a|0}a=g&63;f=a&31;if(a>>>0>=32){a=0;h=b>>>f|0}else{a=b>>>f|0;h=((1<>>f}f=a;a=e&63;e=a&31;if(a>>>0>=32){a=d<>>32-e|b<>>31;f=f<<1|h>>>31;i=l-(f+(a>>>0>e>>>0)|0)>>31;j=c&i;h=a-j|0;f=f-(a>>>0>>0)|0;b=b<<1|d>>>31;d=k|d<<1;k=i&1;g=g-1|0;if(g){continue}break}}$=b<<1|d>>>31;a=k|d<<1;break a}d=0;b=0}$=b;a=d}return a}function Xa(a,b,c,d){var e=0,f=0,g=0,h=0;g=_-16|0;_=g;F[g+12>>2]=d;e=_-160|0;_=e;f=-1;F[e+148>>2]=b?b-1|0:0;a=b?a:e+158|0;F[e+144>>2]=a;e=qa(e,0,144);F[e+76>>2]=-1;F[e+36>>2]=8;F[e+80>>2]=-1;F[e+44>>2]=e+159;F[e+84>>2]=e+144;a:{if((b|0)<0){F[9343]=61;break a}D[a|0]=0;f=0;b=_-208|0;_=b;F[b+204>>2]=d;a=b+160|0;qa(a,0,40);F[b+200>>2]=F[b+204>>2];b:{if((Db(0,c,b+200|0,b+80|0,a)|0)<0){c=-1;break b}h=F[e+76>>2]>=0;d=F[e>>2];if(F[e+72>>2]<=0){F[e>>2]=d&-33}c:{d:{e:{if(!F[e+48>>2]){F[e+48>>2]=80;F[e+28>>2]=0;F[e+16>>2]=0;F[e+20>>2]=0;f=F[e+44>>2];F[e+44>>2]=b;break e}if(F[e+16>>2]){break d}}a=-1;if(Fb(e)){break c}}a=Db(e,c,b+200|0,b+80|0,b+160|0)}c=a;if(f){aa[F[e+36>>2]](e,0,0)|0;F[e+48>>2]=0;F[e+44>>2]=f;F[e+28>>2]=0;a=F[e+20>>2];F[e+16>>2]=0;F[e+20>>2]=0;c=a?c:-1}a=F[e>>2];F[e>>2]=a|d&32;c=a&32?-1:c;if(!h){break b}}_=b+208|0;f=c}_=e+160|0;_=g+16|0;return f}function oc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=_-16|0;_=e;d=17;a:{if((G[a+7372|0]|!G[a+7364|0]?d:71)>>>0>c>>>0){F[a+7516>>2]=2;a=-1;break a}D[b|0]=123;c=G[1490]|G[1491]<<8|(G[1492]<<16|G[1493]<<24);d=G[1486]|G[1487]<<8|(G[1488]<<16|G[1489]<<24);D[b+1|0]=d;D[b+2|0]=d>>>8;D[b+3|0]=d>>>16;D[b+4|0]=d>>>24;D[b+5|0]=c;D[b+6|0]=c>>>8;D[b+7|0]=c>>>16;D[b+8|0]=c>>>24;c=G[1495]|G[1496]<<8|(G[1497]<<16|G[1498]<<24);d=G[1491]|G[1492]<<8|(G[1493]<<16|G[1494]<<24);D[b+6|0]=d;D[b+7|0]=d>>>8;D[b+8|0]=d>>>16;D[b+9|0]=d>>>24;D[b+10|0]=c;D[b+11|0]=c>>>8;D[b+12|0]=c>>>16;D[b+13|0]=c>>>24;D[b+14|0]=123;d=b+15|0;if(!(G[a+7372|0]|!G[a+7364|0])){D[b+15|0]=34;c=e+12|0;la(c,F[a+7368>>2]);c=ma(c,4,b+16|0);D[c+2|0]=34;D[c|0]=34;D[c+1|0]=58;a=ma(a+7373|0,32,c+3|0);D[a|0]=34;d=a+1|0}D[d|0]=125;D[d+1|0]=125;a=(d-b|0)+2|0}_=e+16|0;return a|0}function Jd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;g=_-160|0;_=g;h=-1;c=Pa(b,c,b);a:{if((c|0)==-1){F[a+300>>2]=7;break a}h=F[9340];wb(b,c,aa[F[F[h>>2]>>2]](h)|0,g+136|0);if(G[g+136|0]!=3){F[a+300>>2]=3;h=-1;break a}if(!(F[g+148>>2]?F[g+144>>2]:0)){F[a+300>>2]=4;h=-1;break a}if(f){F[f>>2]=F[g+140>>2]}f=c+-64|0;if(!hb(a+264|0,b,f,b+f|0)){F[a+300>>2]=14;h=-1;break a}c=F[9340];if(aa[F[F[c>>2]+12>>2]](c,F[g+152>>2])>>>0>e>>>0){F[a+300>>2]=2;h=-1;break a}b:{c=F[g+140>>2];c:{if((c-F[a+260>>2]|0)>=0){h=a+132|0;cb(h,c);ja(g,h,132);break c}if((c-F[a+128>>2]|0)<0){break b}cb(ja(g,a,132),c)}c=F[9340];b=aa[F[F[c>>2]+16>>2]](c,g,128,b,f,F[g+148>>2],F[g+152>>2],d,e)|0;ia(g,132);h=-1;if((b|0)==-1){F[a+300>>2]=5;break a}F[a+296>>2]=1;h=b;break a}F[a+300>>2]=12;h=-1}_=g+160|0;return h|0}function qc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=_-16|0;_=e;a:{if((G[a+7364|0]?71:17)>>>0>c>>>0){F[a+7516>>2]=2;a=-1;break a}D[b|0]=123;c=G[1490]|G[1491]<<8|(G[1492]<<16|G[1493]<<24);d=G[1486]|G[1487]<<8|(G[1488]<<16|G[1489]<<24);D[b+1|0]=d;D[b+2|0]=d>>>8;D[b+3|0]=d>>>16;D[b+4|0]=d>>>24;D[b+5|0]=c;D[b+6|0]=c>>>8;D[b+7|0]=c>>>16;D[b+8|0]=c>>>24;c=G[1495]|G[1496]<<8|(G[1497]<<16|G[1498]<<24);d=G[1491]|G[1492]<<8|(G[1493]<<16|G[1494]<<24);D[b+6|0]=d;D[b+7|0]=d>>>8;D[b+8|0]=d>>>16;D[b+9|0]=d>>>24;D[b+10|0]=c;D[b+11|0]=c>>>8;D[b+12|0]=c>>>16;D[b+13|0]=c>>>24;D[b+14|0]=123;if(G[a+7364|0]){D[b+15|0]=34;c=e+12|0;la(c,F[a+7368>>2]);c=ma(c,4,b+16|0);D[c+2|0]=34;D[c|0]=34;D[c+1|0]=58;a=ma(a+7373|0,32,c+3|0);D[a|0]=34;a=a+1|0}else{a=b+15|0}D[a|0]=125;D[a+1|0]=125;a=(a-b|0)+2|0}_=e+16|0;return a|0}function Bb(a,b,c){a:{switch(b-9|0){case 0:b=F[c>>2];F[c>>2]=b+4;F[a>>2]=F[b>>2];return;case 6:b=F[c>>2];F[c>>2]=b+4;b=E[b>>1];F[a>>2]=b;F[a+4>>2]=b>>31;return;case 7:b=F[c>>2];F[c>>2]=b+4;F[a>>2]=H[b>>1];F[a+4>>2]=0;return;case 8:b=F[c>>2];F[c>>2]=b+4;b=D[b|0];F[a>>2]=b;F[a+4>>2]=b>>31;return;case 9:b=F[c>>2];F[c>>2]=b+4;F[a>>2]=G[b|0];F[a+4>>2]=0;return;case 16:b=F[c>>2]+7&-8;F[c>>2]=b+8;K[a>>3]=K[b>>3];return;case 17:aa[7](a,c);default:return;case 1:case 4:case 14:b=F[c>>2];F[c>>2]=b+4;b=F[b>>2];F[a>>2]=b;F[a+4>>2]=b>>31;return;case 2:case 5:case 11:case 15:b=F[c>>2];F[c>>2]=b+4;F[a>>2]=F[b>>2];F[a+4>>2]=0;return;case 3:case 10:case 12:case 13:break a}}b=F[c>>2]+7&-8;F[c>>2]=b+8;c=F[b+4>>2];F[a>>2]=F[b>>2];F[a+4>>2]=c}function qa(a,b,c){var d=0,e=0,f=0;a:{if(!c){break a}D[a|0]=b;e=a+c|0;D[e-1|0]=b;if(c>>>0<3){break a}D[a+2|0]=b;D[a+1|0]=b;D[e-3|0]=b;D[e-2|0]=b;if(c>>>0<7){break a}D[a+3|0]=b;D[e-4|0]=b;if(c>>>0<9){break a}e=0-a&3;f=e+a|0;d=L(b&255,16843009);F[f>>2]=d;b=c-e&-4;c=b+f|0;F[c-4>>2]=d;if(b>>>0<9){break a}F[f+8>>2]=d;F[f+4>>2]=d;F[c-8>>2]=d;F[c-12>>2]=d;if(b>>>0<25){break a}F[f+24>>2]=d;F[f+20>>2]=d;F[f+16>>2]=d;F[f+12>>2]=d;F[c-16>>2]=d;F[c-20>>2]=d;F[c-24>>2]=d;F[c-28>>2]=d;c=b;b=f&4|24;c=c-b|0;if(c>>>0<32){break a}d=se(d,0,1,1);e=$;b=b+f|0;while(1){F[b+24>>2]=d;F[b+28>>2]=e;F[b+16>>2]=d;F[b+20>>2]=e;F[b+8>>2]=d;F[b+12>>2]=e;F[b>>2]=d;F[b+4>>2]=e;b=b+32|0;c=c-32|0;if(c>>>0>31){continue}break}}return a}function Tb(a,b,c,d,e){var f=0,g=0,h=0,i=0;f=_-80|0;_=f;g=-1;h=F[b>>2];i=F[c+4>>2];if(!(h>>>0>i>>>0|i-h>>>0>2e3)){F[f+72>>2]=F[b+32>>2];h=F[b+28>>2];g=f- -64|0;F[g>>2]=F[b+24>>2];F[g+4>>2]=h;g=F[b+20>>2];F[f+56>>2]=F[b+16>>2];F[f+60>>2]=g;g=F[b+12>>2];F[f+48>>2]=F[b+8>>2];F[f+52>>2]=g;g=F[b+4>>2];b=F[b>>2];F[f+40>>2]=b;F[f+44>>2]=g;if(b>>>0>>0){b=f+40|4;while(1){ka(b,32,1869,1,b);g=F[f+40>>2]+1|0;F[f+40>>2]=g;if(g>>>0>2]){continue}break}}b=f+40|0;g=f|4;ka(b|4,32,1868,1,g);F[f>>2]=F[f+40>>2];a=F[a+4>>2];g=aa[F[F[a>>2]+16>>2]](a,g,32,F[c+8>>2],F[c+12>>2],F[c+24>>2],F[c+28>>2],d,e)|0;ia(b,36)}_=f+80|0;return g}function me(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;var l=0,m=0,n=0;l=_-112|0;_=l;m=(aa[F[441]](F[1416],c)|0)+2|0;n=(m>>>0)/3|0;a:{b:{c:{if(((m-L(n,3)|0)+(n<<2)|0)-2>>>0>e>>>0){break c}if(aa[F[440]](F[1416])>>>0>g>>>0){break c}if(i>>>0>=43){break b}}F[a>>2]=2;c=-1;break a}if(k>>>0<=31){F[a>>2]=1;c=-1;break a}g=l+48|0;Fa(j,g);ma(g,32,h);h=g;g=l+16|0;za(h,a+4|0,g);a=aa[F[441]](F[1416],c)|0;e=(d+e|0)-a|0;c=aa[F[442]](F[1416],g,32,b,c,e,a,l+8|0,8)|0;if((c|0)==-1){break a}ma(l+8|0,8,f);ma(e,a,d)}_=l+112|0;return c|0}function Hc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0;g=Ib(a);if(Da(g)>>>0>e>>>0){F[a+7516>>2]=2;return-1}e=a+164|0;f=la(Na(sb(la(_a(d,g),4),a),a+96|0),(F[a+160>>2]-e|0)/72|0);h=F[a+160>>2];if((h|0)!=(e|0)){while(1){f=la(f,F[e>>2]);D[f|0]=G[e+4|0];f=Na(f+1|0,e+5|0);e=e+72|0;if((h|0)!=(e|0)){continue}break}}D[f|0]=G[a+7364|0];e=f+1|0;a:{if(!G[a+7364|0]){break a}e=la(e,F[a+7368>>2]);D[e|0]=G[a+7372|0];e=Na(e+1|0,a+7373|0);if(G[a+7364|0]<2){break a}e=la(e,F[a+7440>>2]);D[e|0]=G[a+7444|0];e=Na(e+1|0,a+7445|0)}la(e,F[a+7512>>2]);return Za(b,c,d,g)|0}function sa(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;d=-1;a:{if((b&3)==1){break a}d=b+2|0;g=((d&3)+L(d>>>2|0,3)|0)-2|0;d=-1;if((g|0)==-1){break a}e=b&-4;b:{if(!e){e=a;break b}e=a+e|0;d=a;while(1){i=G[d|0];f=G[d+1|0];h=G[(G[d+2|0]&127)+1632|0];D[c+2|0]=G[(G[d+3|0]&127)+1632|0]|h<<6;f=G[(f&127)+1632|0]<<6;D[c+1|0]=(f|h)>>>2;D[c|0]=(f|G[(i&127)+1632|0]<<12)>>>10;c=c+3|0;d=d+4|0;if((d|0)!=(e|0)){continue}break}}b=(a+b|0)-e|0;if(b){a=G[(G[e+1|0]&127)+1632|0]|G[(G[e|0]&127)+1632|0]<<6;if((b|0)==3){D[c+1|0]=(G[(G[e+2|0]&127)+1632|0]|a<<6)>>>2}D[c|0]=a>>>4}d=g}return d}function ma(a,b,c){var d=0,e=0,f=0,g=0,h=0;d=b-((b>>>0)%3|0)|0;a:{if(!d){e=a;break a}e=a+d|0;d=a;while(1){f=G[d+1|0];g=G[d|0];h=G[d+2|0];D[c+3|0]=G[(h&63)+1568|0];D[c|0]=G[(g>>>2|0)+1568|0];f=f<<8;D[c+2|0]=G[((f|h)>>>6&63)+1568|0];D[c+1|0]=G[((f|g<<16)>>>12&63)+1568|0];c=c+4|0;d=d+3|0;if((e|0)!=(d|0)){continue}break}}d=(a+b|0)-e|0;if(d){a=2;b=G[e|0];b:{if((d|0)==2){a=G[e+1|0]<<2;D[c+2|0]=G[(a&60)+1568|0];d=(a|b<<10)>>>6|0;a=3;break b}d=b<<4}D[c|0]=G[(d>>>6|0)+1568|0];D[c+1|0]=G[(d&63)+1568|0];c=a+c|0}return c}function Ld(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=_-16|0;_=f;b=Ya(b,c,d,e,a+300|0);a:{if((b|0)!=-1){b=b+d|0;c=eb(d,b,f+12|0);b:{if(!c){d=10;break b}d=9;if(F[f+12>>2]-3>>>0<4294967294){break b}c=ib(a,c,b);if(!c){d=10;break b}c=ib(a+132|0,c,b);if(!c){d=10;break b}c=Oa(c,b,a+264|0);if(!c){d=10;break b}g=a+296|0;c:{if(F[f+12>>2]==1){F[g>>2]=1;break c}d=10;if(!c|(b|0)==(c|0)){c=h}else{D[g|0]=G[c|0]!=0;c=c+1|0}if(!c){break b}}d=17;if((b|0)==(c|0)){break a}}F[a+300>>2]=d}e=-1}_=f+16|0;return e|0}function Ca(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;f=a;e=c;d=b-((b>>>0)%3|0)|0;if(d){f=a+d|0;d=a;while(1){g=G[d+1|0];h=G[d|0];i=G[d+2|0];D[e+3|0]=G[(i&63)+1568|0];D[e|0]=G[(h>>>2|0)+1568|0];g=g<<8;D[e+2|0]=G[((g|i)>>>6&63)+1568|0];D[e+1|0]=G[((g|h<<16)>>>12&63)+1568|0];e=e+4|0;d=d+3|0;if((f|0)!=(d|0)){continue}break}}d=(a+b|0)-f|0;if(d){a=2;b=G[f|0];a:{if((d|0)==2){a=G[f+1|0]<<2;D[e+2|0]=G[(a&60)+1568|0];d=(a|b<<10)>>>6|0;a=3;break a}d=b<<4}D[e|0]=G[(d>>>6|0)+1568|0];D[e+1|0]=G[(d&63)+1568|0];e=a+e|0}return e-c|0}function fc(a,b){a=a|0;b=b|0;var c=0,d=0;c=b+3285|0;b=a+164|0;a:{b:{if((b|0)!=F[a+160>>2]){while(1){if(Ka(b+5|0,c,32)){d=F[b>>2];c=F[a+160>>2]-72|0;F[a+160>>2]=c;if((b|0)==(c|0)){break b}while(1){c=b;b=b+72|0;ja(c,b,72);if(F[a+160>>2]!=(b|0)){continue}break}break b}b=b+72|0;if((b|0)!=F[a+160>>2]){continue}break}}d=-1;if(!G[a+7364|0]){break b}if(Ka(a+7373|0,c,32)){b=F[a+7368>>2];break a}if(G[a+7364|0]<2){break b}if(!Ka(a+7445|0,c,32)){break b}d=F[a+7440>>2]}b=d}if((b|0)==-1){F[a+7516>>2]=6}return b|0}function tc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;g=c;e=b;a:{b:{if(b<<5>>>0<=d>>>0){if(e){break b}e=0;break a}F[a+7516>>2]=1;e=-1;break a}j=a+169|0;k=a+7364|0;h=a+164|0;while(1){b=k;f=F[a+160>>2];if((b|0)!=(f|0)){b=f+72|0;F[a+160>>2]=b}b=b-72|0;if((h|0)!=(b|0)){while(1){f=b;b=b-72|0;ja(f,b,72);if((b|0)!=(h|0)){continue}break}}D[a+168|0]=0;b=F[a+7512>>2]+1|0;F[h>>2]=b;F[a+7512>>2]=b;Fa(g,j);g=g+32|0;i=i+1|0;if((i|0)!=(e|0)){continue}break}}ia(c,d);return e|0}function Ab(a,b){if(!a){return 0}a:{b:{if(a){if(b>>>0<=127){break b}c:{if(!F[F[9380]>>2]){if((b&-128)==57216){break b}break c}if(b>>>0<=2047){D[a+1|0]=b&63|128;D[a|0]=b>>>6|192;a=2;break a}if(!((b&-8192)!=57344&b>>>0>=55296)){D[a+2|0]=b&63|128;D[a|0]=b>>>12|224;D[a+1|0]=b>>>6&63|128;a=3;break a}if(b-65536>>>0<=1048575){D[a+3|0]=b&63|128;D[a|0]=b>>>18|240;D[a+2|0]=b>>>6&63|128;D[a+1|0]=b>>>12&63|128;a=4;break a}}F[9343]=25;a=-1}else{a=1}break a}D[a|0]=b;a=1}return a}function bc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=oa(d);if((e|0)==-1){F[a+3216>>2]=7;return-1}sa(c,d,c);d=_-48|0;_=d;a:{b:{if((b|0)!=1){ab(d+8|0,c,e);c=F[d+36>>2];if(!c){F[a+3216>>2]=4;break b}e=F[d+40>>2]}b=_-32|0;_=b;f=c;c=F[a+4>>2];fb(b,f,e,aa[F[F[c>>2]>>2]](c)|0);c:{if(!F[b+24>>2]){F[a+8>>2]=4;c=-1;break c}c=F[a+4>>2];c=aa[F[F[c>>2]+12>>2]](c,F[b+28>>2])|0}_=b+32|0;if((c|0)!=-1){break a}F[a+3216>>2]=F[a+8>>2];F[a+8>>2]=0}c=-1}_=d+48|0;return c|0}function Ka(a,b,c){var d=0,e=0,f=0,g=0;d=_-16|0;D[d+15|0]=0;a:{if(!c){break a}g=c-1|0;e=c&3;if(e){while(1){D[d+15|0]=G[d+15|0]|G[b|0]^G[a|0];b=b+1|0;a=a+1|0;c=c-1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}}if(g>>>0<3){break a}while(1){D[d+15|0]=G[d+15|0]|G[a|0]^G[b|0];D[d+15|0]=G[d+15|0]|G[a+1|0]^G[b+1|0];D[d+15|0]=G[d+15|0]|G[a+2|0]^G[b+2|0];D[d+15|0]=G[d+15|0]|G[a+3|0]^G[b+3|0];b=b+4|0;a=a+4|0;c=c-4|0;if(c){continue}break}}return!G[d+15|0]}function Qb(a,b,c,d){var e=0,f=0,g=0;e=_-48|0;_=e;ab(e+8|0,c,d);f=F[e+12>>2];c=(f|b)!=0;a:{if(f){if(!c){break a}c=F[e+16>>2]==32}if(!c|!F[e+36>>2]){break a}d=F[e+20>>2];if(!d|F[e+24>>2]!=32){break a}c=F[e+28>>2];if(!c|F[e+32>>2]!=32){break a}b:{c:{if(f){f=Ma(f,a+3221|0);if(b){if(f){break a}break c}if(!f){break b}break a}if(!b){break b}}if(Ma(b,a+3221|0)){break a}}if(Ma(d,a+3253|0)){break a}g=!Ma(c,a+3285|0)}_=e+48|0;return g}function de(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0;j=_-80|0;_=j;k=F[443];a:{if(aa[k|0](F[1416],oa(g))>>>0>i>>>0){F[a>>2]=2;g=-1;break a}k=oa(g);if(!(!((k|0)==-1|(c|0)!=43)&(e|0)==11)){F[a>>2]=7;g=-1;break a}c=b;b=j+48|0;sa(c,43,b);c=b;b=j+16|0;za(a+4|0,c,b);c=j+8|0;sa(d,11,c);sa(f,g,f);g=aa[F[444]](F[1416],b,32,c,8,f,k,h,i)|0;if((g|0)!=-1){break a}F[a>>2]=5}_=j+80|0;return g|0}function fe(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=_-16|0;_=h;a:{if(!(!f|g>>>0>=43)){F[a>>2]=2;g=-1;break a}g=-1;b=Ya(b,c,d,e,a);if((b|0)==-1){break a}b:{b=b+d|0;c=va(d,b,h+12|0);c:{if(!c){break c}if(F[h+12>>2]!=1){F[a>>2]=9;break c}c=Ja(c,b,a+4|0);if(c){break b}}if(F[a>>2]){break a}F[a>>2]=10;break a}if((b|0)!=(c|0)){F[a>>2]=17;break a}if(f){ma(a+4|0,32,f)}g=e}_=h+16|0;return g|0}function Ob(a){var b=0,c=0,d=0,e=0,f=0;b=a+48|0;d=F[a+44>>2];if((b|0)==(d|0)){d=36}else{c=4;while(1){c=c+100|0;b=b+100|0;if((d|0)!=(b|0)){continue}break}d=c+32|0}e=4;c=4;b=a+152|0;f=F[a+148>>2];if((b|0)!=(f|0)){while(1){c=c+68|0;b=b+68|0;if((f|0)!=(b|0)){continue}break}}b=a+496|0;a=F[a+492>>2];if((b|0)!=(a|0)){while(1){e=e+68|0;b=b+68|0;if((a|0)!=(b|0)){continue}break}}return((c+d|0)+e|0)+101|0}function ve(a,b,c){var d=0,e=0,f=0,g=0;g=c&63;f=g;e=f&31;if(f>>>0>=32){f=-1>>>e|0}else{d=-1>>>e|0;f=d|(1<>>0>=32){d=f<>>32-e|d<>>0>=32){d=-1<>>32-d}a=c&a;b=b&d;d=e&31;if(e>>>0>=32){c=0;a=b>>>d|0}else{c=b>>>d|0;a=((1<>>d}a=a|g;$=c|f;return a} +function na(a,b,c){var d=0,e=0,f=0;if(!(G[a|0]&32)){a:{d=b;b=a;a=F[b+16>>2];b:{if(!a){if(Fb(b)){break b}a=F[b+16>>2]}f=F[b+20>>2];if(a-f>>>0>>0){aa[F[b+36>>2]](b,d,c)|0;break a}c:{if(F[b+80>>2]<0){break c}a=c;while(1){e=a;if(!a){break c}a=e-1|0;if(G[d+a|0]!=10){continue}break}if(aa[F[b+36>>2]](b,d,e)>>>0>>0){break b}d=d+e|0;c=c-e|0;f=F[b+20>>2]}ja(f,d,c);F[b+20>>2]=F[b+20>>2]+c}}}}function cd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;e=F[a+84>>2];f=F[e+4>>2];g=F[a+28>>2];d=F[a+20>>2]-g|0;d=d>>>0>f>>>0?f:d;if(d){ja(F[e>>2],g,d);F[e>>2]=d+F[e>>2];f=F[e+4>>2]-d|0;F[e+4>>2]=f}d=F[e>>2];f=c>>>0>f>>>0?f:c;if(f){ja(d,b,f);d=f+F[e>>2]|0;F[e>>2]=d;F[e+4>>2]=F[e+4>>2]-f}D[d|0]=0;b=F[a+44>>2];F[a+28>>2]=b;F[a+20>>2]=b;return c|0}function xd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0;f=_-16|0;_=f;b=Ya(b,c,d,e,a+228|0);a:{if((b|0)!=-1){b=b+d|0;c=eb(d,b,f+12|0);b:{if(!c){d=10;break b}d=9;if(F[f+12>>2]!=1){break b}c=ib(a,c,b);if(!c){d=10;break b}d=10;c=rb(c,b,a+132|0);if(!c){break b}d=17;if((b|0)==(c|0)){break a}}F[a+228>>2]=d}e=-1}_=f+16|0;return e|0}function Kd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;d=_-32|0;_=d;e=-1;c=Pa(b,c,b);a:{if((c|0)==-1){F[a+300>>2]=7;break a}f=b;b=F[9340];wb(f,c,aa[F[F[b>>2]>>2]](b)|0,d+8|0);if(G[d+8|0]!=3){F[a+300>>2]=3;break a}if(!F[d+20>>2]){F[a+300>>2]=4;break a}a=F[9340];e=aa[F[F[a>>2]+12>>2]](a,F[d+24>>2])|0}_=d+32|0;return e|0}function ia(a,b){var c=0,d=0,e=0;a:{if(!b){break a}c=a;d=b&7;if(d){while(1){D[c|0]=0;c=c+1|0;e=e+1|0;if((d|0)!=(e|0)){continue}break}}if(b-1>>>0<7){break a}a=a+b|0;while(1){D[c|0]=0;D[c+1|0]=0;D[c+2|0]=0;D[c+3|0]=0;D[c+4|0]=0;D[c+5|0]=0;D[c+6|0]=0;D[c+7|0]=0;c=c+8|0;if((a|0)!=(c|0)){continue}break}}}function Kb(a,b,c){var d=0;d=_-112|0;_=d;F[d+80>>2]=1779033703;F[d+84>>2]=-1150833019;F[d+72>>2]=0;F[d+76>>2]=0;F[d+64>>2]=0;F[d+104>>2]=528734635;F[d+108>>2]=1541459225;F[d+96>>2]=1359893119;F[d+100>>2]=-1694144372;F[d+88>>2]=1013904242;F[d+92>>2]=-1521486534;ra(d,a,b);Ba(d,c);ia(d,112);_=d+112|0}function Ma(a,b){var c=0,d=0,e=0;c=32;a:{b:{if((a|b)&3){break b}while(1){if(F[a>>2]!=F[b>>2]){break b}b=b+4|0;a=a+4|0;c=c-4|0;if(c>>>0>3){continue}break}if(!c){break a}}while(1){d=G[a|0];e=G[b|0];if((d|0)==(e|0)){b=b+1|0;a=a+1|0;c=c-1|0;if(c){continue}break a}break}return d-e|0}return 0}function _b(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=_-32|0;_=h;a:{if((oa(c)|0)!=32){F[a>>2]=7;c=-1;break a}sa(b,c,h);c=-1;b=oa(g);if((b|0)==-1){F[a>>2]=7;break a}sa(f,g,f);b:{if(b>>>0>=64){c=0;if(hb(h,d,e,f)){break b}}F[a>>2]=5;c=-1}}_=h+32|0;return c|0}function ra(a,b,c){var d=0,e=0,f=0;if(c){d=F[a+64>>2];while(1){D[a+d|0]=G[b+e|0];d=F[a+64>>2]+1|0;F[a+64>>2]=d;if((d|0)==64){gb(a,a);F[a+64>>2]=0;d=F[a+76>>2];f=F[a+72>>2]+512|0;d=f>>>0<512?d+1|0:d;F[a+72>>2]=f;F[a+76>>2]=d;d=0}e=e+1|0;if((e|0)!=(c|0)){continue}break}}}function hd(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=_+-64|0;_=h;a:{if(g>>>0<43){F[a>>2]=2;a=-1;break a}if(!F[a+100>>2]){F[a>>2]=16;a=-1;break a}g=a+68|0;a=h+32|0;Aa(g,32,0,0,d,e,a,32);ka(a,32,b,c,h);Ca(h,32,f);a=0}_=h- -64|0;return a|0}function Ra(a,b,c){var d=0,e=0,f=0;a:{if(!b){d=a;break a}while(1){d=te(a,b,10);f=$;e=se(d,f,10,0);c=c-1|0;D[c|0]=a-e|48;e=b>>>0>9;a=d;b=f;if(e){continue}break}}if(d){while(1){c=c-1|0;a=(d>>>0)/10|0;D[c|0]=d-L(a,10)|48;b=d>>>0>9;d=a;if(b){continue}break}}return c}function sc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;a:{if(c>>>0<=31){F[a+7516>>2]=1;a=-1;break a}d=G[a+7364|0];if(d>>>0<=1){D[a+7364|0]=d+1}ja(a+7440|0,a+7368|0,72);D[a+7372|0]=0;d=F[a+7512>>2]+1|0;F[a+7368>>2]=d;F[a+7512>>2]=d;Fa(b,a+7373|0);a=1}ia(b,c);return a|0}function fd(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=_-256|0;_=h;a:{if(g>>>0<43){F[a>>2]=2;a=-1;break a}if(!F[a+100>>2]){F[a>>2]=16;a=-1;break a}Aa(a+68|0,32,0,0,d,e,h,256);ka(h,256,b,c,f);Ca(f,32,f);a=0}_=h+256|0;return a|0}function gd(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0;h=_-32|0;_=h;a:{if(g>>>0<43){F[a>>2]=2;a=-1;break a}if(!F[a+100>>2]){F[a>>2]=16;a=-1;break a}Aa(a+68|0,32,0,0,d,e,h,32);ka(h,32,b,c,f);Ca(f,32,f);a=0}_=h+32|0;return a|0}function Eb(a,b){var c=0,d=0,e=0;A(+a);d=v(1)|0;e=v(0)|0;c=d>>>20&2047;if((c|0)!=2047){if(!c){if(a==0){c=0}else{a=Eb(a*0x10000000000000000,b);c=F[b>>2]+-64|0}F[b>>2]=c;return a}F[b>>2]=c-1022;x(0,e|0);x(1,d&-2146435073|1071644672);a=+z()}return a}function Ya(a,b,c,d,e){var f=0,g=0;f=-1;g=oa(d);a:{b:{if((g|0)==-1){c=7;if(e){break b}break a}Pa(c,d,c);d=a;a=g-(aa[F[440]](2804)|0)|0;f=aa[F[444]](2804,d,b,c,g,c,a,c,a)|0;if(!e){break a}c=8;if((f|0)!=-1){break a}}F[e>>2]=c;f=-1}return f}function kc(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0;g=_-32|0;_=g;a:{if((oa(d)|0)!=32){F[a+3216>>2]=7;d=-1;break a}sa(c,d,g);d=-1;c=oa(f);if((c|0)==-1){F[a+3216>>2]=7;break a}sa(e,f,e);d=Rb(a,b,g,e,c)}_=g+32|0;return d|0}function zb(a,b,c){var d=0,e=0,f=0;e=1;if(a>>>0>=128){while(1){e=e+1|0;d=a>>>0>16383;a=a>>>7|0;if(d){continue}break}}d=1;if(b>>>0>=128){a=b;while(1){d=d+1|0;f=a>>>0>16383;a=a>>>7|0;if(f){continue}break}}return(((b+c|0)+e|0)+d|0)+37|0}function xb(a,b,c){var d=0,e=0,f=0;d=1;e=1;if(a>>>0>=128){while(1){e=e+1|0;f=a>>>0>16383;a=a>>>7|0;if(f){continue}break}}if(b>>>0>=128){a=b;while(1){d=d+1|0;f=a>>>0>16383;a=a>>>7|0;if(f){continue}break}}return(((b+c|0)+e|0)+d|0)+67|0}function Cb(a){var b=0,c=0,d=0;if(D[F[a>>2]]-48>>>0>=10){return 0}while(1){d=F[a>>2];c=-1;if(b>>>0<=214748364){c=D[d|0]-48|0;b=L(b,10);c=(c|0)>(2147483647-b|0)?-1:c+b|0}F[a>>2]=d+1;b=c;if(D[d+1|0]-48>>>0<10){continue}break}return b}function Ib(a){var b=0,c=0,d=0;b=4;c=a+164|0;d=F[a+160>>2];if((c|0)!=(d|0)){while(1){b=b+69|0;c=c+72|0;if((d|0)!=(c|0)){continue}break}}b=b+165|0;a:{if(!G[a+7364|0]){break a}b=b+69|0;if(G[a+7364|0]<2){break a}b=b+69|0}return b+4|0}function gc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0;f=_-32|0;_=f;a:{if((oa(c)|0)!=32){F[a+3216>>2]=7;c=-1;break a}sa(b,c,f);c=-1;b=oa(e);if((b|0)==-1){F[a+3216>>2]=7;break a}sa(d,e,d);c=Qb(a,f,d,b)}_=f+32|0;return c|0}function Za(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;f=aa[F[441]](2804,d)|0;e=f+(aa[F[440]](2804)|0)|0;g=e+2|0;h=(g>>>0)/3|0;i=a;j=b;b=((g-L(h,3)|0)+(h<<2)|0)-2|0;a=(b+c|0)-e|0;aa[F[442]](2804,i,j,a,d,a,f,a,e)|0;Ca(a,e,c);return b}function se(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=c>>>16|0;f=a>>>16|0;j=L(e,f);g=c&65535;h=a&65535;i=L(g,h);f=(i>>>16|0)+L(f,g)|0;e=(f&65535)+L(e,h)|0;$=(L(b,c)+j|0)+L(a,d)+(f>>>16)+(e>>>16)|0;return i&65535|e<<16}function eb(a,b,c){var d=0,e=0;F[c>>2]=0;a:{if(!a){break a}e=b;b=a+4|0;if(e>>>0>>0){break a}d=G[a|0]<<8;F[c>>2]=d;d=(d|G[a+1|0])<<8;F[c>>2]=d;d=(d|G[a+2|0])<<8;F[c>>2]=d;F[c>>2]=d|G[a+3|0];d=b}return d}function yc(a){a=a|0;var b=0,c=0,d=0;b=a+164|0;c=F[a+160>>2];a:{if((b|0)!=(c|0)){a=1;while(1){if(!G[b+4|0]){d=d+55|0;a=0}b=b+72|0;if((c|0)!=(b|0)){continue}break}b=16;if(!a){break a}}b=17}return b+d|0}function pa(a,b,c,d,e){var f=0;f=_-256|0;_=f;if(!(e&73728|(c|0)<=(d|0))){c=c-d|0;d=c>>>0<256;qa(f,b&255,d?c:256);if(!d){while(1){na(a,f,256);c=c-256|0;if(c>>>0>255){continue}break}}na(a,f,c)}_=f+256|0}function Fb(a){var b=0;b=F[a+72>>2];F[a+72>>2]=b-1|b;b=F[a>>2];if(b&8){F[a>>2]=b|32;return-1}F[a+4>>2]=0;F[a+8>>2]=0;b=F[a+44>>2];F[a+28>>2]=b;F[a+20>>2]=b;F[a+16>>2]=b+F[a+48>>2];return 0} +function wc(a){a=a|0;var b=0,c=0,d=0;b=a+164|0;c=F[a+160>>2];if((b|0)!=(c|0)){while(1){if(!G[b+4|0]){D[b+4|0]=1;d=d+1|0}b=b+72|0;if((c|0)!=(b|0)){continue}break}}D[a+7372|0]=1;return d|0}function ud(a,b){a=a|0;b=b|0;var c=0;c=F[9340];b=aa[F[F[c>>2]+4>>2]](c,b)|0;c=F[9340];c=aa[F[F[c>>2]>>2]](c)|0;b=xb(F[a+128>>2],b,c)+2|0;a=(b>>>0)/3|0;return((b-L(a,3)|0)+(a<<2)|0)-2|0}function va(a,b,c){var d=0;F[c>>2]=0;if(!(!a|a+4>>>0>b>>>0)){b=G[a|0]<<8;F[c>>2]=b;b=(b|G[a+1|0])<<8;F[c>>2]=b;b=(b|G[a+2|0])<<8;F[c>>2]=b;F[c>>2]=b|G[a+3|0];d=a+4|0}return d}function La(a){var b=0,c=0;b=F[9342];c=a+3&-4;a=b+c|0;a:{if(a>>>0<=b>>>0?c:0){break a}if(a>>>0>ba()<<16>>>0){if(!(Y(a|0)|0)){break a}}F[9342]=a;return b}F[9343]=48;return-1}function yd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0;f=a+132|0;if(Da(232)>>>0>e>>>0){F[a+228>>2]=2;return-1}sb(jb(a,la(_a(d,232),1)),f);return Za(b,c,d,232)|0}function ob(a,b){var c=0,d=0;d=F[a+44>>2]==(a+48|0)?0:F[a+112>>2];c=F[a+4>>2];b=aa[F[F[c>>2]+4>>2]](c,b)|0;a=F[a+4>>2];return zb(d,b,aa[F[F[a>>2]>>2]](a)|0)}function Zd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;if(c>>>0<43){F[a>>2]=2;return-1}if(e>>>0<=31){F[a>>2]=15;return-1}a=a+4|0;kb(d,a);ma(a,32,b);return 0}function Ub(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;if(c>>>0<43){F[a>>2]=2;return-1}if(e>>>0<=31){F[a>>2]=15;return-1}a=a+4|0;Fa(d,a);ma(a,32,b);return 0}function kd(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<43){F[a>>2]=15;return-1}if((Pa(b,c,b)|0)==-1){F[a>>2]=7;return-1}za(a+4|0,b,a+68|0);F[a+100>>2]=1;return 0}function qe(a){a=a|0;ia(a,36);F[a+32>>2]=0;F[a+24>>2]=0;F[a+28>>2]=0;F[a+16>>2]=0;F[a+20>>2]=0;F[a+8>>2]=0;F[a+12>>2]=0;F[a>>2]=0;F[a+4>>2]=0;return 36}function ge(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0;f=a+4|0;if(Da(68)>>>0>e>>>0){F[a>>2]=2;return-1}Na(la(_a(d,68),1),f);return Za(b,c,d,68)|0}function vb(a,b,c){var d=0,e=0;a=va(a,b,c);a:{if(!a){break a}if(!(!a|(a|0)==(b|0))){D[c+4|0]=G[a|0]!=0;d=a+1|0}if(!d){break a}e=Ja(d,b,c+5|0)}return e}function yb(a){var b=0,c=0,d=0;b=1;if(a>>>0>=128){c=a;while(1){b=b+1|0;d=c>>>0>16383;c=c>>>7|0;if(d){continue}break}}return(a+b|0)+104|0}function _a(a,b){var c=0,d=0;c=aa[F[441]](2804,b)+aa[F[440]](2804)|0;d=c+2|0;b=(d>>>0)/3|0;return((((d-L(b,3)|0)+(b<<2)|0)-2|0)+a|0)-c|0}function zc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;if(e>>>0<86){F[a+7516>>2]=2;return-1}e=a;a=d+22|0;bb(e,b,c,a);ma(a,64,d);return 86}function Sb(a){F[a+8>>2]=0;F[a+4>>2]=1888;F[a>>2]=1872;F[a+492>>2]=a+496;F[a+148>>2]=a+152;F[a+44>>2]=a+48;D[a+3220|0]=0;F[a+3216>>2]=0}function Xd(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;if(e>>>0<86){F[a>>2]=2;return-1}e=a+4|0;a=d+22|0;bb(e,b,c,a);ma(a,64,d);return 86}function lc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=oa(d);if((e|0)==-1){F[a+3216>>2]=7;return-1}sa(c,d,c);return Rb(a,b,0,c,e)|0}function Dc(a,b,c){a=a|0;b=b|0;c=c|0;a:{if(c>>>0<=63){F[a+7516>>2]=1;a=-1;break a}kb(b,a);Fa(b+32|0,a+96|0);a=0}ia(b,c);return a|0}function la(a,b){b=b<<8&16711680|b<<24|(b>>>8&65280|b>>>24);D[a|0]=b;D[a+1|0]=b>>>8;D[a+2|0]=b>>>16;D[a+3|0]=b>>>24;return a+4|0}function $b(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;if(e>>>0<43){F[a>>2]=2;return-1}Kb(b,c,d+11|0);ma(d+11|0,32,d);return 43}function id(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;if(!F[a+100>>2]){F[a>>2]=16;return-1}Aa(a+68|0,32,0,0,b,c,d,e);return 0}function vd(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<=159){F[a+228>>2]=1;return-1}$a(a,b,0);kb(b+128|0,a+132|0);ia(b,c);return 0}function hc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=oa(c);if((d|0)==-1){F[a+3216>>2]=7;return-1}sa(b,c,b);return Qb(a,0,b,d)|0}function Da(a){var b=0;b=(aa[F[441]](2804,a)+aa[F[440]](2804)|0)+2|0;a=(b>>>0)/3|0;return((b-L(a,3)|0)+(a<<2)|0)-2|0}function Ta(a,b,c,d){var e=0,f=0;a:{if(!a){break a}e=b;b=a+d|0;if(e>>>0>>0){break a}ja(c,a,d);f=b}return f}function oe(a,b){a=a|0;b=b|0;b=(aa[F[441]](F[1416],b)|0)+2|0;a=(b>>>0)/3|0;return((b-L(a,3)|0)+(a<<2)|0)-2|0}function ne(a){a=a|0;var b=0;b=(aa[F[440]](F[1416])|0)+2|0;a=(b>>>0)/3|0;return((b-L(a,3)|0)+(a<<2)|0)-2|0}function Mc(a){a=a|0;ia(a,7520);F[a+7512>>2]=0;F[a+7516>>2]=0;D[a+7364|0]=0;F[a+160>>2]=a+164;return 7520}function md(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<=31){F[a>>2]=1;return-1}Fa(b,a+4|0);F[a+100>>2]=0;return 0}function Pc(a){a=a|0;ia(a,7520);F[a+7512>>2]=0;F[a+7516>>2]=0;D[a+7364|0]=0;F[a+160>>2]=a+164;return a|0}function sd(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<43){F[a+228>>2]=2;return-1}return Ca(a+132|0,32,b)|0}function Id(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<43){F[a+300>>2]=2;return-1}return Ca(a+264|0,32,b)|0}function pe(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<43){F[a>>2]=15;return-1}sa(b,43,a+4|0);return 0}function ld(a,b,c){a=a|0;b=b|0;c=c|0;if(c>>>0<43){F[a>>2]=2;return-1}Ca(a+4|0,32,b);return 0}function Wc(a){a=a|0;a=F[a+7516>>2];if(a>>>0<=17){a=F[(a<<2)+2720>>2]}else{a=1191}return a|0}function Uc(a){a=a|0;a=F[a+3216>>2];if(a>>>0<=17){a=F[(a<<2)+2720>>2]}else{a=1191}return a|0}function Rd(a){a=a|0;a=F[a+300>>2];if(a>>>0<=17){a=F[(a<<2)+2720>>2]}else{a=1191}return a|0}function Bd(a){a=a|0;a=F[a+228>>2];if(a>>>0<=17){a=F[(a<<2)+2720>>2]}else{a=1191}return a|0}function dc(a,b){a=a|0;b=b|0;b=Pb(a,b)+2|0;a=(b>>>0)/3|0;return((b-L(a,3)|0)+(a<<2)|0)-2|0}function ue(a,b){var c=0,d=0;c=b&31;d=(-1>>>c&a)<>>a}function Wa(a){a=a|0;a=F[a>>2];if(a>>>0<=17){a=F[(a<<2)+2720>>2]}else{a=1191}return a|0}function oa(a){if((a&3)!=1){a=a+2|0;a=((a&3)+L(a>>>2|0,3)|0)-2|0}else{a=-1}return a}function Yc(a,b,c){a=a|0;b=b|0;c=c|0;if(a){D[a|0]=3}if(b){D[b|0]=2}if(c){D[c|0]=15}}function ib(a,b,c){b=Ta(b,c,a,128);if(!b){return 0}return eb(b,c,a+128|0)}function nc(a){a=a|0;if(G[a+7364|0]>=2){D[a+7364|0]=1;ia(a+7440|0,72)}}function ee(a,b){a=a|0;b=b|0;a=F[443];return aa[a|0](F[1416],oa(b))|0}function Vd(a){a=a|0;return(a>>>0<=17?F[(a<<2)+2720>>2]:1191)|0}function pc(a){a=a|0;return(G[a+7372|0]|!G[a+7364|0]?17:71)|0}function Pb(a,b){b=ob(a,b);if(!G[a+3220|0]){b=yb(b)}return b}function $d(a){a=a|0;ia(a,100);qa(a,0,100);return 100}function ec(a){a=a|0;return(F[a+44>>2]==(a+48|0))<<5}function jb(a,b){return la(Ua(b,a,128),F[a+128>>2])}function je(a){a=a|0;ia(a,68);qa(a,0,68);return 68}function Nc(a){a=a|0;ia(a,4);F[a>>2]=0;return a|0}function Lc(a){a=a|0;ia(a,3320);Sb(a);return 3320}function rc(a){a=a|0;return(G[a+7364|0]?71:17)|0}function Oc(a){a=a|0;ia(a,3320);Sb(a);return a|0}function Kc(a){a=a|0;ia(a,4);F[a>>2]=0;return 4}function Zc(a){a=a|0;a=_-a&-16;_=a;return a|0}function re(a,b){a=a|0;b=b|0;return b+16&-16}function $a(a,b,c){F[a+128>>2]=c;ja(a,b,128)}function od(a){a=a|0;ia(a,104);return a|0}function nd(a){a=a|0;ia(a,104);return 104}function ae(a){a=a|0;ia(a,100);return a|0}function Td(a){a=a|0;ia(a,304);return a|0}function Sd(a){a=a|0;ia(a,304);return 304}function Dd(a){a=a|0;ia(a,232);return a|0}function Cd(a){a=a|0;ia(a,232);return 232}function uc(a,b){a=a|0;b=b|0;return b<<5}function ke(a){a=a|0;ia(a,68);return a|0}function Xb(a){a=a|0;ia(a,36);return a|0}function Vc(a){a=a|0;return F[a+7516>>2]}function Tc(a){a=a|0;return F[a+3216>>2]}function tb(a){a=a|0;return G[a+3220|0]}function jd(a){a=a|0;return F[a+100>>2]}function _d(a,b){a=a|0;b=b|0;return b|0}function Ua(a,b,c){return ja(a,b,c)+c|0}function Qd(a){a=a|0;return F[a+300>>2]}function Lb(a){a=a|0;return F[a+128>>2]}function Jc(a){a=a|0;return Da(Ib(a))|0}function Ic(a){a=a|0;return Da(Ob(a))|0}function Hd(a){a=a|0;return F[a+296>>2]}function Ad(a){a=a|0;return F[a+228>>2]}function Wb(){F[9380]=37408;F[9362]=42}function zd(a){a=a|0;return Da(232)|0}function Nd(a){a=a|0;return Da(301)|0}function he(a){a=a|0;return Da(68)|0}function Va(a){a=a|0;return F[a>>2]}function Pa(a,b,c){return sa(a,b,c)}function za(a,b,c){Gb(c,a+32|0,b)}function wd(a){a=a|0;return 160}function vc(a){a=a|0;return 100}function rd(a){a=a|0;return 306}function Gd(a){a=a|0;return 220}function Cc(a){a=a|0;return 116}function ub(a){a=a|0;return 64}function qb(a){a=a|0;return 32}function Qa(a){a=a|0;return 43}function Ac(a){a=a|0;return 86}function Zb(a){a=a|0;return 8}function Sc(){return 7520}function Rc(){return 3320}function pd(){return 104}function be(){return 100}function _c(a){a=a|0;_=a}function Ud(){return 304}function Ed(){return 232}function $c(){return _|0}function pb(){return 32}function le(){return 68}function Yd(){return 86}function Yb(){return 36}function Vb(){return 43}function Xc(){return-1}function Qc(){return 4} +// EMSCRIPTEN_END_FUNCS +e=G;p(da);var aa=c([null,Zb,re,ie,_d,Wd,ed,dd,cd]);function ba(){return C.byteLength/65536|0}return{"d":Wb,"e":aa,"f":Yc,"g":Xc,"h":Wc,"i":Vd,"j":Vc,"k":Uc,"l":Tc,"m":Wa,"n":Va,"o":Sc,"p":Rc,"q":Qc,"r":Pc,"s":Oc,"t":Nc,"u":Mc,"v":Lc,"w":Kc,"x":Jc,"y":Ic,"z":Hc,"A":Gc,"B":Fc,"C":Ec,"D":ub,"E":Dc,"F":Cc,"G":Bc,"H":Ac,"I":zc,"J":yc,"K":xc,"L":wc,"M":vc,"N":uc,"O":tc,"P":qb,"Q":sc,"R":rc,"S":qc,"T":pc,"U":oc,"V":nc,"W":ub,"X":mc,"Y":lc,"Z":kc,"_":Qa,"$":jc,"aa":tb,"ba":ic,"ca":hc,"da":gc,"ea":fc,"fa":tb,"ga":ec,"ha":dc,"ia":cc,"ja":bc,"ka":ac,"la":Qa,"ma":$b,"na":_b,"oa":Wa,"pa":Va,"qa":Yb,"ra":Xb,"sa":qe,"ta":pe,"ua":Vb,"va":oe,"wa":ne,"xa":qb,"ya":me,"za":Wa,"Aa":Va,"Ba":le,"Ca":ke,"Da":je,"Ea":pb,"Fa":pb,"Ga":Ub,"Ha":Ub,"Ia":he,"Ja":ge,"Ka":fe,"La":ee,"Ma":de,"Na":ce,"Oa":be,"Pa":ae,"Qa":Wa,"Ra":Va,"Sa":$d,"Ta":pb,"Ua":Vb,"Va":Zd,"Wa":Yd,"Xa":Xd,"Ya":Ud,"Za":Td,"_a":Sd,"$a":Rd,"ab":Qd,"bb":Pd,"cb":Od,"db":Nd,"eb":Md,"fb":Ld,"gb":Kd,"hb":Jd,"ib":Qa,"jb":Id,"kb":Lb,"lb":Hd,"mb":Gd,"nb":Fd,"ob":Ed,"pb":Dd,"qb":Cd,"rb":Bd,"sb":Ad,"tb":zd,"ub":yd,"vb":xd,"wb":wd,"xb":vd,"yb":ud,"zb":td,"Ab":Qa,"Bb":sd,"Cb":Lb,"Db":rd,"Eb":qd,"Fb":Wa,"Gb":Va,"Hb":pd,"Ib":od,"Jb":nd,"Kb":qb,"Lb":md,"Mb":Qa,"Nb":ld,"Ob":kd,"Pb":jd,"Qb":id,"Rb":Qa,"Sb":hd,"Tb":gd,"Ub":fd,"Vb":bd,"Wb":ad,"Xb":$c,"Yb":_c,"Zb":Zc}}return ca(ea)} +// EMSCRIPTEN_END_ASM + + + + +)(sa)}function ta(){return{then:function(b){b({instance:new ra})}}}var ua=Error,WebAssembly={};t=[];"object"!=typeof WebAssembly&&q("no native wasm support detected"); +var va,wa=!1,xa="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0; +function u(b,c){if(b){var d=ya,e=b+c;for(c=b;d[c]&&!(c>=e);)++c;if(16f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}b=e}}else b="";return b} +function za(b,c,d,e){if(!(0=p){var v=b.charCodeAt(++k);p=65536+((p&1023)<<10)|v&1023}if(127>=p){if(d>=e)break;c[d++]=p}else{if(2047>=p){if(d+1>=e)break;c[d++]=192|p>>6}else{if(65535>=p){if(d+2>=e)break;c[d++]=224|p>>12}else{if(d+3>=e)break;c[d++]=240|p>>18;c[d++]=128|p>>12&63}c[d++]=128|p>>6&63}c[d++]=128|p&63}}c[d]=0;return d-f}function w(b,c,d){return za(b,ya,c,d)} +function x(b){for(var c=0,d=0;d=e?c++:2047>=e?c+=2:55296<=e&&57343>=e?(c+=4,++d):c+=3}return c}var Aa,y,ya,Ba,z,Ca,Ea,Fa,qa=a.INITIAL_MEMORY||16777216;a.wasmMemory?va=a.wasmMemory:va=new pa;va&&(Aa=va.buffer);qa=Aa.byteLength;var A=Aa;Aa=A;a.HEAP8=y=new Int8Array(A);a.HEAP16=Ba=new Int16Array(A);a.HEAP32=z=new Int32Array(A);a.HEAPU8=ya=new Uint8Array(A);a.HEAPU16=new Uint16Array(A);a.HEAPU32=Ca=new Uint32Array(A);a.HEAPF32=Ea=new Float32Array(A); +a.HEAPF64=Fa=new Float64Array(A);var Ga=[],Ha=[],Ia=[];function Ja(){var b=a.preRun.shift();Ga.unshift(b)}var B=0,Ka=null,La=null;function q(b){if(a.onAbort)a.onAbort(b);b="Aborted("+b+")";r(b);wa=!0;b=new ua(b+". Build with -sASSERTIONS for more info.");ba(b);throw b;}var Ma="data:application/octet-stream;base64,",C;C="olm_legacy.wasm";if(!C.startsWith(Ma)){var Na=C;C=a.locateFile?a.locateFile(Na,m):m+Na} +function Oa(){var b=C;try{if(b==C&&t)return new Uint8Array(t);var c=n(b);if(c)return c;if(la)return la(b);throw"both async and sync fetching of the wasm failed";}catch(d){q(d)}} +function Pa(){if(!t&&(ha||l)){if("function"==typeof fetch&&!C.startsWith("file://"))return fetch(C,{credentials:"same-origin"}).then(function(b){if(!b.ok)throw"failed to load wasm binary file at '"+C+"'";return b.arrayBuffer()}).catch(function(){return Oa()});if(ka)return new Promise(function(b,c){ka(C,function(d){b(new Uint8Array(d))},c)})}return Promise.resolve().then(function(){return Oa()})}var Qa;function Ra(b){for(;0>0];case "i8":return y[b>>0];case "i16":return Ba[b>>1];case "i32":return z[b>>2];case "i64":return z[b>>2];case "float":return Ea[b>>2];case "double":return Fa[b>>3];case "*":return Ca[b>>2];default:q("invalid type for getValue: "+c)}return null} +function D(b){var c="i8";c.endsWith("*")&&(c="*");switch(c){case "i1":y[b>>0]=0;break;case "i8":y[b>>0]=0;break;case "i16":Ba[b>>1]=0;break;case "i32":z[b>>2]=0;break;case "i64":Qa=[0,0];z[b>>2]=Qa[0];z[b+4>>2]=Qa[1];break;case "float":Ea[b>>2]=0;break;case "double":Fa[b>>3]=0;break;case "*":Ca[b>>2]=0;break;default:q("invalid type for setValue: "+c)}}function Ta(b,c,d){for(var e=0;e>0]=b.charCodeAt(e);d||(y[c>>0]=0)} +function Ua(b,c,d){d=Array(0>4;f=(f&15)<<4|k>>2;var v=(k&3)<<6|p;c+=String.fromCharCode(e);64!==k&&(c+=String.fromCharCode(f));64!==p&&(c+=String.fromCharCode(v))}while(d + + diff --git a/hydrogen/assets/paperclip-3961996319.da562307.svg b/hydrogen/assets/paperclip-3961996319.da562307.svg new file mode 100644 index 0000000..5538dd7 --- /dev/null +++ b/hydrogen/assets/paperclip-3961996319.da562307.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/paperclip.ec29fd9d.svg b/hydrogen/assets/paperclip.ec29fd9d.svg new file mode 100644 index 0000000..c18661e --- /dev/null +++ b/hydrogen/assets/paperclip.ec29fd9d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/plus-3937109722.5c243914.svg b/hydrogen/assets/plus-3937109722.5c243914.svg new file mode 100644 index 0000000..6f60a21 --- /dev/null +++ b/hydrogen/assets/plus-3937109722.5c243914.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/plus-4190356069.084c5e3d.svg b/hydrogen/assets/plus-4190356069.084c5e3d.svg new file mode 100644 index 0000000..04b67de --- /dev/null +++ b/hydrogen/assets/plus-4190356069.084c5e3d.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/plus.49560f96.svg b/hydrogen/assets/plus.49560f96.svg new file mode 100644 index 0000000..54e5d06 --- /dev/null +++ b/hydrogen/assets/plus.49560f96.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/room-members-1680968332.b4f57622.svg b/hydrogen/assets/room-members-1680968332.b4f57622.svg new file mode 100644 index 0000000..e500f2e --- /dev/null +++ b/hydrogen/assets/room-members-1680968332.b4f57622.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hydrogen/assets/room-members-2999414798.6534e8ec.svg b/hydrogen/assets/room-members-2999414798.6534e8ec.svg new file mode 100644 index 0000000..8c1e917 --- /dev/null +++ b/hydrogen/assets/room-members-2999414798.6534e8ec.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hydrogen/assets/room-members-3084360280.6f64aaef.svg b/hydrogen/assets/room-members-3084360280.6f64aaef.svg new file mode 100644 index 0000000..c2e87ef --- /dev/null +++ b/hydrogen/assets/room-members-3084360280.6f64aaef.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hydrogen/assets/room-members-3297708388.1a158fe2.svg b/hydrogen/assets/room-members-3297708388.1a158fe2.svg new file mode 100644 index 0000000..ceca0e3 --- /dev/null +++ b/hydrogen/assets/room-members-3297708388.1a158fe2.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hydrogen/assets/room-members-3847743605.9fcf4567.svg b/hydrogen/assets/room-members-3847743605.9fcf4567.svg new file mode 100644 index 0000000..85c244c --- /dev/null +++ b/hydrogen/assets/room-members-3847743605.9fcf4567.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hydrogen/assets/room-members-871477030.90b799fe.svg b/hydrogen/assets/room-members-871477030.90b799fe.svg new file mode 100644 index 0000000..09f92d9 --- /dev/null +++ b/hydrogen/assets/room-members-871477030.90b799fe.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hydrogen/assets/room-members.35ed0bf9.svg b/hydrogen/assets/room-members.35ed0bf9.svg new file mode 100644 index 0000000..61cdf29 --- /dev/null +++ b/hydrogen/assets/room-members.35ed0bf9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/search-261439583.1bffaca1.svg b/hydrogen/assets/search-261439583.1bffaca1.svg new file mode 100644 index 0000000..3700c3e --- /dev/null +++ b/hydrogen/assets/search-261439583.1bffaca1.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/search-3263540198.1511780c.svg b/hydrogen/assets/search-3263540198.1511780c.svg new file mode 100644 index 0000000..b923e68 --- /dev/null +++ b/hydrogen/assets/search-3263540198.1511780c.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/search.21e0fd39.svg b/hydrogen/assets/search.21e0fd39.svg new file mode 100644 index 0000000..584b865 --- /dev/null +++ b/hydrogen/assets/search.21e0fd39.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/send-1171052351.caa5c494.svg b/hydrogen/assets/send-1171052351.caa5c494.svg new file mode 100644 index 0000000..a21a578 --- /dev/null +++ b/hydrogen/assets/send-1171052351.caa5c494.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/send-3413346515.b0fb8626.svg b/hydrogen/assets/send-3413346515.b0fb8626.svg new file mode 100644 index 0000000..1742eef --- /dev/null +++ b/hydrogen/assets/send-3413346515.b0fb8626.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/send.7a090949.svg b/hydrogen/assets/send.7a090949.svg new file mode 100644 index 0000000..b64d074 --- /dev/null +++ b/hydrogen/assets/send.7a090949.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/settings-2175246113.00804666.svg b/hydrogen/assets/settings-2175246113.00804666.svg new file mode 100644 index 0000000..85d1de1 --- /dev/null +++ b/hydrogen/assets/settings-2175246113.00804666.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/settings-878939771.57cf3680.svg b/hydrogen/assets/settings-878939771.57cf3680.svg new file mode 100644 index 0000000..4e3aee3 --- /dev/null +++ b/hydrogen/assets/settings-878939771.57cf3680.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/settings.45b8e09f.svg b/hydrogen/assets/settings.45b8e09f.svg new file mode 100644 index 0000000..fb8809a --- /dev/null +++ b/hydrogen/assets/settings.45b8e09f.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/theme-element-dark.a6fddb2f.css b/hydrogen/assets/theme-element-dark.a6fddb2f.css new file mode 100644 index 0000000..8142591 --- /dev/null +++ b/hydrogen/assets/theme-element-dark.a6fddb2f.css @@ -0,0 +1 @@ +@font-face{font-family:"emoji";src:local("Apple Color Emoji"),local("Segoe UI Emoji"),local("Segoe UI Symbol"),local("Noto Color Emoji"),local("Twemoji"),local("Twemoji Mozilla"),local("Android Emoji"),local("EmojiSymbols"),local("Symbola");unicode-range:U+1F300-1F5FF,U+1F600-1F64F,U+1F680-1F6FF,U+2600-26FF}html{height:100%}main{display:block}@media screen and (min-width: 600px){.PreSessionScreen{width:600px;box-sizing:border-box;margin:50px auto 0}}.room-placeholder{display:flex;flex-direction:row}.SessionView{position:fixed;height:100%;width:100%;display:grid;grid-template:"status status" auto "left middle" 1fr / 320px 1fr;min-height:0;min-width:0}.right-shown{grid-template:"status status status" auto "left middle right" 1fr / 320px 1fr 300px}.hydrogen.ios .SessionView{height:var(--ios-viewport-height, 100%);top:var(--ios-viewport-top, 0)}.middle .close-middle{display:none}@media screen and (max-width: 800px){.SessionView:not(.middle-shown):not(.right-shown){grid-template:"status" auto "left" 1fr / 1fr}.SessionView.middle-shown{grid-template:"status" auto "middle" 1fr / 1fr}.SessionView.right-shown{grid-template:"status" auto "right" 1fr / 1fr}.SessionView:not(.middle-shown):not(.right-shown) .room-placeholder{display:none}.SessionView.middle-shown .LeftPanel,.SessionView.right-shown .middle,.SessionView.right-shown .LeftPanel{display:none}.middle .close-middle{display:block!important}.LeftPanel .grid{display:none!important}.VerificationReadyTileView{flex-direction:column}.VerificationTileView__actions{justify-content:center}}.LeftPanel{grid-area:left;min-width:0;min-height:0}.room-placeholder,.middle{min-width:0;grid-area:middle;width:100%;min-height:0}.middle{display:flex;flex-direction:column}.SessionStatusView{grid-area:status}.lightbox{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1;box-sizing:border-box;height:100%}.RoomView_body{flex:1 1;min-height:0;min-width:0;display:flex;flex-direction:column;height:100%}.RoomView_body .Timeline,.RoomView_body .TimelineLoadingView{flex:1 0}.middle-header{display:flex}.RoomGridView{display:grid}.RoomGridView.layout3x2{grid-template:"t0 t1 t2" 1fr "t3 t4 t5" 1fr / 1fr 1fr 1fr}.RoomGridView>.tile0{grid-area:t0}.RoomGridView>.tile1{grid-area:t1}.RoomGridView>.tile2{grid-area:t2}.RoomGridView>.tile3{grid-area:t3}.RoomGridView>.tile4{grid-area:t4}.RoomGridView>.tile5{grid-area:t5}.RoomGridView>div{display:flex;min-width:0;min-height:0}.RoomGridView>div.focus-ring{z-index:1;pointer-events:none}.menu{position:absolute;z-index:2}.menu .menu-item{box-sizing:border-box;width:100%}.Settings{display:flex;flex-direction:column}.SettingsBody{min-height:0;overflow-y:auto}.LazyListParent{flex:1 1;flex-basis:0;margin-top:15px}.LoadingView{display:flex;justify-content:center;align-items:center}.vertical-layout{display:flex;flex-direction:row;align-items:center;gap:12px}.vertical-layout>.stretch{flex:1 0}.popupContainer{position:absolute;white-space:nowrap}.SessionPickerView{padding:.4em}.SessionPickerView ul{list-style:none;padding:0}.SessionPickerView li{margin:.4em 0}.SessionPickerView .session-info{cursor:pointer;display:flex;align-items:center}.SessionPickerView .session-info>:not(:first-child){margin-left:8px}.SessionPickerView li .user-id{flex:1 1;overflow:hidden;text-overflow:ellipsis}.SessionPickerView li .error{margin:0 20px}.PasswordLoginView{padding:0 .4em .4em}.SessionLoadStatusView>.status,.LoginView_query-spinner{display:flex;gap:12px}.SessionLoadStatusView>.status p,.LoginView_query-spinner p{flex:1 1;margin:0}.SessionLoadStatusView .spinner{--size: 20px}.StartSSOLoginView{display:flex;flex-direction:column;padding:0 .4em}.StartSSOLoginView_button{flex:1 1;margin-top:12px}.LoginView_separator{justify-content:center;display:flex;margin:8px}.CompleteSSOView_title{display:flex;justify-content:center}.LoginView_sso{padding:.4em .4em 0}.LeftPanel{display:flex;flex-direction:column}.LeftPanel .utilities{display:flex}.LeftPanel .utilities .FilterField{flex:1 1;min-width:0}.LeftPanel ul{list-style:none;padding:0;margin:0}.RoomList{flex:1 0;overflow-y:auto;overscroll-behavior:contain}.RoomList>li>a{display:flex;align-items:center}.RoomList .description{margin:0;flex:1 1;min-width:0;display:flex}.RoomList .description>.name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;flex:1 1}.RightPanelView{grid-area:right;min-height:0;min-width:0;display:flex;flex-direction:column}.RoomDetailsView,.MemberDetailsView{flex-direction:column;flex:1 1}.RoomDetailsView_avatar{display:flex}.RoomDetailsView_name h2,.MemberDetailsView_name h2{text-align:center}.MemberDetailsView_shield_container{display:flex;gap:4px}.MemberDetailsView_shield_red,.MemberDetailsView_shield_green,.MemberDetailsView_shield_black{background-size:contain;background-repeat:no-repeat;width:24px;height:24px;display:block;flex-shrink:0}.MemberDetailsView_shield_description{flex-grow:1;margin:0}.MemberDetailsView_shield_red{background-image:var(--icon-url-0)}.MemberDetailsView_shield_green{background-image:var(--icon-url-1)}.MemberDetailsView_shield_black{background-image:var(--icon-url-2)}.RoomDetailsView_label,.RoomDetailsView_row,.RoomDetailsView,.MemberDetailsView,.EncryptionIconView{display:flex;align-items:center;color:var(--text-color)}.RoomDetailsView_value{display:flex;justify-content:flex-end}.EncryptionIconView{justify-content:center}.RightPanelView_buttons{display:flex;justify-content:space-between;width:100%;box-sizing:border-box;padding:16px}.RightPanelView_buttons .hide{visibility:hidden}.MemberTileView a{display:flex;align-items:center}.middle-header{align-items:center}.middle-header h2{flex:1 1}.middle-header .room-description{flex:1 1;min-width:0}.RoomHeader .topic{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.RoomHeader .description{flex:1 1 auto;min-width:0}.middle-header h2{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin:0}.MessageComposer_replyPreview{display:grid;grid-template-columns:1fr auto}.MessageComposer_replyPreview .Timeline_message{grid-column:1/-1}.MessageComposer_input{display:flex;align-items:center}.MessageComposer_input>input{display:block;flex:1 1;min-width:0;box-sizing:border-box}.TimelineLoadingView{display:flex;align-items:center;justify-content:center}.TimelineLoadingView>:not(:first-child){margin-left:12px}.Timeline{display:flex;flex-direction:column;position:relative;min-height:0}.Timeline_jumpDown{position:absolute}.Timeline_scroller{overflow-y:scroll;overscroll-behavior-y:contain;overflow-anchor:none;padding:0;margin:0;position:relative;min-height:0;flex:1 0}.Timeline_scroller>ul{list-style:none;padding:1px 0;margin:0}.AnnouncementView{display:flex;align-items:center}.GapView_container{display:flex}.GapView_container>span{flex:1 1}.Timeline_messageBody img{max-width:400px;max-height:300px}.hydrogen{--avatar-size: 32px}.hydrogen .avatar{width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6);overflow:hidden;flex-shrink:0;user-select:none;text-align:center;speak:none}.hydrogen .avatar img{width:100%;height:100%;object-fit:cover}.hydrogen .avatar.size-128{--avatar-size: 128px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-96{--avatar-size: 96px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-64{--avatar-size: 64px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-52{--avatar-size: 52px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-30{--avatar-size: 30px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-24{--avatar-size: 24px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-12{--avatar-size: 12px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}@keyframes spinner{0%{transform:rotate(0);stroke-dasharray:0 0 10 90}45%{stroke-dasharray:0 0 90 10}75%{stroke-dasharray:0 50 50 0}to{transform:rotate(360deg);stroke-dasharray:10 90 0 0}}.hydrogen:not(.legacy) .spinner circle{transform-origin:50% 50%;animation-name:spinner;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear;stroke-dasharray:0 0 85 85;fill:none;stroke:currentcolor;stroke-width:12;stroke-linecap:butt}.hydrogen.legacy .spinner{display:inline-block;position:relative}.hydrogen.legacy .spinner div{box-sizing:border-box;display:block;position:absolute;padding:2px;border:2px solid currentcolor;border-radius:50%;animation:legacy-spinner 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:currentcolor transparent transparent transparent;width:var(--size);height:var(--size)}.hydrogen.legacy .spinner div:nth-child(1){animation-delay:-.45s}.hydrogen.legacy .spinner div:nth-child(2){animation-delay:-.3s}.hydrogen.legacy .spinner div:nth-child(3){animation-delay:-.15s}@keyframes legacy-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinner{--size: 20px;width:var(--size);height:var(--size)}.form-row.text>input,.form-row.text>textarea{display:block;width:100%;min-width:0;box-sizing:border-box}.FilterField{display:flex}.FilterField input{display:block;flex:1 1;min-width:0}.SessionStatusView{display:flex}.SessionStatusView p{margin:0 10px;word-break:break-all;word-break:break-word}body.hydrogen{overscroll-behavior:none;overflow:hidden}.hydrogen{margin:0}.hiddenWithLayout{visibility:hidden}.hidden{display:none!important}input::-ms-clear{display:none}@font-face{font-family:Inter;font-style:normal;font-weight:100;font-display:swap;src:url(./Inter-Thin.5d8e2ac4.woff2) format("woff2"),url(./Inter-Thin.5565b01e.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:100;font-display:swap;src:url(./Inter-ThinItalic.6b3ded18.woff2) format("woff2"),url(./Inter-ThinItalic.c413497b.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:200;font-display:swap;src:url(./Inter-ExtraLight.da47c335.woff2) format("woff2"),url(./Inter-ExtraLight.d7be68a4.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:200;font-display:swap;src:url(./Inter-ExtraLightItalic.b3f94cfe.woff2) format("woff2"),url(./Inter-ExtraLightItalic.762fa4d2.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:300;font-display:swap;src:url(./Inter-Light.0f7dfe72.woff2) format("woff2"),url(./Inter-Light.38326098.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:300;font-display:swap;src:url(./Inter-LightItalic.125c7e6a.woff2) format("woff2"),url(./Inter-LightItalic.ec6c76a8.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:400;font-display:swap;src:url(./Inter-Regular.89d406b0.woff2) format("woff2"),url(./Inter-Regular.5b3a854b.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:400;font-display:swap;src:url(./Inter-Italic.bab4e808.woff2) format("woff2"),url(./Inter-Italic.7b187d57.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:500;font-display:swap;src:url(./Inter-Medium.5d308f3d.woff2) format("woff2"),url(./Inter-Medium.0fc5d904.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:500;font-display:swap;src:url(./Inter-MediumItalic.76551c20.woff2) format("woff2"),url(./Inter-MediumItalic.1458af9d.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:600;font-display:swap;src:url(./Inter-SemiBold.c7c3befe.woff2) format("woff2"),url(./Inter-SemiBold.04cd699f.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:600;font-display:swap;src:url(./Inter-SemiBoldItalic.d376ade4.woff2) format("woff2"),url(./Inter-SemiBoldItalic.420db54a.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:700;font-display:swap;src:url(./Inter-Bold.6f5e9a23.woff2) format("woff2"),url(./Inter-Bold.20d46cff.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:700;font-display:swap;src:url(./Inter-BoldItalic.e09dcbe1.woff2) format("woff2"),url(./Inter-BoldItalic.31a185fa.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:800;font-display:swap;src:url(./Inter-ExtraBold.0ef4267e.woff2) format("woff2"),url(./Inter-ExtraBold.45bae435.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:800;font-display:swap;src:url(./Inter-ExtraBoldItalic.d1e1f6a0.woff2) format("woff2"),url(./Inter-ExtraBoldItalic.30a1af87.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:900;font-display:swap;src:url(./Inter-Black.7f1f5616.woff2) format("woff2"),url(./Inter-Black.067c82f7.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:900;font-display:swap;src:url(./Inter-BlackItalic.72d5983b.woff2) format("woff2"),url(./Inter-BlackItalic.c628a2cf.woff) format("woff")}.Timeline_jumpDown{width:40px;height:40px;bottom:16px;right:32px;border-radius:100%;border:1px solid var(--background-color-secondary--darker-7);background-image:var(--icon-url-3);background-position:center;background-color:var(--background-color-primary--darker-10);background-repeat:no-repeat;cursor:pointer}.Timeline_message{display:grid;grid-template:"avatar sender" auto "avatar body" auto "time body" 1fr "time reactions" auto / 30px 1fr;column-gap:8px;padding:4px;margin:0 12px;box-sizing:border-box}.Timeline_message:not(.continuation){margin-top:4px}.ReplyPreviewView .Timeline_message{display:grid;grid-template:"body" auto;margin-left:0;padding:0}.ReplyPreviewView .Timeline_message:not(.continuation){margin-top:0}@media screen and (max-width: 800px){.Timeline_message{grid-template:"avatar sender" auto "body body" 1fr "time time" auto "reactions reactions" auto / 30px 1fr}.Timeline_messageSender{margin-top:0!important;align-self:center}}.Timeline_message:hover:not(.disabled),.Timeline_message.selected,.Timeline_message.menuOpen{background-color:#8d97a51a;border-radius:4px}.Timeline_message:hover>.Timeline_messageOptions,.Timeline_message.menuOpen>.Timeline_messageOptions{display:block;user-select:none}.Timeline_messageAvatar{grid-area:avatar;text-decoration:none}.Timeline_messageSender{grid-area:sender;font-weight:700;line-height:1.7rem}.Timeline_messageSender,.Timeline_messageBody{margin:0;word-break:break-all;word-break:break-word}.Timeline_message:not(.continuation) .Timeline_messageSender,.Timeline_message:not(.continuation) .Timeline_messageBody{margin-top:4px}.Timeline_messageOptions{display:none;grid-area:body;align-self:start;justify-self:end;margin-top:-12px;margin-right:4px;border:var(--background-color-primary--darker-10) 1px solid;height:24px;width:24px;background-color:var(--background-color-primary);color:inherit;border-radius:4px;padding:0;text-align:center;line-height:22px;cursor:pointer}.Timeline_messageTime{grid-area:time}.Timeline_messageBody time{padding:2px 0 0 10px;user-select:none}.Timeline_messageBody time,.Timeline_messageTime{font-size:.8em;line-height:normal;color:var(--timeline-time-text-color)}.Timeline_messageBody.statusMessage{font-style:italic;color:var(--light-text-color)}.Timeline_messageBody{grid-area:body;line-height:2.2rem;width:100%;min-width:0}.hydrogen .Timeline_messageSender.usercolor1{color:var(--usercolor1)}.hydrogen .Timeline_messageSender.usercolor2{color:var(--usercolor2)}.hydrogen .Timeline_messageSender.usercolor3{color:var(--usercolor3)}.hydrogen .Timeline_messageSender.usercolor4{color:var(--usercolor4)}.hydrogen .Timeline_messageSender.usercolor5{color:var(--usercolor5)}.hydrogen .Timeline_messageSender.usercolor6{color:var(--usercolor6)}.hydrogen .Timeline_messageSender.usercolor7{color:var(--usercolor7)}.hydrogen .Timeline_messageSender.usercolor8{color:var(--usercolor8)}.Timeline_messageBody h1,.Timeline_messageBody h2,.Timeline_messageBody h3,.Timeline_messageBody h4,.Timeline_messageBody h5,.Timeline_messageBody h6{font-weight:700;margin:.7em 0}.Timeline_messageBody h1{font-size:1.6em}.Timeline_messageBody h2{font-size:1.5em}.Timeline_messageBody h3{font-size:1.4em}.Timeline_messageBody h4{font-size:1.3em}.Timeline_messageBody h5{font-size:1.2em}.Timeline_messageBody h6{font-size:1.1em}.Timeline_messageBody a{word-break:break-all}.Timeline_messageBody a.link{color:var(--link-color);text-decoration:none}.Timeline_messageBody .media{display:grid;margin-top:4px;width:100%}.Timeline_messageBody .media>a{text-decoration:none;width:100%;display:block}.Timeline_messageBody .media>*{grid-row:1;grid-column:1}.Timeline_messageBody .media img,.Timeline_messageBody .media video{width:100%;height:auto;align-self:start;border-radius:4px;display:block}.hydrogen:not(.legacy) .Timeline_messageBody .media img,.hydrogen:not(.legacy) .Timeline_messageBody .media video{align-self:stretch}.Timeline_messageBody .media>.status{align-self:end;justify-self:start;font-size:.8em}.Timeline_messageBody .media>progress{align-self:center;justify-self:center;width:75%}.Timeline_messageBody .media>time{align-self:end;justify-self:end}.Timeline_messageBody .media>time,.Timeline_messageBody .media>.status{color:var(--text-color);display:block;padding:2px;margin:4px;background-color:#ffffffbf;border-radius:4px}.Timeline_messageBody .media>.spacer{width:100%;align-self:start}.Timeline_messageBody code,.Timeline_messageBody pre{background-color:var(--background-color-secondary);font-family:monospace;font-size:.9em}.Timeline_messageBody code{border-radius:3px;padding:.2em .3em;margin:0}.Timeline_messageBody pre{border:1px solid var(--light-border);padding:.5em;max-height:30em;overflow:auto}.Timeline_messageBody pre>code{background-color:unset;border-radius:unset;display:block;font-size:unset}.Timeline_messageBody blockquote{margin-left:0;padding-left:20px;border-left:4px solid var(--light-border)}.Timeline_messageBody table{border:1px solid var(--background-color-secondary--darker-15);border-radius:2px;border-spacing:0}.Timeline_messageBody thead th{border-bottom:1px solid var(--background-color-secondary--darker-15)}.Timeline_messageBody td,.Timeline_messageBody th{padding:2px 5px}.Timeline_messageBody tbody tr:nth-child(2n){background-color:var(--background-color-secondary)}.Timeline_messageBody .pill{padding:0 5px;border-radius:15px;background-color:var(--background-color-secondary);border:1px solid var(--background-color-secondary--darker-10);text-decoration:none;display:inline-flex;align-items:center;line-height:2rem;vertical-align:top;margin:1px}.Timeline_messageBody .pill div.avatar{display:inline-block;margin-right:3px}.Timeline_message.unsent .Timeline_messageBody{color:var(--light-text-color)}.Timeline_message.unverified .Timeline_messageBody{color:var(--error-color)}.Timeline_messageReactions{grid-area:reactions;margin-top:6px}.Timeline_messageReactions button{display:inline-flex;line-height:2rem;margin-right:6px;padding:1px 6px;border:1px solid var(--light-border);border-radius:10px;background-color:var(--background-color-secondary);color:inherit;cursor:pointer;user-select:none;vertical-align:middle}.Timeline_messageReactions button.active{background-color:var(--accent-color--alpha-11);border-color:var(--accent-color)}@keyframes glow-reaction-border{0%{border-color:var(--background-color-secondary)}to{border-color:var(--accent-color)}}.Timeline_messageReactions button.active.pending{animation-name:glow-reaction-border;animation-duration:.5s;animation-direction:alternate;animation-iteration-count:infinite;animation-timing-function:linear}.Timeline_locationLink{padding:0 8px;border-radius:16px;border:1px solid var(--light-border);background-color:var(--background-color-secondary);text-decoration:none;display:inline-block;line-height:2rem;vertical-align:top;margin:1px 4px}.AnnouncementView{margin:5px 0;padding:5px 10%}.AnnouncementView>div{margin:0 auto;padding:10px 20px;background-color:var(--background-color-secondary);text-align:center;border-radius:10px}.GapView_container>:not(:first-child){margin-left:12px}.GapView{padding:52px 20px}.GapView.isAtTop{padding:52px 20px 12px}.DateHeader{font-weight:700;font-size:1.5rem;position:sticky;top:5px}.DateHeader time{margin:0 auto;max-width:350px;padding:12px;display:block;color:var(--light-text-color);background-color:var(--background-color-primary);border-radius:8px;text-align:center}.CallTileView>div>div{display:flex;flex-direction:column;gap:4px}.CallTileView_members>*{margin-right:-16px}.CallTileView_members{display:flex}.CallTileView_title{font-weight:700}.CallTileView_subtitle{font-size:12px}.CallTileView_memberCount:before{content:"";background-image:var(--icon-url-4);background-repeat:no-repeat;background-size:16px 16px;width:16px;height:16px;display:inline-flex;vertical-align:bottom;margin-right:4px}.CallView{height:40vh;display:grid}.CallView>*{grid-column:1;grid-row:1}.CallView_error{align-self:start;justify-self:center;margin:16px;z-index:1}.CallView_members{display:grid;gap:12px;background:var(--background-color-secondary--darker-5);padding:12px;margin:0;min-height:0;list-style:none;align-self:stretch}.StreamView{display:grid;border-radius:8px;overflow:hidden;background-color:#000}.StreamView>*{grid-column:1;grid-row:1}.StreamView video{width:100%;height:100%;min-height:0;object-fit:contain}.StreamView_avatar{align-self:center;justify-self:center}.StreamView_error{align-self:start;justify-self:center;z-index:1}.StreamView_muteStatus{align-self:start;justify-self:end;width:24px;height:24px;background-position:center;background-repeat:no-repeat;background-size:14px;display:block;background-color:var(--text-color);border-radius:4px;margin:4px}.StreamView_muteStatus.microphoneMuted{background-image:var(--icon-url-5)}.StreamView_muteStatus.cameraMuted{background-image:var(--icon-url-6)}.CallView_buttons{align-self:end;justify-self:center;display:flex;gap:12px;margin-bottom:16px;z-index:1}.CallView_buttons button{border-radius:100%;width:48px;height:48px;border:none;background-color:var(--accent-color);background-position:center;background-repeat:no-repeat}.CallView_buttons button:disabled{background-color:var(--accent-color--lighter-10)}.CallView_buttons .CallView_hangup{background-color:var(--error-color);background-image:var(--icon-url-7)}.CallView_buttons .CallView_hangup:disabled{background-color:var(--error-color--lighter-10)}.CallView_buttons .CallView_mutedMicrophone{background-color:var(--background-color-primary);background-image:var(--icon-url-8)}.CallView_buttons .CallView_unmutedMicrophone{background-image:var(--icon-url-9)}.CallView_buttons .CallView_mutedCamera{background-color:var(--background-color-primary);background-image:var(--icon-url-10)}.CallView_buttons .CallView_unmutedCamera{background-image:var(--icon-url-11)}.CallView_members.size1{grid-template-columns:1fr;grid-template-rows:1fr}.CallView_members.size2{grid-template-columns:1fr;grid-template-rows:repeat(2,1fr)}.CallView_members.square.size3,.CallView_members.square.size4{grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,1fr)}.CallView_members.square.size5,.CallView_members.square.size6{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr)}.CallView_members.square.size7,.CallView_members.square.size8,.CallView_members.square.size9{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr)}.CallView_members.square.size10{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr)}.CallView_members.tall.size3{grid-template-columns:1fr;grid-template-rows:repeat(3,1fr)}.CallView_members.tall.size4{grid-template-columns:1fr;grid-template-rows:repeat(4,1fr)}.CallView_members.tall.size5,.CallView_members.tall.size6{grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.tall.size7,.CallView_members.tall.size8{grid-template-rows:repeat(4,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.tall.size9,.CallView_members.tall.size10{grid-template-rows:repeat(5,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.wide.size2{grid-template-columns:repeat(2,1fr);grid-template-rows:1fr}.CallView_members.wide.size3{grid-template-rows:1fr;grid-template-columns:repeat(3,1fr)}.CallView_members.wide.size4{grid-template-rows:1fr;grid-template-columns:repeat(4,1fr)}.CallView_members.wide.size5,.CallView_members.wide.size6{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(3,1fr)}.CallView_members.wide.size7,.CallView_members.wide.size8{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(4,1fr)}.CallView_members.wide.size9,.CallView_members.wide.size10{grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(4,1fr)}.ErrorView_block{background:var(--error-color);color:var(--fixed-white);margin:16px}.ErrorView.ErrorView_inline{color:var(--error-color);margin:4px 0;padding:4px 0}.ErrorView.ErrorView_inline>p{margin:0}.ErrorView{font-weight:700;margin:16px;border-radius:8px;padding:12px;display:flex;gap:8px}.ErrorView_message{flex-basis:0;flex-grow:1;margin:0;word-break:break-all;word-break:break-word;align-self:center}.ErrorView_submit{align-self:end}.ErrorView_close{align-self:start;width:16px;height:16px;border:none;background:none;background-repeat:no-repeat;background-size:contain;cursor:pointer}.ErrorView_block .ErrorView_close{background-image:var(--icon-url-12)}.ErrorView_inline .ErrorView_close{background-image:var(--icon-url-13)}:root{font-size:10px;--icon-color: var(--background-color-secondary--darker-40);--light-border: var(--background-color-secondary--darker-5);--light-text-color: var(--background-color-secondary--darker-55);--timeline-time-text-color: var(--background-color-secondary--darker-35);--icon-background: var(--background-color-secondary--darker-7);--right-panel-text-color: var(--background-color-secondary--darker-35)}.hydrogen{font-family:Inter,sans-serif,"emoji";background-color:var(--background-color-primary);color:var(--text-color);font-size:1.4rem;--usercolor1: #368BD6;--usercolor2: #AC3BA8;--usercolor3: #03B381;--usercolor4: #E64F7A;--usercolor5: #FF812D;--usercolor6: #2DC2C5;--usercolor7: #5C56F5;--usercolor8: #74D12C}.hydrogen button{font-family:inherit}.avatar{border-radius:100%;background:var(--background-color-primary);color:var(--fixed-white)}.hydrogen .avatar.usercolor1{background-color:var(--usercolor1)}.hydrogen .avatar.usercolor2{background-color:var(--usercolor2)}.hydrogen .avatar.usercolor3{background-color:var(--usercolor3)}.hydrogen .avatar.usercolor4{background-color:var(--usercolor4)}.hydrogen .avatar.usercolor5{background-color:var(--usercolor5)}.hydrogen .avatar.usercolor6{background-color:var(--usercolor6)}.hydrogen .avatar.usercolor7{background-color:var(--usercolor7)}.hydrogen .avatar.usercolor8{background-color:var(--usercolor8)}.logo{height:48px;min-width:48px;background-image:var(--icon-url-14);background-repeat:no-repeat;background-position:center}.button-row{display:flex}.button-row>*{margin-right:10px}.button-row>*:last-child{margin-right:0}.button-row .button-action{margin:10px 0;flex:1 0 auto}.form-row.text textarea{font-family:Inter,sans-serif;background-color:var(--background-color-secondary);color:inherit}.form-group{margin:24px 0}.form-row{margin:12px 0}.form-row.text>input,.form-row.text>textarea{padding:12px;border:1px solid var(--light-border);border-radius:8px;margin-top:5px;font-size:1em;resize:vertical;background-color:var(--background-color-secondary);color:inherit}.form-row.check{display:flex;align-items:baseline;gap:4px}.form-row.text>label,.form-row.text>input{display:block}.form-row .form-row-description{font-size:1rem;color:var(--light-text-color);margin:8px 0 0}.button-action{cursor:pointer}a.button-action{text-decoration:none;text-align:center;display:block}.button-action.secondary{color:var(--accent-color)}.button-action.primary{background-color:var(--accent-color);border-radius:8px;color:var(--fixed-white);font-weight:700}.button-action.primary:disabled{color:var(--fixed-white--darker-10)}.button-action.primary.destructive{background-color:var(--error-color)}.button-action.secondary.destructive{color:var(--error-color)}.button-action{border:none;padding:10px;background:none;font-weight:500}.button-utility{cursor:pointer;width:32px;height:32px;background-position:center;background-color:var(--icon-background);background-repeat:no-repeat;border:none;border-radius:100%;display:block}.button-utility.grid{background-image:var(--icon-url-15)}.button-utility.settings{background-image:var(--icon-url-16)}.button-utility.create{background-image:var(--icon-url-17)}.button-utility.grid.on{background-image:var(--icon-url-18)}.FilterField{background-image:var(--icon-url-19);background-repeat:no-repeat;background-position:8px center;background-color:var(--icon-background);border:1px solid transparent;border-radius:16px;height:32px;align-items:center;padding-left:30px;box-sizing:border-box}.FilterField:focus-within{border:1px var(--icon-background) solid;background-color:var(--background-color-primary)}.FilterField:focus-within button{border-color:var(--background-color-primary)}.FilterField input{font-family:Inter;font-size:1.3rem;font-weight:500;line-height:1.573rem;outline:none;border:none;background-color:transparent;height:100%;color:var(--text-color)}.FilterField button{width:30px;height:30px;background-position:center;background-color:var(--icon-background);background-repeat:no-repeat;background-image:var(--icon-url-20);border:7px solid transparent;border-radius:100%;box-sizing:border-box}.PreSessionScreen{padding:30px}.PreSessionScreen h1{font-size:16px;text-align:center}.SessionLoadView{padding-top:16px}.StartSSOLoginView_button{border:1px solid var(--accent-color);border-radius:8px}.LoginView_back{background-image:var(--icon-url-21);background-color:transparent}.LoginView_separator{font-weight:500;font-size:1.5rem}.LoginView_forwardInfo{font-size:.9em;margin-left:1em;color:var(--light-text-color)}.CompleteSSOView_title{font-weight:500}@media screen and (min-width: 600px){.PreSessionScreen{box-shadow:0 6px 32px #0000001a;border-radius:8px}}.PreSessionScreen .logo{height:48px;min-width:48px}.LeftPanel{background:var(--background-color-secondary);font-size:1.5rem;padding:12px 8px 0}.LeftPanel>:not(:first-child){margin-top:12px}.LeftPanel .utilities>:not(:first-child){margin-left:8px}.LeftPanel .filter{border-bottom:1px solid var(--background-color-secondary)}.LeftPanel .filter input{padding:.8em;border:none}.LeftPanel .RoomList{padding:0 8px 0 0;margin-right:-8px}.RoomList>li{margin:0;padding:4px 8px 4px 0;align-items:center}.RoomList>li>a{text-decoration:none;align-items:center}.RoomList li:not(:first-child){margin-top:4px}.RoomList li.active{background:var(--background-color-secondary--darker-7);border-radius:5px}.RoomList li>a>*{margin-right:8px}.RoomList .description{align-items:center}.RoomList .name.unread{font-weight:600}.RoomList .badge{min-width:1.6rem;height:1.6rem;border-radius:1.6rem;box-sizing:border-box;padding:.1rem .3rem;background-color:var(--room-badge);color:var(--fixed-white);font-weight:700;font-size:1rem;line-height:1.4rem;text-align:center}.RoomList .badge.highlighted{background-color:var(--error-color)}a{color:inherit}.SessionStatusView{padding:4px;min-height:22px;background-color:var(--accent-color);color:var(--fixed-white);align-items:center}.SessionStatusView button.link{color:currentcolor;text-align:left}.SessionStatusView>.end{flex:1 1;display:flex;justify-content:flex-end;align-self:stretch;align-items:stretch}.SessionStatusView .dismiss{border:none;background:none;background-image:var(--icon-url-22);background-position:center;background-repeat:no-repeat;width:32px;cursor:pointer}.room-placeholder{align-items:center;justify-content:center;text-align:center;padding:20px}.SessionPickerView li{font-size:1.2em}.SessionPickerView .session-info{text-decoration:none;padding:12px;border:1px solid var(--light-border);border-radius:8px;background-image:var(--icon-url-23);background-position:center right 30px;background-repeat:no-repeat;font-weight:500}.SessionPickerView .session-actions{margin:10px 0 20px;display:flex}.SessionPickerView .session-actions>*{margin-right:10px}.SessionPickerView .session-actions>*:last-child{margin-right:0}.SessionPickerView .session-actions button{border:none;background:none;color:inherit}.SessionPickerView button.destructive{color:var(--error-color)}.RoomGridView>div.container{border-right:1px solid var(--background-color-secondary);border-bottom:1px solid var(--background-color-secondary)}.RoomGridView>.focused>.room-placeholder .unfocused{display:none}.RoomGridView>:not(.focused)>.room-placeholder .focused{display:none}.room-placeholder .unfocused{color:var(--right-panel-text-color)}.RoomGridView>div.focus-ring{border:2px solid var(--accent-color--darker-5);border-radius:12px}.middle-header{box-sizing:border-box;flex:0 0 56px;background:var(--background-color-primary);padding:0 16px;border-bottom:1px solid var(--background-color-secondary)}.middle-header h2{font-size:1.8rem;font-weight:600}.middle-header>:not(:last-child){margin-right:8px}.close-middle,.close-session{background-image:var(--icon-url-24);background-position-x:10px}.RoomHeader .topic{font-size:14rem}.RoomHeader .room-options{background-image:var(--icon-url-25)}.RoomView_error{color:var(--error-color);background:#efefef;height:0px;font-weight:700;transition:.25s all ease-out;padding-right:20px;padding-left:20px}.RoomView_error div{overflow:hidden;height:100%;width:100%;position:relative;display:flex;align-items:center}.RoomView_error:not(:empty){height:auto;padding-top:20px;padding-bottom:20px}.RoomView_error p{position:relative;display:block;width:100%;height:auto;margin:0}.RoomView_error button{width:40px;padding-top:20px;padding-bottom:20px;background:none;border:none;position:relative;border-radius:5px;transition:.1s all ease-out;cursor:pointer}.RoomView_error button:hover{background:#cfcfcf}.RoomView_error button:before{content:"\274c";position:absolute;top:15px;left:9px;width:20px;height:10px;font-size:10px;align-self:middle}.MessageComposer_replyPreview .Timeline_message{margin:5px 0 0;max-height:30vh;overflow:auto}.MessageComposer_replyPreview{background:var(--background-color-secondary);margin:0 10px 10px;box-shadow:0 0 5px var(--background-color-secondary--darker-15);border-radius:5px}.MessageComposer_input,.MessageComposer_replyPreview{padding:8px}.MessageComposer_replyPreview>.replying{display:inline-flex;flex-direction:row;align-items:center;font-weight:700}.MessageComposer_replyPreview>button.cancel{width:32px;height:32px;display:block;border:none;text-indent:200%;white-space:nowrap;overflow:hidden;background-color:transparent;background-image:var(--icon-url-26);background-repeat:no-repeat;background-position:center;background-size:18px;cursor:pointer}.MessageComposer_input:first-child{border-top:1px solid var(--background-color-secondary)}.MessageComposer_input>:not(:first-child){margin-left:12px}.MessageComposer_input>textarea{border:none;border-radius:24px;background:var(--background-color-secondary);color:inherit;font-size:14px;font-family:Inter,sans-serif;resize:none;flex:1 1;padding:14px;box-sizing:border-box;overflow:hidden;max-height:113px;overflow-y:auto;overflow-y:overlay}.MessageComposer_input>button.send{width:32px;height:32px;display:block;border-radius:100%;border:none;text-indent:200%;overflow:hidden;background-color:var(--accent-color);background-image:var(--icon-url-27);background-repeat:no-repeat;background-position:center;align-self:end;margin-bottom:8px}.MessageComposer_input>button.sendFile{width:32px;height:32px;display:block;border:none;text-indent:200%;white-space:nowrap;overflow:hidden;background-color:transparent;background-image:var(--icon-url-28);background-repeat:no-repeat;background-position:center}.MessageComposer.MessageComposer_canSend button.sendFile{display:none}.MessageComposer:not(.MessageComposer_canSend) button.send{display:none}.SettingsBody{padding:0 16px}.Settings h3{margin:16px 0 8px}.Settings p{max-width:700px}.Settings .row .label{font-weight:600}.Settings .row .label,.Settings .row .content{margin-top:4px;margin-bottom:4px}.Settings .row .content{margin-left:4px;flex:1 1}.Settings .row.code .content{font-family:monospace}.Settings .row .content button{display:inline-block;margin:0 8px}.Settings .row .content input[type=range]{width:100%;max-width:300px;min-width:160px}.Settings .row{margin:4px 0;display:flex;flex-wrap:wrap;align-items:center}.Settings .row .label{flex:0 0 200px;align-self:flex-start}.Settings .row .content p{margin:8px 0}.Settings .row .content p:first-child{margin-top:0}.Settings .row .content p:last-child{margin-bottom:0}.FeatureView{display:flex;gap:8px}.FeaturesView ul{list-style:none;padding:8px 16px}.FeaturesView input[type=checkbox]{align-self:start}.FeatureView h4{margin:0}.FeatureView p{margin:8px 0}.error{color:var(--error-color);font-weight:600}button.link{font-size:1em;border:none;text-decoration:underline;background:none;cursor:pointer;margin:-12px;padding:12px;color:inherit}.Settings a,.Settings .link{color:var(--accent-color);font-weight:600}.lightbox{background-color:#000000bf;display:grid;grid-template:"content close" auto "content details" 1fr / 1fr auto;color:var(--background-color-primary);padding:4px}@media (max-aspect-ratio: 1/1){.lightbox{grid-template:"close" auto "content" 1fr "details" auto / 1fr}.lightbox .details{width:100%!important}}.lightbox .picture{grid-area:content;background-size:contain;background-position:center;background-repeat:no-repeat;width:100%;height:100%;align-self:center;justify-self:center}.lightbox .loading{grid-area:content;align-self:center;justify-self:center;display:flex}.lightbox .loading>:not(:first-child){margin-left:8px}.lightbox .close{display:block;grid-area:close;justify-self:end;background-image:var(--icon-url-29);background-position:center;background-size:16px;background-repeat:no-repeat;width:16px;height:16px;padding:12px}.lightbox .details{grid-area:details;padding:12px;font-size:1.5rem;width:200px}.menu{border-radius:8px;box-shadow:2px 2px 10px #00000080;padding:4px;background-color:var(--background-color-primary);list-style:none;margin:0}.menu li{margin-bottom:10px}.menu .menu-item{color:var(--text-color)}.menu button{border-radius:4px;border:none;background-color:transparent;text-align:left;padding:8px 32px 8px 8px;font-size:1.5rem;height:24px;cursor:pointer}.menu .destructive button{color:var(--error-color)}.menu .quick-reactions{display:flex;padding:8px 32px 8px 8px}.menu .quick-reactions button{padding:2px 4px;text-align:center}.InviteView_body{display:flex;justify-content:space-around;align-items:center;flex:1 1;overflow:auto}.InviteView_invite{display:flex;width:100%;max-width:400px;flex-direction:column;padding:0 24px}.InviteView_roomProfile{display:grid;gap:4px;grid-template:"avatar name" auto "avatar description" 1fr / 72px 1fr;align-self:center;margin-bottom:24px}.InviteView_roomProfile h3{grid-area:name;margin:0}.InviteView_roomDescription{grid-area:description;font-size:1.2rem;margin:0;color:var(--light-text-color)}.InviteView_roomAvatar{grid-area:avatar}.InviteView_dmAvatar{align-self:center}.InviteView_inviter{text-align:center;margin:24px 0}.InviteView_inviter .avatar{display:inline-block;vertical-align:middle;margin-right:4px}.InviteView_buttonRow{margin:10px auto;max-width:200px;width:100%}.InviteView_buttonRow button{display:block;width:100%}.DisabledComposerView{padding:12px;background-color:var(--background-color-secondary)}.DisabledComposerView h3{margin:0}.UnknownRoomView_container{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.UnknownRoomView_body{height:100%;text-align:center;padding:16px;box-sizing:border-box}.UnknownRoomView h2{word-break:break-all;word-break:break-word}.UnknownRoomView button{max-width:200px;width:100%}.LoadingView{height:100%;width:100%}.LoadingView .spinner{margin-right:5px}.InvitePanelView{display:flex;flex-direction:column;justify-content:center;align-items:center}.InvitePanelView__form{margin-top:8px}.InvitePanelView__input{font-family:Inter;font-size:1.3rem;font-weight:500;line-height:1.573rem;outline:none;border:none;background-color:var(--icon-background);color:var(--text-color);height:32px;box-sizing:border-box;margin:5px;border-radius:16px;padding:15px;width:90%}.InvitePanelView__form,.InvitePanelView__btn{display:flex;flex-direction:column;justify-content:center;align-items:center}.InvitePanelView__btn{width:100px;height:30px;margin-top:8px}.InvitePanelView__heading{width:90%;text-align:center;margin:0}.RightPanelView{background:var(--background-color-secondary)}.RoomDetailsView{padding:0 16px 16px}.RoomDetailsView_id,.MemberDetailsView_id{color:var(--right-panel-text-color);font-size:12px}.RoomDetailsView_rows{margin-top:36px;width:100%}.RoomDetailsView_name h2,.MemberDetailsView_name h2{margin-bottom:4px;font-size:1.8rem}.RoomDetailsView_row{margin-bottom:20px;font-weight:500;font-size:15px;width:100%;background:none;border:none;padding:0}button.RoomDetailsView_row{cursor:pointer}button.RoomDetailsView_row:after{content:var(--icon-url-30);margin-left:12px}.RoomDetailsView_row:not(button):after{content:" ";width:19px}.RoomDetailsView_label:before{padding-right:16px;height:24px;width:20px}.RoomDetailsView_label{width:200px}.RoomDetailsView_value{color:var(--right-panel-text-color);flex:1 1}.MemberCount:before{content:var(--icon-url-31)}.EncryptionStatus:before{content:var(--icon-url-32)}.EncryptionIconView{width:52px;height:52px;border-radius:100%;background:var(--right-panel-text-color);border:3px solid var(--background-color-secondary);margin-left:-16px}.EncryptionIconView_encrypted,.EncryptionIconView_unencrypted{height:24px;width:24px}.EncryptionIconView_encrypted{content:var(--icon-url-33)}.EncryptionIconView_unencrypted{content:var(--icon-url-34)}.RightPanelView_buttons .button-utility{width:24px;height:24px}.RightPanelView_buttons .close{background-image:var(--icon-url-35)}.RightPanelView_buttons .back{background-image:var(--icon-url-36)}.MemberListView__list{padding-left:16px;padding-right:16px;margin:0}.MemberListView{display:flex;flex-direction:column;height:100%}.MemberListView__invite-container{display:flex;justify-content:center;align-items:center}.MemberListView__invite-btn{width:80%;height:32px;display:flex;justify-content:center;align-items:center}.MemberTileView{margin-bottom:8px;list-style:none}.MemberTileView a{text-decoration:none}.MemberTileView .avatar{margin-right:8px}.MemberTileView_name{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;flex:1 1}.MemberDetailsView_section{box-sizing:border-box;padding:16px;width:100%}.MemberDetailsView_label{font-size:12px;font-weight:600;color:var(--right-panel-text-color);text-transform:uppercase}.MemberDetailsView_value,.MemberDetailsView_options{margin-left:8px;margin-top:5px;font-size:12px}.MemberDetailsView_options{display:inline-flex;flex-direction:column}.MemberDetailsView_options a,.MemberDetailsView_options button{color:var(--accent-color);text-decoration:none;margin:0 0 3px;padding:0;border:none;background:none;cursor:pointer;text-align:left}.LazyListParent{overflow-y:auto}.LogoutScreen{height:100vh}.LogoutScreen .content{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.LogoutScreen .status{display:flex;gap:12px}.CreateRoomView_body,.JoinRoomView_body,.RoomBeingCreated_error{max-width:400px}.RoomBeingCreated_error{margin-top:48px}.centered-column{padding:0 12px;align-self:center;width:100%;box-sizing:border-box}.CreateRoomView_selectAvatar{border:none;background:none;cursor:pointer}.CreateRoomView_selectAvatarPlaceholder{width:64px;height:64px;border-radius:100%;background-color:var(--icon-background);background-image:var(--icon-url-37);background-repeat:no-repeat;background-position:center;background-size:36px}.JoinRoomView_status{display:flex;align-items:center;justify-content:center;margin-top:10px}.JoinRoomView_status .spinner{margin-right:5px}.ToastCollectionView{display:flex;position:fixed;flex-direction:column;z-index:1000;left:44px;top:52px}.ToastCollectionView ul{margin:0;padding:0}.VerificationToastNotificationView:not(:first-child),.CallToastNotificationView:not(:first-child){margin-top:12px}.VerificationToastNotificationView{display:flex;flex-direction:column}.CallToastNotificationView{display:grid;grid-template-rows:40px 1fr 1fr 48px;row-gap:4px}.VerificationToastNotificationView,.CallToastNotificationView{background-color:var(--background-color-secondary);border-radius:8px;color:var(--text-color);box-shadow:2px 2px 10px #00000080}.CallToastNotificationView{width:260px}.VerificationToastNotificationView{width:248px}.VerificationToastNotificationView__top{padding:8px;display:flex}.CallToastNotificationView__top{display:grid;grid-template-columns:auto 176px auto;align-items:center;justify-items:center}.VerificationToastNotificationView__dismiss-btn,.CallToastNotificationView__dismiss-btn{background:center var(--background-color-secondary--darker-5) var(--icon-url-38) no-repeat;border-radius:100%;height:15px;width:15px}.VerificationToastNotificationView__title,.CallToastNotificationView__name{font-weight:600;width:100%}.VerificationToastNotificationView__description{padding:8px}.CallToastNotificationView__description{margin-left:42px}.CallToastNotificationView__call-type:before{content:"";background-image:var(--icon-url-39);background-repeat:no-repeat;background-size:20px 20px;display:flex;width:20px;height:20px;padding-right:5px}.CallToastNotificationView__call-type:after{content:"";width:4px;height:4px;background-color:var(--text-color);border-radius:100%;align-self:center;margin:5px}.CallToastNotificationView__member-count:before{content:"";background-image:var(--icon-url-40);background-repeat:no-repeat;background-size:20px 20px;display:flex;width:20px;height:20px;padding-right:5px}.CallToastNotificationView__member-count,.CallToastNotificationView__call-type{display:flex;align-items:center}.CallToastNotificationView__info{display:flex;margin-left:42px}.CallToastNotificationView__action{display:flex;justify-content:end;margin-right:10px}.VerificationToastNotificationView__action{display:flex;justify-content:space-between;padding:8px}.CallToastNotificationView__action .button-action{width:100px;height:40px}.VerificationToastNotificationView__action .button-action{width:100px;height:32px;display:flex;align-items:center;justify-content:center}.VerifyEmojisView{width:100%}.VerificationCompleteView,.DeviceVerificationView,.SelectMethodView{display:flex;align-items:center;justify-content:center;flex-direction:column;width:100%}.SelectMethodView>div,.SelectMethodView__heading,.SelectMethodView__title{width:inherit;box-sizing:border-box}.VerificationCompleteView__heading,.VerifyEmojisView__heading,.SelectMethodView__heading,.MissingKeysView__heading,.WaitingForOtherUserView__heading{display:flex;align-items:center;gap:16px;flex-wrap:wrap;justify-content:center;padding:8px}.MissingKeysView__heading{text-align:center}.VerificationCompleteView>*,.SelectMethodView>*,.VerifyEmojisView>*,.WaitingForOtherUserView>*{padding:16px}.VerificationCancelledView__title,.VerificationCompleteView__title,.VerifyEmojisView__title,.SelectMethodView__title,.WaitingForOtherUserView__title{font-size:1.5em;text-align:center}.VerificationCompleteView__title,.VerifyEmojisView__title,.SelectMethodView__title,.WaitingForOtherUserView__title,.VerificationCancelledView__description,.MissingKeysView__description,.VerificationCompleteView__description,.VerifyEmojisView__description,.SelectMethodView__description,.WaitingForOtherUserView__description{text-align:center;margin:0}.VerificationCancelledView__actions,.MissingKeysView__actions,.SelectMethodView__actions,.VerifyEmojisView__actions,.WaitingForOtherUserView__actions{display:flex;justify-content:center;gap:12px;padding:16px}.EmojiCollection{display:flex;justify-content:center;gap:16px;flex-wrap:wrap}.EmojiContainer__emoji{font-size:3.2rem}.VerifyEmojisView__waiting,.EmojiContainer__name,.EmojiContainer__emoji{display:flex;justify-content:center;align-items:center}.EmojiContainer__name{font-weight:700}.VerifyEmojisView__waiting{gap:12px}.VerificationCompleteView__icon{background:var(--icon-url-41) no-repeat;background-size:contain;width:128px;height:128px}.SelectMethodView__name{overflow:hidden;text-overflow:ellipsis;width:100%;display:inline-block}.VerificationInProgressTileView,.VerificationCompletedTileView,.VerificationCancelledTileView,.VerificationReadyTileView{display:flex;gap:20px}.VerificationTileView__actions{display:flex;gap:16px}.VerificationTileView__description{display:flex;align-items:center;font-weight:700;font-size:1.4rem;color:var(--text-color);gap:4px;text-align:center}.VerificationInProgressTileView,.VerificationCompletedTileView,.VerificationCancelledTileView,.VerificationReadyTileView{background:var(--background-color-primary--darker-5);padding:8px;box-sizing:border-box;border-radius:8px}.VerificationTileView{display:flex;justify-content:center;padding:5px 10%;box-sizing:border-box}.VerificationInProgressTileView .VerificationTileView__shield,.VerificationReadyTileView .VerificationTileView__shield{background:var(--icon-url-42) no-repeat}.VerificationCompletedTileView .VerificationTileView__shield{background:var(--icon-url-43) no-repeat}.VerificationTileView__shield{width:20px;height:20px;display:flex;align-self:center}:root{--background-color-primary: #21262b;--background-color-secondary: #2D3239;--text-color: #fff;--accent-color: #03B381;--error-color: #FF4B55;--fixed-white: #fff;--room-badge: #61708b;--link-color: #238cf5}:root{--background-color-secondary--darker-7: #3d444d;--background-color-primary--darker-10: #374048;--background-color-secondary--darker-15: #4f5764;--background-color-secondary--darker-10: #444b56;--accent-color--alpha-11: rgba(3,179,129, .11);--background-color-secondary--darker-5: #383f47;--text-color--lighter-80: #333333;--accent-color--lighter-10: #02815d;--error-color--lighter-10: #ff1825;--background-color-secondary--darker-40: #8d97a5;--background-color-secondary--darker-55: #b8bec7;--background-color-secondary--darker-35: #7f8a9a;--fixed-white--darker-10: #ffffff;--accent-color--darker-5: #03cc93;--background-color-primary--darker-5: #2c3339}:root{--icon-url-0: url(./verification-error-3007923930.91f5da98.svg);--icon-url-1: url(./verified-3138359829.814d0123.svg);--icon-url-2: url(./encryption-status-2100926911.a90232b4.svg);--icon-url-3: url(./chevron-down-1956489915.3389f17f.svg);--icon-url-4: url(./room-members-871477030.90b799fe.svg);--icon-url-5: url(./mic-muted-2638557456.4d8c99b4.svg);--icon-url-6: url(./cam-muted-3489740486.a882d986.svg);--icon-url-7: url(./hangup-581771896.279a6adf.svg);--icon-url-8: url(./mic-muted-3642419863.228ee86f.svg);--icon-url-9: url(./mic-unmuted-211198830.1fde69c5.svg);--icon-url-10: url(./cam-muted-711199923.069dcf2b.svg);--icon-url-11: url(./cam-unmuted-2274150835.69bcdbc4.svg);--icon-url-12: url(./clear-2743697487.2f1a17f1.svg);--icon-url-13: url(./clear-2743697487.2f1a17f1.svg);--icon-url-14: url(./element-logo-1551909733.1d59f06a.svg);--icon-url-15: url(./enable-grid-2288309723.f83895c8.svg);--icon-url-16: url(./settings-878939771.57cf3680.svg);--icon-url-17: url(./plus-3937109722.5c243914.svg);--icon-url-18: url(./disable-grid-4240599831.c8dc25a1.svg);--icon-url-19: url(./search-261439583.1bffaca1.svg);--icon-url-20: url(./clear-4137897294.7b90e8df.svg);--icon-url-21: url(./chevron-left-2611498805.b5555a61.svg);--icon-url-22: url(./dismiss-2476348673.d0f98560.svg);--icon-url-23: url(./chevron-right-2390431650.ec9bf561.svg);--icon-url-24: url(./chevron-left-2611498805.b5555a61.svg);--icon-url-25: url(./vertical-ellipsis-487061581.e7709afd.svg);--icon-url-26: url(./clear-4137897294.7b90e8df.svg);--icon-url-27: url(./send-3413346515.b0fb8626.svg);--icon-url-28: url(./paperclip-3961996319.da562307.svg);--icon-url-29: url(./clear-2743697487.2f1a17f1.svg);--icon-url-30: url(./chevron-small-4098047679.489e66cc.svg);--icon-url-31: url(./room-members-3084360280.6f64aaef.svg);--icon-url-32: url(./encryption-status-3449529405.c200a9bb.svg);--icon-url-33: url(./e2ee-normal-1448349558.af8f5484.svg);--icon-url-34: url(./e2ee-disabled-1470792300.6863c16d.svg);--icon-url-35: url(./clear-4137897294.7b90e8df.svg);--icon-url-36: url(./chevron-thin-left-3078630092.d0d143e3.svg);--icon-url-37: url(./plus-3937109722.5c243914.svg);--icon-url-38: url(./clear-2743697487.2f1a17f1.svg);--icon-url-39: url(./video-call-2591082837.8f09bafc.svg);--icon-url-40: url(./room-members-2999414798.6534e8ec.svg);--icon-url-41: url(./verified-3138359829.814d0123.svg);--icon-url-42: url(./e2ee-normal-3923817510.8737e7ee.svg);--icon-url-43: url(./e2ee-normal-3127337641.2624a9c9.svg)} diff --git a/hydrogen/assets/theme-element-light.78427b5a.css b/hydrogen/assets/theme-element-light.78427b5a.css new file mode 100644 index 0000000..dbdb4ce --- /dev/null +++ b/hydrogen/assets/theme-element-light.78427b5a.css @@ -0,0 +1 @@ +@font-face{font-family:"emoji";src:local("Apple Color Emoji"),local("Segoe UI Emoji"),local("Segoe UI Symbol"),local("Noto Color Emoji"),local("Twemoji"),local("Twemoji Mozilla"),local("Android Emoji"),local("EmojiSymbols"),local("Symbola");unicode-range:U+1F300-1F5FF,U+1F600-1F64F,U+1F680-1F6FF,U+2600-26FF}html{height:100%}main{display:block}@media screen and (min-width: 600px){.PreSessionScreen{width:600px;box-sizing:border-box;margin:50px auto 0}}.room-placeholder{display:flex;flex-direction:row}.SessionView{position:fixed;height:100%;width:100%;display:grid;grid-template:"status status" auto "left middle" 1fr / 320px 1fr;min-height:0;min-width:0}.right-shown{grid-template:"status status status" auto "left middle right" 1fr / 320px 1fr 300px}.hydrogen.ios .SessionView{height:var(--ios-viewport-height, 100%);top:var(--ios-viewport-top, 0)}.middle .close-middle{display:none}@media screen and (max-width: 800px){.SessionView:not(.middle-shown):not(.right-shown){grid-template:"status" auto "left" 1fr / 1fr}.SessionView.middle-shown{grid-template:"status" auto "middle" 1fr / 1fr}.SessionView.right-shown{grid-template:"status" auto "right" 1fr / 1fr}.SessionView:not(.middle-shown):not(.right-shown) .room-placeholder{display:none}.SessionView.middle-shown .LeftPanel,.SessionView.right-shown .middle,.SessionView.right-shown .LeftPanel{display:none}.middle .close-middle{display:block!important}.LeftPanel .grid{display:none!important}.VerificationReadyTileView{flex-direction:column}.VerificationTileView__actions{justify-content:center}}.LeftPanel{grid-area:left;min-width:0;min-height:0}.room-placeholder,.middle{min-width:0;grid-area:middle;width:100%;min-height:0}.middle{display:flex;flex-direction:column}.SessionStatusView{grid-area:status}.lightbox{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1;box-sizing:border-box;height:100%}.RoomView_body{flex:1 1;min-height:0;min-width:0;display:flex;flex-direction:column;height:100%}.RoomView_body .Timeline,.RoomView_body .TimelineLoadingView{flex:1 0}.middle-header{display:flex}.RoomGridView{display:grid}.RoomGridView.layout3x2{grid-template:"t0 t1 t2" 1fr "t3 t4 t5" 1fr / 1fr 1fr 1fr}.RoomGridView>.tile0{grid-area:t0}.RoomGridView>.tile1{grid-area:t1}.RoomGridView>.tile2{grid-area:t2}.RoomGridView>.tile3{grid-area:t3}.RoomGridView>.tile4{grid-area:t4}.RoomGridView>.tile5{grid-area:t5}.RoomGridView>div{display:flex;min-width:0;min-height:0}.RoomGridView>div.focus-ring{z-index:1;pointer-events:none}.menu{position:absolute;z-index:2}.menu .menu-item{box-sizing:border-box;width:100%}.Settings{display:flex;flex-direction:column}.SettingsBody{min-height:0;overflow-y:auto}.LazyListParent{flex:1 1;flex-basis:0;margin-top:15px}.LoadingView{display:flex;justify-content:center;align-items:center}.vertical-layout{display:flex;flex-direction:row;align-items:center;gap:12px}.vertical-layout>.stretch{flex:1 0}.popupContainer{position:absolute;white-space:nowrap}.SessionPickerView{padding:.4em}.SessionPickerView ul{list-style:none;padding:0}.SessionPickerView li{margin:.4em 0}.SessionPickerView .session-info{cursor:pointer;display:flex;align-items:center}.SessionPickerView .session-info>:not(:first-child){margin-left:8px}.SessionPickerView li .user-id{flex:1 1;overflow:hidden;text-overflow:ellipsis}.SessionPickerView li .error{margin:0 20px}.PasswordLoginView{padding:0 .4em .4em}.SessionLoadStatusView>.status,.LoginView_query-spinner{display:flex;gap:12px}.SessionLoadStatusView>.status p,.LoginView_query-spinner p{flex:1 1;margin:0}.SessionLoadStatusView .spinner{--size: 20px}.StartSSOLoginView{display:flex;flex-direction:column;padding:0 .4em}.StartSSOLoginView_button{flex:1 1;margin-top:12px}.LoginView_separator{justify-content:center;display:flex;margin:8px}.CompleteSSOView_title{display:flex;justify-content:center}.LoginView_sso{padding:.4em .4em 0}.LeftPanel{display:flex;flex-direction:column}.LeftPanel .utilities{display:flex}.LeftPanel .utilities .FilterField{flex:1 1;min-width:0}.LeftPanel ul{list-style:none;padding:0;margin:0}.RoomList{flex:1 0;overflow-y:auto;overscroll-behavior:contain}.RoomList>li>a{display:flex;align-items:center}.RoomList .description{margin:0;flex:1 1;min-width:0;display:flex}.RoomList .description>.name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;flex:1 1}.RightPanelView{grid-area:right;min-height:0;min-width:0;display:flex;flex-direction:column}.RoomDetailsView,.MemberDetailsView{flex-direction:column;flex:1 1}.RoomDetailsView_avatar{display:flex}.RoomDetailsView_name h2,.MemberDetailsView_name h2{text-align:center}.MemberDetailsView_shield_container{display:flex;gap:4px}.MemberDetailsView_shield_red,.MemberDetailsView_shield_green,.MemberDetailsView_shield_black{background-size:contain;background-repeat:no-repeat;width:24px;height:24px;display:block;flex-shrink:0}.MemberDetailsView_shield_description{flex-grow:1;margin:0}.MemberDetailsView_shield_red{background-image:var(--icon-url-0)}.MemberDetailsView_shield_green{background-image:var(--icon-url-1)}.MemberDetailsView_shield_black{background-image:var(--icon-url-2)}.RoomDetailsView_label,.RoomDetailsView_row,.RoomDetailsView,.MemberDetailsView,.EncryptionIconView{display:flex;align-items:center;color:var(--text-color)}.RoomDetailsView_value{display:flex;justify-content:flex-end}.EncryptionIconView{justify-content:center}.RightPanelView_buttons{display:flex;justify-content:space-between;width:100%;box-sizing:border-box;padding:16px}.RightPanelView_buttons .hide{visibility:hidden}.MemberTileView a{display:flex;align-items:center}.middle-header{align-items:center}.middle-header h2{flex:1 1}.middle-header .room-description{flex:1 1;min-width:0}.RoomHeader .topic{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.RoomHeader .description{flex:1 1 auto;min-width:0}.middle-header h2{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin:0}.MessageComposer_replyPreview{display:grid;grid-template-columns:1fr auto}.MessageComposer_replyPreview .Timeline_message{grid-column:1/-1}.MessageComposer_input{display:flex;align-items:center}.MessageComposer_input>input{display:block;flex:1 1;min-width:0;box-sizing:border-box}.TimelineLoadingView{display:flex;align-items:center;justify-content:center}.TimelineLoadingView>:not(:first-child){margin-left:12px}.Timeline{display:flex;flex-direction:column;position:relative;min-height:0}.Timeline_jumpDown{position:absolute}.Timeline_scroller{overflow-y:scroll;overscroll-behavior-y:contain;overflow-anchor:none;padding:0;margin:0;position:relative;min-height:0;flex:1 0}.Timeline_scroller>ul{list-style:none;padding:1px 0;margin:0}.AnnouncementView{display:flex;align-items:center}.GapView_container{display:flex}.GapView_container>span{flex:1 1}.Timeline_messageBody img{max-width:400px;max-height:300px}.hydrogen{--avatar-size: 32px}.hydrogen .avatar{width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6);overflow:hidden;flex-shrink:0;user-select:none;text-align:center;speak:none}.hydrogen .avatar img{width:100%;height:100%;object-fit:cover}.hydrogen .avatar.size-128{--avatar-size: 128px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-96{--avatar-size: 96px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-64{--avatar-size: 64px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-52{--avatar-size: 52px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-30{--avatar-size: 30px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-24{--avatar-size: 24px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-12{--avatar-size: 12px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}@keyframes spinner{0%{transform:rotate(0);stroke-dasharray:0 0 10 90}45%{stroke-dasharray:0 0 90 10}75%{stroke-dasharray:0 50 50 0}to{transform:rotate(360deg);stroke-dasharray:10 90 0 0}}.hydrogen:not(.legacy) .spinner circle{transform-origin:50% 50%;animation-name:spinner;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear;stroke-dasharray:0 0 85 85;fill:none;stroke:currentcolor;stroke-width:12;stroke-linecap:butt}.hydrogen.legacy .spinner{display:inline-block;position:relative}.hydrogen.legacy .spinner div{box-sizing:border-box;display:block;position:absolute;padding:2px;border:2px solid currentcolor;border-radius:50%;animation:legacy-spinner 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:currentcolor transparent transparent transparent;width:var(--size);height:var(--size)}.hydrogen.legacy .spinner div:nth-child(1){animation-delay:-.45s}.hydrogen.legacy .spinner div:nth-child(2){animation-delay:-.3s}.hydrogen.legacy .spinner div:nth-child(3){animation-delay:-.15s}@keyframes legacy-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinner{--size: 20px;width:var(--size);height:var(--size)}.form-row.text>input,.form-row.text>textarea{display:block;width:100%;min-width:0;box-sizing:border-box}.FilterField{display:flex}.FilterField input{display:block;flex:1 1;min-width:0}.SessionStatusView{display:flex}.SessionStatusView p{margin:0 10px;word-break:break-all;word-break:break-word}body.hydrogen{overscroll-behavior:none;overflow:hidden}.hydrogen{margin:0}.hiddenWithLayout{visibility:hidden}.hidden{display:none!important}input::-ms-clear{display:none}@font-face{font-family:Inter;font-style:normal;font-weight:100;font-display:swap;src:url(./Inter-Thin.5d8e2ac4.woff2) format("woff2"),url(./Inter-Thin.5565b01e.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:100;font-display:swap;src:url(./Inter-ThinItalic.6b3ded18.woff2) format("woff2"),url(./Inter-ThinItalic.c413497b.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:200;font-display:swap;src:url(./Inter-ExtraLight.da47c335.woff2) format("woff2"),url(./Inter-ExtraLight.d7be68a4.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:200;font-display:swap;src:url(./Inter-ExtraLightItalic.b3f94cfe.woff2) format("woff2"),url(./Inter-ExtraLightItalic.762fa4d2.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:300;font-display:swap;src:url(./Inter-Light.0f7dfe72.woff2) format("woff2"),url(./Inter-Light.38326098.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:300;font-display:swap;src:url(./Inter-LightItalic.125c7e6a.woff2) format("woff2"),url(./Inter-LightItalic.ec6c76a8.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:400;font-display:swap;src:url(./Inter-Regular.89d406b0.woff2) format("woff2"),url(./Inter-Regular.5b3a854b.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:400;font-display:swap;src:url(./Inter-Italic.bab4e808.woff2) format("woff2"),url(./Inter-Italic.7b187d57.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:500;font-display:swap;src:url(./Inter-Medium.5d308f3d.woff2) format("woff2"),url(./Inter-Medium.0fc5d904.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:500;font-display:swap;src:url(./Inter-MediumItalic.76551c20.woff2) format("woff2"),url(./Inter-MediumItalic.1458af9d.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:600;font-display:swap;src:url(./Inter-SemiBold.c7c3befe.woff2) format("woff2"),url(./Inter-SemiBold.04cd699f.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:600;font-display:swap;src:url(./Inter-SemiBoldItalic.d376ade4.woff2) format("woff2"),url(./Inter-SemiBoldItalic.420db54a.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:700;font-display:swap;src:url(./Inter-Bold.6f5e9a23.woff2) format("woff2"),url(./Inter-Bold.20d46cff.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:700;font-display:swap;src:url(./Inter-BoldItalic.e09dcbe1.woff2) format("woff2"),url(./Inter-BoldItalic.31a185fa.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:800;font-display:swap;src:url(./Inter-ExtraBold.0ef4267e.woff2) format("woff2"),url(./Inter-ExtraBold.45bae435.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:800;font-display:swap;src:url(./Inter-ExtraBoldItalic.d1e1f6a0.woff2) format("woff2"),url(./Inter-ExtraBoldItalic.30a1af87.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:900;font-display:swap;src:url(./Inter-Black.7f1f5616.woff2) format("woff2"),url(./Inter-Black.067c82f7.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:900;font-display:swap;src:url(./Inter-BlackItalic.72d5983b.woff2) format("woff2"),url(./Inter-BlackItalic.c628a2cf.woff) format("woff")}.Timeline_jumpDown{width:40px;height:40px;bottom:16px;right:32px;border-radius:100%;border:1px solid var(--background-color-secondary--darker-7);background-image:var(--icon-url-3);background-position:center;background-color:var(--background-color-primary--darker-10);background-repeat:no-repeat;cursor:pointer}.Timeline_message{display:grid;grid-template:"avatar sender" auto "avatar body" auto "time body" 1fr "time reactions" auto / 30px 1fr;column-gap:8px;padding:4px;margin:0 12px;box-sizing:border-box}.Timeline_message:not(.continuation){margin-top:4px}.ReplyPreviewView .Timeline_message{display:grid;grid-template:"body" auto;margin-left:0;padding:0}.ReplyPreviewView .Timeline_message:not(.continuation){margin-top:0}@media screen and (max-width: 800px){.Timeline_message{grid-template:"avatar sender" auto "body body" 1fr "time time" auto "reactions reactions" auto / 30px 1fr}.Timeline_messageSender{margin-top:0!important;align-self:center}}.Timeline_message:hover:not(.disabled),.Timeline_message.selected,.Timeline_message.menuOpen{background-color:#8d97a51a;border-radius:4px}.Timeline_message:hover>.Timeline_messageOptions,.Timeline_message.menuOpen>.Timeline_messageOptions{display:block;user-select:none}.Timeline_messageAvatar{grid-area:avatar;text-decoration:none}.Timeline_messageSender{grid-area:sender;font-weight:700;line-height:1.7rem}.Timeline_messageSender,.Timeline_messageBody{margin:0;word-break:break-all;word-break:break-word}.Timeline_message:not(.continuation) .Timeline_messageSender,.Timeline_message:not(.continuation) .Timeline_messageBody{margin-top:4px}.Timeline_messageOptions{display:none;grid-area:body;align-self:start;justify-self:end;margin-top:-12px;margin-right:4px;border:var(--background-color-primary--darker-10) 1px solid;height:24px;width:24px;background-color:var(--background-color-primary);color:inherit;border-radius:4px;padding:0;text-align:center;line-height:22px;cursor:pointer}.Timeline_messageTime{grid-area:time}.Timeline_messageBody time{padding:2px 0 0 10px;user-select:none}.Timeline_messageBody time,.Timeline_messageTime{font-size:.8em;line-height:normal;color:var(--timeline-time-text-color)}.Timeline_messageBody.statusMessage{font-style:italic;color:var(--light-text-color)}.Timeline_messageBody{grid-area:body;line-height:2.2rem;width:100%;min-width:0}.hydrogen .Timeline_messageSender.usercolor1{color:var(--usercolor1)}.hydrogen .Timeline_messageSender.usercolor2{color:var(--usercolor2)}.hydrogen .Timeline_messageSender.usercolor3{color:var(--usercolor3)}.hydrogen .Timeline_messageSender.usercolor4{color:var(--usercolor4)}.hydrogen .Timeline_messageSender.usercolor5{color:var(--usercolor5)}.hydrogen .Timeline_messageSender.usercolor6{color:var(--usercolor6)}.hydrogen .Timeline_messageSender.usercolor7{color:var(--usercolor7)}.hydrogen .Timeline_messageSender.usercolor8{color:var(--usercolor8)}.Timeline_messageBody h1,.Timeline_messageBody h2,.Timeline_messageBody h3,.Timeline_messageBody h4,.Timeline_messageBody h5,.Timeline_messageBody h6{font-weight:700;margin:.7em 0}.Timeline_messageBody h1{font-size:1.6em}.Timeline_messageBody h2{font-size:1.5em}.Timeline_messageBody h3{font-size:1.4em}.Timeline_messageBody h4{font-size:1.3em}.Timeline_messageBody h5{font-size:1.2em}.Timeline_messageBody h6{font-size:1.1em}.Timeline_messageBody a{word-break:break-all}.Timeline_messageBody a.link{color:var(--link-color);text-decoration:none}.Timeline_messageBody .media{display:grid;margin-top:4px;width:100%}.Timeline_messageBody .media>a{text-decoration:none;width:100%;display:block}.Timeline_messageBody .media>*{grid-row:1;grid-column:1}.Timeline_messageBody .media img,.Timeline_messageBody .media video{width:100%;height:auto;align-self:start;border-radius:4px;display:block}.hydrogen:not(.legacy) .Timeline_messageBody .media img,.hydrogen:not(.legacy) .Timeline_messageBody .media video{align-self:stretch}.Timeline_messageBody .media>.status{align-self:end;justify-self:start;font-size:.8em}.Timeline_messageBody .media>progress{align-self:center;justify-self:center;width:75%}.Timeline_messageBody .media>time{align-self:end;justify-self:end}.Timeline_messageBody .media>time,.Timeline_messageBody .media>.status{color:var(--text-color);display:block;padding:2px;margin:4px;background-color:#ffffffbf;border-radius:4px}.Timeline_messageBody .media>.spacer{width:100%;align-self:start}.Timeline_messageBody code,.Timeline_messageBody pre{background-color:var(--background-color-secondary);font-family:monospace;font-size:.9em}.Timeline_messageBody code{border-radius:3px;padding:.2em .3em;margin:0}.Timeline_messageBody pre{border:1px solid var(--light-border);padding:.5em;max-height:30em;overflow:auto}.Timeline_messageBody pre>code{background-color:unset;border-radius:unset;display:block;font-size:unset}.Timeline_messageBody blockquote{margin-left:0;padding-left:20px;border-left:4px solid var(--light-border)}.Timeline_messageBody table{border:1px solid var(--background-color-secondary--darker-15);border-radius:2px;border-spacing:0}.Timeline_messageBody thead th{border-bottom:1px solid var(--background-color-secondary--darker-15)}.Timeline_messageBody td,.Timeline_messageBody th{padding:2px 5px}.Timeline_messageBody tbody tr:nth-child(2n){background-color:var(--background-color-secondary)}.Timeline_messageBody .pill{padding:0 5px;border-radius:15px;background-color:var(--background-color-secondary);border:1px solid var(--background-color-secondary--darker-10);text-decoration:none;display:inline-flex;align-items:center;line-height:2rem;vertical-align:top;margin:1px}.Timeline_messageBody .pill div.avatar{display:inline-block;margin-right:3px}.Timeline_message.unsent .Timeline_messageBody{color:var(--light-text-color)}.Timeline_message.unverified .Timeline_messageBody{color:var(--error-color)}.Timeline_messageReactions{grid-area:reactions;margin-top:6px}.Timeline_messageReactions button{display:inline-flex;line-height:2rem;margin-right:6px;padding:1px 6px;border:1px solid var(--light-border);border-radius:10px;background-color:var(--background-color-secondary);color:inherit;cursor:pointer;user-select:none;vertical-align:middle}.Timeline_messageReactions button.active{background-color:var(--accent-color--alpha-11);border-color:var(--accent-color)}@keyframes glow-reaction-border{0%{border-color:var(--background-color-secondary)}to{border-color:var(--accent-color)}}.Timeline_messageReactions button.active.pending{animation-name:glow-reaction-border;animation-duration:.5s;animation-direction:alternate;animation-iteration-count:infinite;animation-timing-function:linear}.Timeline_locationLink{padding:0 8px;border-radius:16px;border:1px solid var(--light-border);background-color:var(--background-color-secondary);text-decoration:none;display:inline-block;line-height:2rem;vertical-align:top;margin:1px 4px}.AnnouncementView{margin:5px 0;padding:5px 10%}.AnnouncementView>div{margin:0 auto;padding:10px 20px;background-color:var(--background-color-secondary);text-align:center;border-radius:10px}.GapView_container>:not(:first-child){margin-left:12px}.GapView{padding:52px 20px}.GapView.isAtTop{padding:52px 20px 12px}.DateHeader{font-weight:700;font-size:1.5rem;position:sticky;top:5px}.DateHeader time{margin:0 auto;max-width:350px;padding:12px;display:block;color:var(--light-text-color);background-color:var(--background-color-primary);border-radius:8px;text-align:center}.CallTileView>div>div{display:flex;flex-direction:column;gap:4px}.CallTileView_members>*{margin-right:-16px}.CallTileView_members{display:flex}.CallTileView_title{font-weight:700}.CallTileView_subtitle{font-size:12px}.CallTileView_memberCount:before{content:"";background-image:var(--icon-url-4);background-repeat:no-repeat;background-size:16px 16px;width:16px;height:16px;display:inline-flex;vertical-align:bottom;margin-right:4px}.CallView{height:40vh;display:grid}.CallView>*{grid-column:1;grid-row:1}.CallView_error{align-self:start;justify-self:center;margin:16px;z-index:1}.CallView_members{display:grid;gap:12px;background:var(--background-color-secondary--darker-5);padding:12px;margin:0;min-height:0;list-style:none;align-self:stretch}.StreamView{display:grid;border-radius:8px;overflow:hidden;background-color:#000}.StreamView>*{grid-column:1;grid-row:1}.StreamView video{width:100%;height:100%;min-height:0;object-fit:contain}.StreamView_avatar{align-self:center;justify-self:center}.StreamView_error{align-self:start;justify-self:center;z-index:1}.StreamView_muteStatus{align-self:start;justify-self:end;width:24px;height:24px;background-position:center;background-repeat:no-repeat;background-size:14px;display:block;background-color:var(--text-color);border-radius:4px;margin:4px}.StreamView_muteStatus.microphoneMuted{background-image:var(--icon-url-5)}.StreamView_muteStatus.cameraMuted{background-image:var(--icon-url-6)}.CallView_buttons{align-self:end;justify-self:center;display:flex;gap:12px;margin-bottom:16px;z-index:1}.CallView_buttons button{border-radius:100%;width:48px;height:48px;border:none;background-color:var(--accent-color);background-position:center;background-repeat:no-repeat}.CallView_buttons button:disabled{background-color:var(--accent-color--lighter-10)}.CallView_buttons .CallView_hangup{background-color:var(--error-color);background-image:var(--icon-url-7)}.CallView_buttons .CallView_hangup:disabled{background-color:var(--error-color--lighter-10)}.CallView_buttons .CallView_mutedMicrophone{background-color:var(--background-color-primary);background-image:var(--icon-url-8)}.CallView_buttons .CallView_unmutedMicrophone{background-image:var(--icon-url-9)}.CallView_buttons .CallView_mutedCamera{background-color:var(--background-color-primary);background-image:var(--icon-url-10)}.CallView_buttons .CallView_unmutedCamera{background-image:var(--icon-url-11)}.CallView_members.size1{grid-template-columns:1fr;grid-template-rows:1fr}.CallView_members.size2{grid-template-columns:1fr;grid-template-rows:repeat(2,1fr)}.CallView_members.square.size3,.CallView_members.square.size4{grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,1fr)}.CallView_members.square.size5,.CallView_members.square.size6{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr)}.CallView_members.square.size7,.CallView_members.square.size8,.CallView_members.square.size9{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr)}.CallView_members.square.size10{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr)}.CallView_members.tall.size3{grid-template-columns:1fr;grid-template-rows:repeat(3,1fr)}.CallView_members.tall.size4{grid-template-columns:1fr;grid-template-rows:repeat(4,1fr)}.CallView_members.tall.size5,.CallView_members.tall.size6{grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.tall.size7,.CallView_members.tall.size8{grid-template-rows:repeat(4,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.tall.size9,.CallView_members.tall.size10{grid-template-rows:repeat(5,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.wide.size2{grid-template-columns:repeat(2,1fr);grid-template-rows:1fr}.CallView_members.wide.size3{grid-template-rows:1fr;grid-template-columns:repeat(3,1fr)}.CallView_members.wide.size4{grid-template-rows:1fr;grid-template-columns:repeat(4,1fr)}.CallView_members.wide.size5,.CallView_members.wide.size6{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(3,1fr)}.CallView_members.wide.size7,.CallView_members.wide.size8{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(4,1fr)}.CallView_members.wide.size9,.CallView_members.wide.size10{grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(4,1fr)}.ErrorView_block{background:var(--error-color);color:var(--fixed-white);margin:16px}.ErrorView.ErrorView_inline{color:var(--error-color);margin:4px 0;padding:4px 0}.ErrorView.ErrorView_inline>p{margin:0}.ErrorView{font-weight:700;margin:16px;border-radius:8px;padding:12px;display:flex;gap:8px}.ErrorView_message{flex-basis:0;flex-grow:1;margin:0;word-break:break-all;word-break:break-word;align-self:center}.ErrorView_submit{align-self:end}.ErrorView_close{align-self:start;width:16px;height:16px;border:none;background:none;background-repeat:no-repeat;background-size:contain;cursor:pointer}.ErrorView_block .ErrorView_close{background-image:var(--icon-url-12)}.ErrorView_inline .ErrorView_close{background-image:var(--icon-url-13)}:root{font-size:10px;--icon-color: var(--background-color-secondary--darker-40);--light-border: var(--background-color-secondary--darker-5);--light-text-color: var(--background-color-secondary--darker-55);--timeline-time-text-color: var(--background-color-secondary--darker-35);--icon-background: var(--background-color-secondary--darker-7);--right-panel-text-color: var(--background-color-secondary--darker-35)}.hydrogen{font-family:Inter,sans-serif,"emoji";background-color:var(--background-color-primary);color:var(--text-color);font-size:1.4rem;--usercolor1: #368BD6;--usercolor2: #AC3BA8;--usercolor3: #03B381;--usercolor4: #E64F7A;--usercolor5: #FF812D;--usercolor6: #2DC2C5;--usercolor7: #5C56F5;--usercolor8: #74D12C}.hydrogen button{font-family:inherit}.avatar{border-radius:100%;background:var(--background-color-primary);color:var(--fixed-white)}.hydrogen .avatar.usercolor1{background-color:var(--usercolor1)}.hydrogen .avatar.usercolor2{background-color:var(--usercolor2)}.hydrogen .avatar.usercolor3{background-color:var(--usercolor3)}.hydrogen .avatar.usercolor4{background-color:var(--usercolor4)}.hydrogen .avatar.usercolor5{background-color:var(--usercolor5)}.hydrogen .avatar.usercolor6{background-color:var(--usercolor6)}.hydrogen .avatar.usercolor7{background-color:var(--usercolor7)}.hydrogen .avatar.usercolor8{background-color:var(--usercolor8)}.logo{height:48px;min-width:48px;background-image:var(--icon-url-14);background-repeat:no-repeat;background-position:center}.button-row{display:flex}.button-row>*{margin-right:10px}.button-row>*:last-child{margin-right:0}.button-row .button-action{margin:10px 0;flex:1 0 auto}.form-row.text textarea{font-family:Inter,sans-serif;background-color:var(--background-color-secondary);color:inherit}.form-group{margin:24px 0}.form-row{margin:12px 0}.form-row.text>input,.form-row.text>textarea{padding:12px;border:1px solid var(--light-border);border-radius:8px;margin-top:5px;font-size:1em;resize:vertical;background-color:var(--background-color-secondary);color:inherit}.form-row.check{display:flex;align-items:baseline;gap:4px}.form-row.text>label,.form-row.text>input{display:block}.form-row .form-row-description{font-size:1rem;color:var(--light-text-color);margin:8px 0 0}.button-action{cursor:pointer}a.button-action{text-decoration:none;text-align:center;display:block}.button-action.secondary{color:var(--accent-color)}.button-action.primary{background-color:var(--accent-color);border-radius:8px;color:var(--fixed-white);font-weight:700}.button-action.primary:disabled{color:var(--fixed-white--darker-10)}.button-action.primary.destructive{background-color:var(--error-color)}.button-action.secondary.destructive{color:var(--error-color)}.button-action{border:none;padding:10px;background:none;font-weight:500}.button-utility{cursor:pointer;width:32px;height:32px;background-position:center;background-color:var(--icon-background);background-repeat:no-repeat;border:none;border-radius:100%;display:block}.button-utility.grid{background-image:var(--icon-url-15)}.button-utility.settings{background-image:var(--icon-url-16)}.button-utility.create{background-image:var(--icon-url-17)}.button-utility.grid.on{background-image:var(--icon-url-18)}.FilterField{background-image:var(--icon-url-19);background-repeat:no-repeat;background-position:8px center;background-color:var(--icon-background);border:1px solid transparent;border-radius:16px;height:32px;align-items:center;padding-left:30px;box-sizing:border-box}.FilterField:focus-within{border:1px var(--icon-background) solid;background-color:var(--background-color-primary)}.FilterField:focus-within button{border-color:var(--background-color-primary)}.FilterField input{font-family:Inter;font-size:1.3rem;font-weight:500;line-height:1.573rem;outline:none;border:none;background-color:transparent;height:100%;color:var(--text-color)}.FilterField button{width:30px;height:30px;background-position:center;background-color:var(--icon-background);background-repeat:no-repeat;background-image:var(--icon-url-20);border:7px solid transparent;border-radius:100%;box-sizing:border-box}.PreSessionScreen{padding:30px}.PreSessionScreen h1{font-size:16px;text-align:center}.SessionLoadView{padding-top:16px}.StartSSOLoginView_button{border:1px solid var(--accent-color);border-radius:8px}.LoginView_back{background-image:var(--icon-url-21);background-color:transparent}.LoginView_separator{font-weight:500;font-size:1.5rem}.LoginView_forwardInfo{font-size:.9em;margin-left:1em;color:var(--light-text-color)}.CompleteSSOView_title{font-weight:500}@media screen and (min-width: 600px){.PreSessionScreen{box-shadow:0 6px 32px #0000001a;border-radius:8px}}.PreSessionScreen .logo{height:48px;min-width:48px}.LeftPanel{background:var(--background-color-secondary);font-size:1.5rem;padding:12px 8px 0}.LeftPanel>:not(:first-child){margin-top:12px}.LeftPanel .utilities>:not(:first-child){margin-left:8px}.LeftPanel .filter{border-bottom:1px solid var(--background-color-secondary)}.LeftPanel .filter input{padding:.8em;border:none}.LeftPanel .RoomList{padding:0 8px 0 0;margin-right:-8px}.RoomList>li{margin:0;padding:4px 8px 4px 0;align-items:center}.RoomList>li>a{text-decoration:none;align-items:center}.RoomList li:not(:first-child){margin-top:4px}.RoomList li.active{background:var(--background-color-secondary--darker-7);border-radius:5px}.RoomList li>a>*{margin-right:8px}.RoomList .description{align-items:center}.RoomList .name.unread{font-weight:600}.RoomList .badge{min-width:1.6rem;height:1.6rem;border-radius:1.6rem;box-sizing:border-box;padding:.1rem .3rem;background-color:var(--room-badge);color:var(--fixed-white);font-weight:700;font-size:1rem;line-height:1.4rem;text-align:center}.RoomList .badge.highlighted{background-color:var(--error-color)}a{color:inherit}.SessionStatusView{padding:4px;min-height:22px;background-color:var(--accent-color);color:var(--fixed-white);align-items:center}.SessionStatusView button.link{color:currentcolor;text-align:left}.SessionStatusView>.end{flex:1 1;display:flex;justify-content:flex-end;align-self:stretch;align-items:stretch}.SessionStatusView .dismiss{border:none;background:none;background-image:var(--icon-url-22);background-position:center;background-repeat:no-repeat;width:32px;cursor:pointer}.room-placeholder{align-items:center;justify-content:center;text-align:center;padding:20px}.SessionPickerView li{font-size:1.2em}.SessionPickerView .session-info{text-decoration:none;padding:12px;border:1px solid var(--light-border);border-radius:8px;background-image:var(--icon-url-23);background-position:center right 30px;background-repeat:no-repeat;font-weight:500}.SessionPickerView .session-actions{margin:10px 0 20px;display:flex}.SessionPickerView .session-actions>*{margin-right:10px}.SessionPickerView .session-actions>*:last-child{margin-right:0}.SessionPickerView .session-actions button{border:none;background:none;color:inherit}.SessionPickerView button.destructive{color:var(--error-color)}.RoomGridView>div.container{border-right:1px solid var(--background-color-secondary);border-bottom:1px solid var(--background-color-secondary)}.RoomGridView>.focused>.room-placeholder .unfocused{display:none}.RoomGridView>:not(.focused)>.room-placeholder .focused{display:none}.room-placeholder .unfocused{color:var(--right-panel-text-color)}.RoomGridView>div.focus-ring{border:2px solid var(--accent-color--darker-5);border-radius:12px}.middle-header{box-sizing:border-box;flex:0 0 56px;background:var(--background-color-primary);padding:0 16px;border-bottom:1px solid var(--background-color-secondary)}.middle-header h2{font-size:1.8rem;font-weight:600}.middle-header>:not(:last-child){margin-right:8px}.close-middle,.close-session{background-image:var(--icon-url-24);background-position-x:10px}.RoomHeader .topic{font-size:14rem}.RoomHeader .room-options{background-image:var(--icon-url-25)}.RoomView_error{color:var(--error-color);background:#efefef;height:0px;font-weight:700;transition:.25s all ease-out;padding-right:20px;padding-left:20px}.RoomView_error div{overflow:hidden;height:100%;width:100%;position:relative;display:flex;align-items:center}.RoomView_error:not(:empty){height:auto;padding-top:20px;padding-bottom:20px}.RoomView_error p{position:relative;display:block;width:100%;height:auto;margin:0}.RoomView_error button{width:40px;padding-top:20px;padding-bottom:20px;background:none;border:none;position:relative;border-radius:5px;transition:.1s all ease-out;cursor:pointer}.RoomView_error button:hover{background:#cfcfcf}.RoomView_error button:before{content:"\274c";position:absolute;top:15px;left:9px;width:20px;height:10px;font-size:10px;align-self:middle}.MessageComposer_replyPreview .Timeline_message{margin:5px 0 0;max-height:30vh;overflow:auto}.MessageComposer_replyPreview{background:var(--background-color-secondary);margin:0 10px 10px;box-shadow:0 0 5px var(--background-color-secondary--darker-15);border-radius:5px}.MessageComposer_input,.MessageComposer_replyPreview{padding:8px}.MessageComposer_replyPreview>.replying{display:inline-flex;flex-direction:row;align-items:center;font-weight:700}.MessageComposer_replyPreview>button.cancel{width:32px;height:32px;display:block;border:none;text-indent:200%;white-space:nowrap;overflow:hidden;background-color:transparent;background-image:var(--icon-url-26);background-repeat:no-repeat;background-position:center;background-size:18px;cursor:pointer}.MessageComposer_input:first-child{border-top:1px solid var(--background-color-secondary)}.MessageComposer_input>:not(:first-child){margin-left:12px}.MessageComposer_input>textarea{border:none;border-radius:24px;background:var(--background-color-secondary);color:inherit;font-size:14px;font-family:Inter,sans-serif;resize:none;flex:1 1;padding:14px;box-sizing:border-box;overflow:hidden;max-height:113px;overflow-y:auto;overflow-y:overlay}.MessageComposer_input>button.send{width:32px;height:32px;display:block;border-radius:100%;border:none;text-indent:200%;overflow:hidden;background-color:var(--accent-color);background-image:var(--icon-url-27);background-repeat:no-repeat;background-position:center;align-self:end;margin-bottom:8px}.MessageComposer_input>button.sendFile{width:32px;height:32px;display:block;border:none;text-indent:200%;white-space:nowrap;overflow:hidden;background-color:transparent;background-image:var(--icon-url-28);background-repeat:no-repeat;background-position:center}.MessageComposer.MessageComposer_canSend button.sendFile{display:none}.MessageComposer:not(.MessageComposer_canSend) button.send{display:none}.SettingsBody{padding:0 16px}.Settings h3{margin:16px 0 8px}.Settings p{max-width:700px}.Settings .row .label{font-weight:600}.Settings .row .label,.Settings .row .content{margin-top:4px;margin-bottom:4px}.Settings .row .content{margin-left:4px;flex:1 1}.Settings .row.code .content{font-family:monospace}.Settings .row .content button{display:inline-block;margin:0 8px}.Settings .row .content input[type=range]{width:100%;max-width:300px;min-width:160px}.Settings .row{margin:4px 0;display:flex;flex-wrap:wrap;align-items:center}.Settings .row .label{flex:0 0 200px;align-self:flex-start}.Settings .row .content p{margin:8px 0}.Settings .row .content p:first-child{margin-top:0}.Settings .row .content p:last-child{margin-bottom:0}.FeatureView{display:flex;gap:8px}.FeaturesView ul{list-style:none;padding:8px 16px}.FeaturesView input[type=checkbox]{align-self:start}.FeatureView h4{margin:0}.FeatureView p{margin:8px 0}.error{color:var(--error-color);font-weight:600}button.link{font-size:1em;border:none;text-decoration:underline;background:none;cursor:pointer;margin:-12px;padding:12px;color:inherit}.Settings a,.Settings .link{color:var(--accent-color);font-weight:600}.lightbox{background-color:#000000bf;display:grid;grid-template:"content close" auto "content details" 1fr / 1fr auto;color:var(--background-color-primary);padding:4px}@media (max-aspect-ratio: 1/1){.lightbox{grid-template:"close" auto "content" 1fr "details" auto / 1fr}.lightbox .details{width:100%!important}}.lightbox .picture{grid-area:content;background-size:contain;background-position:center;background-repeat:no-repeat;width:100%;height:100%;align-self:center;justify-self:center}.lightbox .loading{grid-area:content;align-self:center;justify-self:center;display:flex}.lightbox .loading>:not(:first-child){margin-left:8px}.lightbox .close{display:block;grid-area:close;justify-self:end;background-image:var(--icon-url-29);background-position:center;background-size:16px;background-repeat:no-repeat;width:16px;height:16px;padding:12px}.lightbox .details{grid-area:details;padding:12px;font-size:1.5rem;width:200px}.menu{border-radius:8px;box-shadow:2px 2px 10px #00000080;padding:4px;background-color:var(--background-color-primary);list-style:none;margin:0}.menu li{margin-bottom:10px}.menu .menu-item{color:var(--text-color)}.menu button{border-radius:4px;border:none;background-color:transparent;text-align:left;padding:8px 32px 8px 8px;font-size:1.5rem;height:24px;cursor:pointer}.menu .destructive button{color:var(--error-color)}.menu .quick-reactions{display:flex;padding:8px 32px 8px 8px}.menu .quick-reactions button{padding:2px 4px;text-align:center}.InviteView_body{display:flex;justify-content:space-around;align-items:center;flex:1 1;overflow:auto}.InviteView_invite{display:flex;width:100%;max-width:400px;flex-direction:column;padding:0 24px}.InviteView_roomProfile{display:grid;gap:4px;grid-template:"avatar name" auto "avatar description" 1fr / 72px 1fr;align-self:center;margin-bottom:24px}.InviteView_roomProfile h3{grid-area:name;margin:0}.InviteView_roomDescription{grid-area:description;font-size:1.2rem;margin:0;color:var(--light-text-color)}.InviteView_roomAvatar{grid-area:avatar}.InviteView_dmAvatar{align-self:center}.InviteView_inviter{text-align:center;margin:24px 0}.InviteView_inviter .avatar{display:inline-block;vertical-align:middle;margin-right:4px}.InviteView_buttonRow{margin:10px auto;max-width:200px;width:100%}.InviteView_buttonRow button{display:block;width:100%}.DisabledComposerView{padding:12px;background-color:var(--background-color-secondary)}.DisabledComposerView h3{margin:0}.UnknownRoomView_container{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.UnknownRoomView_body{height:100%;text-align:center;padding:16px;box-sizing:border-box}.UnknownRoomView h2{word-break:break-all;word-break:break-word}.UnknownRoomView button{max-width:200px;width:100%}.LoadingView{height:100%;width:100%}.LoadingView .spinner{margin-right:5px}.InvitePanelView{display:flex;flex-direction:column;justify-content:center;align-items:center}.InvitePanelView__form{margin-top:8px}.InvitePanelView__input{font-family:Inter;font-size:1.3rem;font-weight:500;line-height:1.573rem;outline:none;border:none;background-color:var(--icon-background);color:var(--text-color);height:32px;box-sizing:border-box;margin:5px;border-radius:16px;padding:15px;width:90%}.InvitePanelView__form,.InvitePanelView__btn{display:flex;flex-direction:column;justify-content:center;align-items:center}.InvitePanelView__btn{width:100px;height:30px;margin-top:8px}.InvitePanelView__heading{width:90%;text-align:center;margin:0}.RightPanelView{background:var(--background-color-secondary)}.RoomDetailsView{padding:0 16px 16px}.RoomDetailsView_id,.MemberDetailsView_id{color:var(--right-panel-text-color);font-size:12px}.RoomDetailsView_rows{margin-top:36px;width:100%}.RoomDetailsView_name h2,.MemberDetailsView_name h2{margin-bottom:4px;font-size:1.8rem}.RoomDetailsView_row{margin-bottom:20px;font-weight:500;font-size:15px;width:100%;background:none;border:none;padding:0}button.RoomDetailsView_row{cursor:pointer}button.RoomDetailsView_row:after{content:var(--icon-url-30);margin-left:12px}.RoomDetailsView_row:not(button):after{content:" ";width:19px}.RoomDetailsView_label:before{padding-right:16px;height:24px;width:20px}.RoomDetailsView_label{width:200px}.RoomDetailsView_value{color:var(--right-panel-text-color);flex:1 1}.MemberCount:before{content:var(--icon-url-31)}.EncryptionStatus:before{content:var(--icon-url-32)}.EncryptionIconView{width:52px;height:52px;border-radius:100%;background:var(--right-panel-text-color);border:3px solid var(--background-color-secondary);margin-left:-16px}.EncryptionIconView_encrypted,.EncryptionIconView_unencrypted{height:24px;width:24px}.EncryptionIconView_encrypted{content:var(--icon-url-33)}.EncryptionIconView_unencrypted{content:var(--icon-url-34)}.RightPanelView_buttons .button-utility{width:24px;height:24px}.RightPanelView_buttons .close{background-image:var(--icon-url-35)}.RightPanelView_buttons .back{background-image:var(--icon-url-36)}.MemberListView__list{padding-left:16px;padding-right:16px;margin:0}.MemberListView{display:flex;flex-direction:column;height:100%}.MemberListView__invite-container{display:flex;justify-content:center;align-items:center}.MemberListView__invite-btn{width:80%;height:32px;display:flex;justify-content:center;align-items:center}.MemberTileView{margin-bottom:8px;list-style:none}.MemberTileView a{text-decoration:none}.MemberTileView .avatar{margin-right:8px}.MemberTileView_name{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;flex:1 1}.MemberDetailsView_section{box-sizing:border-box;padding:16px;width:100%}.MemberDetailsView_label{font-size:12px;font-weight:600;color:var(--right-panel-text-color);text-transform:uppercase}.MemberDetailsView_value,.MemberDetailsView_options{margin-left:8px;margin-top:5px;font-size:12px}.MemberDetailsView_options{display:inline-flex;flex-direction:column}.MemberDetailsView_options a,.MemberDetailsView_options button{color:var(--accent-color);text-decoration:none;margin:0 0 3px;padding:0;border:none;background:none;cursor:pointer;text-align:left}.LazyListParent{overflow-y:auto}.LogoutScreen{height:100vh}.LogoutScreen .content{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.LogoutScreen .status{display:flex;gap:12px}.CreateRoomView_body,.JoinRoomView_body,.RoomBeingCreated_error{max-width:400px}.RoomBeingCreated_error{margin-top:48px}.centered-column{padding:0 12px;align-self:center;width:100%;box-sizing:border-box}.CreateRoomView_selectAvatar{border:none;background:none;cursor:pointer}.CreateRoomView_selectAvatarPlaceholder{width:64px;height:64px;border-radius:100%;background-color:var(--icon-background);background-image:var(--icon-url-37);background-repeat:no-repeat;background-position:center;background-size:36px}.JoinRoomView_status{display:flex;align-items:center;justify-content:center;margin-top:10px}.JoinRoomView_status .spinner{margin-right:5px}.ToastCollectionView{display:flex;position:fixed;flex-direction:column;z-index:1000;left:44px;top:52px}.ToastCollectionView ul{margin:0;padding:0}.VerificationToastNotificationView:not(:first-child),.CallToastNotificationView:not(:first-child){margin-top:12px}.VerificationToastNotificationView{display:flex;flex-direction:column}.CallToastNotificationView{display:grid;grid-template-rows:40px 1fr 1fr 48px;row-gap:4px}.VerificationToastNotificationView,.CallToastNotificationView{background-color:var(--background-color-secondary);border-radius:8px;color:var(--text-color);box-shadow:2px 2px 10px #00000080}.CallToastNotificationView{width:260px}.VerificationToastNotificationView{width:248px}.VerificationToastNotificationView__top{padding:8px;display:flex}.CallToastNotificationView__top{display:grid;grid-template-columns:auto 176px auto;align-items:center;justify-items:center}.VerificationToastNotificationView__dismiss-btn,.CallToastNotificationView__dismiss-btn{background:center var(--background-color-secondary--darker-5) var(--icon-url-38) no-repeat;border-radius:100%;height:15px;width:15px}.VerificationToastNotificationView__title,.CallToastNotificationView__name{font-weight:600;width:100%}.VerificationToastNotificationView__description{padding:8px}.CallToastNotificationView__description{margin-left:42px}.CallToastNotificationView__call-type:before{content:"";background-image:var(--icon-url-39);background-repeat:no-repeat;background-size:20px 20px;display:flex;width:20px;height:20px;padding-right:5px}.CallToastNotificationView__call-type:after{content:"";width:4px;height:4px;background-color:var(--text-color);border-radius:100%;align-self:center;margin:5px}.CallToastNotificationView__member-count:before{content:"";background-image:var(--icon-url-40);background-repeat:no-repeat;background-size:20px 20px;display:flex;width:20px;height:20px;padding-right:5px}.CallToastNotificationView__member-count,.CallToastNotificationView__call-type{display:flex;align-items:center}.CallToastNotificationView__info{display:flex;margin-left:42px}.CallToastNotificationView__action{display:flex;justify-content:end;margin-right:10px}.VerificationToastNotificationView__action{display:flex;justify-content:space-between;padding:8px}.CallToastNotificationView__action .button-action{width:100px;height:40px}.VerificationToastNotificationView__action .button-action{width:100px;height:32px;display:flex;align-items:center;justify-content:center}.VerifyEmojisView{width:100%}.VerificationCompleteView,.DeviceVerificationView,.SelectMethodView{display:flex;align-items:center;justify-content:center;flex-direction:column;width:100%}.SelectMethodView>div,.SelectMethodView__heading,.SelectMethodView__title{width:inherit;box-sizing:border-box}.VerificationCompleteView__heading,.VerifyEmojisView__heading,.SelectMethodView__heading,.MissingKeysView__heading,.WaitingForOtherUserView__heading{display:flex;align-items:center;gap:16px;flex-wrap:wrap;justify-content:center;padding:8px}.MissingKeysView__heading{text-align:center}.VerificationCompleteView>*,.SelectMethodView>*,.VerifyEmojisView>*,.WaitingForOtherUserView>*{padding:16px}.VerificationCancelledView__title,.VerificationCompleteView__title,.VerifyEmojisView__title,.SelectMethodView__title,.WaitingForOtherUserView__title{font-size:1.5em;text-align:center}.VerificationCompleteView__title,.VerifyEmojisView__title,.SelectMethodView__title,.WaitingForOtherUserView__title,.VerificationCancelledView__description,.MissingKeysView__description,.VerificationCompleteView__description,.VerifyEmojisView__description,.SelectMethodView__description,.WaitingForOtherUserView__description{text-align:center;margin:0}.VerificationCancelledView__actions,.MissingKeysView__actions,.SelectMethodView__actions,.VerifyEmojisView__actions,.WaitingForOtherUserView__actions{display:flex;justify-content:center;gap:12px;padding:16px}.EmojiCollection{display:flex;justify-content:center;gap:16px;flex-wrap:wrap}.EmojiContainer__emoji{font-size:3.2rem}.VerifyEmojisView__waiting,.EmojiContainer__name,.EmojiContainer__emoji{display:flex;justify-content:center;align-items:center}.EmojiContainer__name{font-weight:700}.VerifyEmojisView__waiting{gap:12px}.VerificationCompleteView__icon{background:var(--icon-url-41) no-repeat;background-size:contain;width:128px;height:128px}.SelectMethodView__name{overflow:hidden;text-overflow:ellipsis;width:100%;display:inline-block}.VerificationInProgressTileView,.VerificationCompletedTileView,.VerificationCancelledTileView,.VerificationReadyTileView{display:flex;gap:20px}.VerificationTileView__actions{display:flex;gap:16px}.VerificationTileView__description{display:flex;align-items:center;font-weight:700;font-size:1.4rem;color:var(--text-color);gap:4px;text-align:center}.VerificationInProgressTileView,.VerificationCompletedTileView,.VerificationCancelledTileView,.VerificationReadyTileView{background:var(--background-color-primary--darker-5);padding:8px;box-sizing:border-box;border-radius:8px}.VerificationTileView{display:flex;justify-content:center;padding:5px 10%;box-sizing:border-box}.VerificationInProgressTileView .VerificationTileView__shield,.VerificationReadyTileView .VerificationTileView__shield{background:var(--icon-url-42) no-repeat}.VerificationCompletedTileView .VerificationTileView__shield{background:var(--icon-url-43) no-repeat}.VerificationTileView__shield{width:20px;height:20px;display:flex;align-self:center}:root{--background-color-primary: #fff;--background-color-secondary: #f6f6f6;--text-color: #2E2F32;--accent-color: #03b381;--error-color: #FF4B55;--fixed-white: #fff;--room-badge: #61708b;--link-color: #238cf5}:root{--background-color-secondary--darker-7: #e4e4e4;--background-color-primary--darker-10: #e6e6e6;--background-color-secondary--darker-15: #d0d0d0;--background-color-secondary--darker-10: #dddddd;--accent-color--alpha-11: rgba(3,179,129, .11);--background-color-secondary--darker-5: #e9e9e9;--text-color--lighter-80: #fcfcfc;--accent-color--lighter-10: #04e5a5;--error-color--lighter-10: #ff7e85;--background-color-secondary--darker-40: #909090;--background-color-secondary--darker-55: #6a6a6a;--background-color-secondary--darker-35: #9d9d9d;--fixed-white--darker-10: #e6e6e6;--accent-color--darker-5: #039a6f;--background-color-primary--darker-5: #f2f2f2}:root{--icon-url-0: url(./verification-error-3007923930.91f5da98.svg);--icon-url-1: url(./verified-1676512664.5538d685.svg);--icon-url-2: url(./encryption-status-689620003.8086e625.svg);--icon-url-3: url(./chevron-down-3300400168.d1a083a1.svg);--icon-url-4: url(./room-members-3297708388.1a158fe2.svg);--icon-url-5: url(./mic-muted-2617055184.e8d1962f.svg);--icon-url-6: url(./cam-muted-2247331037.b0b2cf01.svg);--icon-url-7: url(./hangup-1798659826.d0cb8438.svg);--icon-url-8: url(./mic-muted-4213153786.513608a5.svg);--icon-url-9: url(./mic-unmuted-3178778883.b8f57412.svg);--icon-url-10: url(./cam-muted-1894081672.22150c2b.svg);--icon-url-11: url(./cam-unmuted-2215154474.a82b7bf1.svg);--icon-url-12: url(./clear-2743697487.2f1a17f1.svg);--icon-url-13: url(./clear-2203718389.37dd36a5.svg);--icon-url-14: url(./element-logo-703176763.fc54fc8d.svg);--icon-url-15: url(./enable-grid-2071838379.ab4f40c5.svg);--icon-url-16: url(./settings-2175246113.00804666.svg);--icon-url-17: url(./plus-4190356069.084c5e3d.svg);--icon-url-18: url(./disable-grid-3304422220.8a79cfcb.svg);--icon-url-19: url(./search-3263540198.1511780c.svg);--icon-url-20: url(./clear-426756705.361f7a30.svg);--icon-url-21: url(./chevron-left-3506338632.4e437777.svg);--icon-url-22: url(./clear-2743697487.2f1a17f1.svg);--icon-url-23: url(./chevron-right-847198822.23380c56.svg);--icon-url-24: url(./chevron-left-3506338632.4e437777.svg);--icon-url-25: url(./vertical-ellipsis-3416547705.f619a721.svg);--icon-url-26: url(./clear-426756705.361f7a30.svg);--icon-url-27: url(./send-1171052351.caa5c494.svg);--icon-url-28: url(./paperclip-2441131778.1f5e29f3.svg);--icon-url-29: url(./clear-2743697487.2f1a17f1.svg);--icon-url-30: url(./chevron-small-781914114.936b4943.svg);--icon-url-31: url(./room-members-3847743605.9fcf4567.svg);--icon-url-32: url(./encryption-status-475927392.2fedc0bd.svg);--icon-url-33: url(./e2ee-normal-1448349558.af8f5484.svg);--icon-url-34: url(./e2ee-disabled-1470792300.6863c16d.svg);--icon-url-35: url(./clear-426756705.361f7a30.svg);--icon-url-36: url(./chevron-thin-left-3831175135.13f60c05.svg);--icon-url-37: url(./plus-4190356069.084c5e3d.svg);--icon-url-38: url(./clear-2203718389.37dd36a5.svg);--icon-url-39: url(./video-call-3307702325.5e74dd9a.svg);--icon-url-40: url(./room-members-1680968332.b4f57622.svg);--icon-url-41: url(./verified-1676512664.5538d685.svg);--icon-url-42: url(./e2ee-normal-3652557173.2a97dccf.svg);--icon-url-43: url(./e2ee-normal-2713987956.215b3ddf.svg)} diff --git a/hydrogen/assets/theme-element-runtime.054f90d4.css b/hydrogen/assets/theme-element-runtime.054f90d4.css new file mode 100644 index 0000000..20c9f56 --- /dev/null +++ b/hydrogen/assets/theme-element-runtime.054f90d4.css @@ -0,0 +1 @@ +@font-face{font-family:"emoji";src:local("Apple Color Emoji"),local("Segoe UI Emoji"),local("Segoe UI Symbol"),local("Noto Color Emoji"),local("Twemoji"),local("Twemoji Mozilla"),local("Android Emoji"),local("EmojiSymbols"),local("Symbola");unicode-range:U+1F300-1F5FF,U+1F600-1F64F,U+1F680-1F6FF,U+2600-26FF}html{height:100%}main{display:block}@media screen and (min-width: 600px){.PreSessionScreen{width:600px;box-sizing:border-box;margin:50px auto 0}}.room-placeholder{display:flex;flex-direction:row}.SessionView{position:fixed;height:100%;width:100%;display:grid;grid-template:"status status" auto "left middle" 1fr / 320px 1fr;min-height:0;min-width:0}.right-shown{grid-template:"status status status" auto "left middle right" 1fr / 320px 1fr 300px}.hydrogen.ios .SessionView{height:var(--ios-viewport-height, 100%);top:var(--ios-viewport-top, 0)}.middle .close-middle{display:none}@media screen and (max-width: 800px){.SessionView:not(.middle-shown):not(.right-shown){grid-template:"status" auto "left" 1fr / 1fr}.SessionView.middle-shown{grid-template:"status" auto "middle" 1fr / 1fr}.SessionView.right-shown{grid-template:"status" auto "right" 1fr / 1fr}.SessionView:not(.middle-shown):not(.right-shown) .room-placeholder{display:none}.SessionView.middle-shown .LeftPanel,.SessionView.right-shown .middle,.SessionView.right-shown .LeftPanel{display:none}.middle .close-middle{display:block!important}.LeftPanel .grid{display:none!important}.VerificationReadyTileView{flex-direction:column}.VerificationTileView__actions{justify-content:center}}.LeftPanel{grid-area:left;min-width:0;min-height:0}.room-placeholder,.middle{min-width:0;grid-area:middle;width:100%;min-height:0}.middle{display:flex;flex-direction:column}.SessionStatusView{grid-area:status}.lightbox{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1;box-sizing:border-box;height:100%}.RoomView_body{flex:1 1;min-height:0;min-width:0;display:flex;flex-direction:column;height:100%}.RoomView_body .Timeline,.RoomView_body .TimelineLoadingView{flex:1 0}.middle-header{display:flex}.RoomGridView{display:grid}.RoomGridView.layout3x2{grid-template:"t0 t1 t2" 1fr "t3 t4 t5" 1fr / 1fr 1fr 1fr}.RoomGridView>.tile0{grid-area:t0}.RoomGridView>.tile1{grid-area:t1}.RoomGridView>.tile2{grid-area:t2}.RoomGridView>.tile3{grid-area:t3}.RoomGridView>.tile4{grid-area:t4}.RoomGridView>.tile5{grid-area:t5}.RoomGridView>div{display:flex;min-width:0;min-height:0}.RoomGridView>div.focus-ring{z-index:1;pointer-events:none}.menu{position:absolute;z-index:2}.menu .menu-item{box-sizing:border-box;width:100%}.Settings{display:flex;flex-direction:column}.SettingsBody{min-height:0;overflow-y:auto}.LazyListParent{flex:1 1;flex-basis:0;margin-top:15px}.LoadingView{display:flex;justify-content:center;align-items:center}.vertical-layout{display:flex;flex-direction:row;align-items:center;gap:12px}.vertical-layout>.stretch{flex:1 0}.popupContainer{position:absolute;white-space:nowrap}.SessionPickerView{padding:.4em}.SessionPickerView ul{list-style:none;padding:0}.SessionPickerView li{margin:.4em 0}.SessionPickerView .session-info{cursor:pointer;display:flex;align-items:center}.SessionPickerView .session-info>:not(:first-child){margin-left:8px}.SessionPickerView li .user-id{flex:1 1;overflow:hidden;text-overflow:ellipsis}.SessionPickerView li .error{margin:0 20px}.PasswordLoginView{padding:0 .4em .4em}.SessionLoadStatusView>.status,.LoginView_query-spinner{display:flex;gap:12px}.SessionLoadStatusView>.status p,.LoginView_query-spinner p{flex:1 1;margin:0}.SessionLoadStatusView .spinner{--size: 20px}.StartSSOLoginView{display:flex;flex-direction:column;padding:0 .4em}.StartSSOLoginView_button{flex:1 1;margin-top:12px}.LoginView_separator{justify-content:center;display:flex;margin:8px}.CompleteSSOView_title{display:flex;justify-content:center}.LoginView_sso{padding:.4em .4em 0}.LeftPanel{display:flex;flex-direction:column}.LeftPanel .utilities{display:flex}.LeftPanel .utilities .FilterField{flex:1 1;min-width:0}.LeftPanel ul{list-style:none;padding:0;margin:0}.RoomList{flex:1 0;overflow-y:auto;overscroll-behavior:contain}.RoomList>li>a{display:flex;align-items:center}.RoomList .description{margin:0;flex:1 1;min-width:0;display:flex}.RoomList .description>.name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;flex:1 1}.RightPanelView{grid-area:right;min-height:0;min-width:0;display:flex;flex-direction:column}.RoomDetailsView,.MemberDetailsView{flex-direction:column;flex:1 1}.RoomDetailsView_avatar{display:flex}.RoomDetailsView_name h2,.MemberDetailsView_name h2{text-align:center}.MemberDetailsView_shield_container{display:flex;gap:4px}.MemberDetailsView_shield_red,.MemberDetailsView_shield_green,.MemberDetailsView_shield_black{background-size:contain;background-repeat:no-repeat;width:24px;height:24px;display:block;flex-shrink:0}.MemberDetailsView_shield_description{flex-grow:1;margin:0}.MemberDetailsView_shield_red{background-image:var(--icon-url-0)}.MemberDetailsView_shield_green{background-image:var(--icon-url-1)}.MemberDetailsView_shield_black{background-image:var(--icon-url-2)}.RoomDetailsView_label,.RoomDetailsView_row,.RoomDetailsView,.MemberDetailsView,.EncryptionIconView{display:flex;align-items:center;color:var(--text-color)}.RoomDetailsView_value{display:flex;justify-content:flex-end}.EncryptionIconView{justify-content:center}.RightPanelView_buttons{display:flex;justify-content:space-between;width:100%;box-sizing:border-box;padding:16px}.RightPanelView_buttons .hide{visibility:hidden}.MemberTileView a{display:flex;align-items:center}.middle-header{align-items:center}.middle-header h2{flex:1 1}.middle-header .room-description{flex:1 1;min-width:0}.RoomHeader .topic{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.RoomHeader .description{flex:1 1 auto;min-width:0}.middle-header h2{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin:0}.MessageComposer_replyPreview{display:grid;grid-template-columns:1fr auto}.MessageComposer_replyPreview .Timeline_message{grid-column:1/-1}.MessageComposer_input{display:flex;align-items:center}.MessageComposer_input>input{display:block;flex:1 1;min-width:0;box-sizing:border-box}.TimelineLoadingView{display:flex;align-items:center;justify-content:center}.TimelineLoadingView>:not(:first-child){margin-left:12px}.Timeline{display:flex;flex-direction:column;position:relative;min-height:0}.Timeline_jumpDown{position:absolute}.Timeline_scroller{overflow-y:scroll;overscroll-behavior-y:contain;overflow-anchor:none;padding:0;margin:0;position:relative;min-height:0;flex:1 0}.Timeline_scroller>ul{list-style:none;padding:1px 0;margin:0}.AnnouncementView{display:flex;align-items:center}.GapView_container{display:flex}.GapView_container>span{flex:1 1}.Timeline_messageBody img{max-width:400px;max-height:300px}.hydrogen{--avatar-size: 32px}.hydrogen .avatar{width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6);overflow:hidden;flex-shrink:0;user-select:none;text-align:center;speak:none}.hydrogen .avatar img{width:100%;height:100%;object-fit:cover}.hydrogen .avatar.size-128{--avatar-size: 128px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-96{--avatar-size: 96px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-64{--avatar-size: 64px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-52{--avatar-size: 52px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-30{--avatar-size: 30px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-24{--avatar-size: 24px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}.hydrogen .avatar.size-12{--avatar-size: 12px;width:var(--avatar-size);height:var(--avatar-size);line-height:var(--avatar-size);font-size:calc(var(--avatar-size) * .6)}@keyframes spinner{0%{transform:rotate(0);stroke-dasharray:0 0 10 90}45%{stroke-dasharray:0 0 90 10}75%{stroke-dasharray:0 50 50 0}to{transform:rotate(360deg);stroke-dasharray:10 90 0 0}}.hydrogen:not(.legacy) .spinner circle{transform-origin:50% 50%;animation-name:spinner;animation-duration:2s;animation-iteration-count:infinite;animation-timing-function:linear;stroke-dasharray:0 0 85 85;fill:none;stroke:currentcolor;stroke-width:12;stroke-linecap:butt}.hydrogen.legacy .spinner{display:inline-block;position:relative}.hydrogen.legacy .spinner div{box-sizing:border-box;display:block;position:absolute;padding:2px;border:2px solid currentcolor;border-radius:50%;animation:legacy-spinner 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:currentcolor transparent transparent transparent;width:var(--size);height:var(--size)}.hydrogen.legacy .spinner div:nth-child(1){animation-delay:-.45s}.hydrogen.legacy .spinner div:nth-child(2){animation-delay:-.3s}.hydrogen.legacy .spinner div:nth-child(3){animation-delay:-.15s}@keyframes legacy-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinner{--size: 20px;width:var(--size);height:var(--size)}.form-row.text>input,.form-row.text>textarea{display:block;width:100%;min-width:0;box-sizing:border-box}.FilterField{display:flex}.FilterField input{display:block;flex:1 1;min-width:0}.SessionStatusView{display:flex}.SessionStatusView p{margin:0 10px;word-break:break-all;word-break:break-word}body.hydrogen{overscroll-behavior:none;overflow:hidden}.hydrogen{margin:0}.hiddenWithLayout{visibility:hidden}.hidden{display:none!important}input::-ms-clear{display:none}@font-face{font-family:Inter;font-style:normal;font-weight:100;font-display:swap;src:url(./Inter-Thin.5d8e2ac4.woff2) format("woff2"),url(./Inter-Thin.5565b01e.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:100;font-display:swap;src:url(./Inter-ThinItalic.6b3ded18.woff2) format("woff2"),url(./Inter-ThinItalic.c413497b.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:200;font-display:swap;src:url(./Inter-ExtraLight.da47c335.woff2) format("woff2"),url(./Inter-ExtraLight.d7be68a4.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:200;font-display:swap;src:url(./Inter-ExtraLightItalic.b3f94cfe.woff2) format("woff2"),url(./Inter-ExtraLightItalic.762fa4d2.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:300;font-display:swap;src:url(./Inter-Light.0f7dfe72.woff2) format("woff2"),url(./Inter-Light.38326098.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:300;font-display:swap;src:url(./Inter-LightItalic.125c7e6a.woff2) format("woff2"),url(./Inter-LightItalic.ec6c76a8.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:400;font-display:swap;src:url(./Inter-Regular.89d406b0.woff2) format("woff2"),url(./Inter-Regular.5b3a854b.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:400;font-display:swap;src:url(./Inter-Italic.bab4e808.woff2) format("woff2"),url(./Inter-Italic.7b187d57.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:500;font-display:swap;src:url(./Inter-Medium.5d308f3d.woff2) format("woff2"),url(./Inter-Medium.0fc5d904.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:500;font-display:swap;src:url(./Inter-MediumItalic.76551c20.woff2) format("woff2"),url(./Inter-MediumItalic.1458af9d.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:600;font-display:swap;src:url(./Inter-SemiBold.c7c3befe.woff2) format("woff2"),url(./Inter-SemiBold.04cd699f.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:600;font-display:swap;src:url(./Inter-SemiBoldItalic.d376ade4.woff2) format("woff2"),url(./Inter-SemiBoldItalic.420db54a.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:700;font-display:swap;src:url(./Inter-Bold.6f5e9a23.woff2) format("woff2"),url(./Inter-Bold.20d46cff.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:700;font-display:swap;src:url(./Inter-BoldItalic.e09dcbe1.woff2) format("woff2"),url(./Inter-BoldItalic.31a185fa.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:800;font-display:swap;src:url(./Inter-ExtraBold.0ef4267e.woff2) format("woff2"),url(./Inter-ExtraBold.45bae435.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:800;font-display:swap;src:url(./Inter-ExtraBoldItalic.d1e1f6a0.woff2) format("woff2"),url(./Inter-ExtraBoldItalic.30a1af87.woff) format("woff")}@font-face{font-family:Inter;font-style:normal;font-weight:900;font-display:swap;src:url(./Inter-Black.7f1f5616.woff2) format("woff2"),url(./Inter-Black.067c82f7.woff) format("woff")}@font-face{font-family:Inter;font-style:italic;font-weight:900;font-display:swap;src:url(./Inter-BlackItalic.72d5983b.woff2) format("woff2"),url(./Inter-BlackItalic.c628a2cf.woff) format("woff")}.Timeline_jumpDown{width:40px;height:40px;bottom:16px;right:32px;border-radius:100%;border:1px solid var(--background-color-secondary--darker-7);background-image:var(--icon-url-3);background-position:center;background-color:var(--background-color-primary--darker-10);background-repeat:no-repeat;cursor:pointer}.Timeline_message{display:grid;grid-template:"avatar sender" auto "avatar body" auto "time body" 1fr "time reactions" auto / 30px 1fr;column-gap:8px;padding:4px;margin:0 12px;box-sizing:border-box}.Timeline_message:not(.continuation){margin-top:4px}.ReplyPreviewView .Timeline_message{display:grid;grid-template:"body" auto;margin-left:0;padding:0}.ReplyPreviewView .Timeline_message:not(.continuation){margin-top:0}@media screen and (max-width: 800px){.Timeline_message{grid-template:"avatar sender" auto "body body" 1fr "time time" auto "reactions reactions" auto / 30px 1fr}.Timeline_messageSender{margin-top:0!important;align-self:center}}.Timeline_message:hover:not(.disabled),.Timeline_message.selected,.Timeline_message.menuOpen{background-color:#8d97a51a;border-radius:4px}.Timeline_message:hover>.Timeline_messageOptions,.Timeline_message.menuOpen>.Timeline_messageOptions{display:block;user-select:none}.Timeline_messageAvatar{grid-area:avatar;text-decoration:none}.Timeline_messageSender{grid-area:sender;font-weight:700;line-height:1.7rem}.Timeline_messageSender,.Timeline_messageBody{margin:0;word-break:break-all;word-break:break-word}.Timeline_message:not(.continuation) .Timeline_messageSender,.Timeline_message:not(.continuation) .Timeline_messageBody{margin-top:4px}.Timeline_messageOptions{display:none;grid-area:body;align-self:start;justify-self:end;margin-top:-12px;margin-right:4px;border:var(--background-color-primary--darker-10) 1px solid;height:24px;width:24px;background-color:var(--background-color-primary);color:inherit;border-radius:4px;padding:0;text-align:center;line-height:22px;cursor:pointer}.Timeline_messageTime{grid-area:time}.Timeline_messageBody time{padding:2px 0 0 10px;user-select:none}.Timeline_messageBody time,.Timeline_messageTime{font-size:.8em;line-height:normal;color:var(--timeline-time-text-color)}.Timeline_messageBody.statusMessage{font-style:italic;color:var(--light-text-color)}.Timeline_messageBody{grid-area:body;line-height:2.2rem;width:100%;min-width:0}.hydrogen .Timeline_messageSender.usercolor1{color:var(--usercolor1)}.hydrogen .Timeline_messageSender.usercolor2{color:var(--usercolor2)}.hydrogen .Timeline_messageSender.usercolor3{color:var(--usercolor3)}.hydrogen .Timeline_messageSender.usercolor4{color:var(--usercolor4)}.hydrogen .Timeline_messageSender.usercolor5{color:var(--usercolor5)}.hydrogen .Timeline_messageSender.usercolor6{color:var(--usercolor6)}.hydrogen .Timeline_messageSender.usercolor7{color:var(--usercolor7)}.hydrogen .Timeline_messageSender.usercolor8{color:var(--usercolor8)}.Timeline_messageBody h1,.Timeline_messageBody h2,.Timeline_messageBody h3,.Timeline_messageBody h4,.Timeline_messageBody h5,.Timeline_messageBody h6{font-weight:700;margin:.7em 0}.Timeline_messageBody h1{font-size:1.6em}.Timeline_messageBody h2{font-size:1.5em}.Timeline_messageBody h3{font-size:1.4em}.Timeline_messageBody h4{font-size:1.3em}.Timeline_messageBody h5{font-size:1.2em}.Timeline_messageBody h6{font-size:1.1em}.Timeline_messageBody a{word-break:break-all}.Timeline_messageBody a.link{color:var(--link-color);text-decoration:none}.Timeline_messageBody .media{display:grid;margin-top:4px;width:100%}.Timeline_messageBody .media>a{text-decoration:none;width:100%;display:block}.Timeline_messageBody .media>*{grid-row:1;grid-column:1}.Timeline_messageBody .media img,.Timeline_messageBody .media video{width:100%;height:auto;align-self:start;border-radius:4px;display:block}.hydrogen:not(.legacy) .Timeline_messageBody .media img,.hydrogen:not(.legacy) .Timeline_messageBody .media video{align-self:stretch}.Timeline_messageBody .media>.status{align-self:end;justify-self:start;font-size:.8em}.Timeline_messageBody .media>progress{align-self:center;justify-self:center;width:75%}.Timeline_messageBody .media>time{align-self:end;justify-self:end}.Timeline_messageBody .media>time,.Timeline_messageBody .media>.status{color:var(--text-color);display:block;padding:2px;margin:4px;background-color:#ffffffbf;border-radius:4px}.Timeline_messageBody .media>.spacer{width:100%;align-self:start}.Timeline_messageBody code,.Timeline_messageBody pre{background-color:var(--background-color-secondary);font-family:monospace;font-size:.9em}.Timeline_messageBody code{border-radius:3px;padding:.2em .3em;margin:0}.Timeline_messageBody pre{border:1px solid var(--light-border);padding:.5em;max-height:30em;overflow:auto}.Timeline_messageBody pre>code{background-color:unset;border-radius:unset;display:block;font-size:unset}.Timeline_messageBody blockquote{margin-left:0;padding-left:20px;border-left:4px solid var(--light-border)}.Timeline_messageBody table{border:1px solid var(--background-color-secondary--darker-15);border-radius:2px;border-spacing:0}.Timeline_messageBody thead th{border-bottom:1px solid var(--background-color-secondary--darker-15)}.Timeline_messageBody td,.Timeline_messageBody th{padding:2px 5px}.Timeline_messageBody tbody tr:nth-child(2n){background-color:var(--background-color-secondary)}.Timeline_messageBody .pill{padding:0 5px;border-radius:15px;background-color:var(--background-color-secondary);border:1px solid var(--background-color-secondary--darker-10);text-decoration:none;display:inline-flex;align-items:center;line-height:2rem;vertical-align:top;margin:1px}.Timeline_messageBody .pill div.avatar{display:inline-block;margin-right:3px}.Timeline_message.unsent .Timeline_messageBody{color:var(--light-text-color)}.Timeline_message.unverified .Timeline_messageBody{color:var(--error-color)}.Timeline_messageReactions{grid-area:reactions;margin-top:6px}.Timeline_messageReactions button{display:inline-flex;line-height:2rem;margin-right:6px;padding:1px 6px;border:1px solid var(--light-border);border-radius:10px;background-color:var(--background-color-secondary);color:inherit;cursor:pointer;user-select:none;vertical-align:middle}.Timeline_messageReactions button.active{background-color:var(--accent-color--alpha-11);border-color:var(--accent-color)}@keyframes glow-reaction-border{0%{border-color:var(--background-color-secondary)}to{border-color:var(--accent-color)}}.Timeline_messageReactions button.active.pending{animation-name:glow-reaction-border;animation-duration:.5s;animation-direction:alternate;animation-iteration-count:infinite;animation-timing-function:linear}.Timeline_locationLink{padding:0 8px;border-radius:16px;border:1px solid var(--light-border);background-color:var(--background-color-secondary);text-decoration:none;display:inline-block;line-height:2rem;vertical-align:top;margin:1px 4px}.AnnouncementView{margin:5px 0;padding:5px 10%}.AnnouncementView>div{margin:0 auto;padding:10px 20px;background-color:var(--background-color-secondary);text-align:center;border-radius:10px}.GapView_container>:not(:first-child){margin-left:12px}.GapView{padding:52px 20px}.GapView.isAtTop{padding:52px 20px 12px}.DateHeader{font-weight:700;font-size:1.5rem;position:sticky;top:5px}.DateHeader time{margin:0 auto;max-width:350px;padding:12px;display:block;color:var(--light-text-color);background-color:var(--background-color-primary);border-radius:8px;text-align:center}.CallTileView>div>div{display:flex;flex-direction:column;gap:4px}.CallTileView_members>*{margin-right:-16px}.CallTileView_members{display:flex}.CallTileView_title{font-weight:700}.CallTileView_subtitle{font-size:12px}.CallTileView_memberCount:before{content:"";background-image:var(--icon-url-4);background-repeat:no-repeat;background-size:16px 16px;width:16px;height:16px;display:inline-flex;vertical-align:bottom;margin-right:4px}.CallView{height:40vh;display:grid}.CallView>*{grid-column:1;grid-row:1}.CallView_error{align-self:start;justify-self:center;margin:16px;z-index:1}.CallView_members{display:grid;gap:12px;background:var(--background-color-secondary--darker-5);padding:12px;margin:0;min-height:0;list-style:none;align-self:stretch}.StreamView{display:grid;border-radius:8px;overflow:hidden;background-color:#000}.StreamView>*{grid-column:1;grid-row:1}.StreamView video{width:100%;height:100%;min-height:0;object-fit:contain}.StreamView_avatar{align-self:center;justify-self:center}.StreamView_error{align-self:start;justify-self:center;z-index:1}.StreamView_muteStatus{align-self:start;justify-self:end;width:24px;height:24px;background-position:center;background-repeat:no-repeat;background-size:14px;display:block;background-color:var(--text-color);border-radius:4px;margin:4px}.StreamView_muteStatus.microphoneMuted{background-image:var(--icon-url-5)}.StreamView_muteStatus.cameraMuted{background-image:var(--icon-url-6)}.CallView_buttons{align-self:end;justify-self:center;display:flex;gap:12px;margin-bottom:16px;z-index:1}.CallView_buttons button{border-radius:100%;width:48px;height:48px;border:none;background-color:var(--accent-color);background-position:center;background-repeat:no-repeat}.CallView_buttons button:disabled{background-color:var(--accent-color--lighter-10)}.CallView_buttons .CallView_hangup{background-color:var(--error-color);background-image:var(--icon-url-7)}.CallView_buttons .CallView_hangup:disabled{background-color:var(--error-color--lighter-10)}.CallView_buttons .CallView_mutedMicrophone{background-color:var(--background-color-primary);background-image:var(--icon-url-8)}.CallView_buttons .CallView_unmutedMicrophone{background-image:var(--icon-url-9)}.CallView_buttons .CallView_mutedCamera{background-color:var(--background-color-primary);background-image:var(--icon-url-10)}.CallView_buttons .CallView_unmutedCamera{background-image:var(--icon-url-11)}.CallView_members.size1{grid-template-columns:1fr;grid-template-rows:1fr}.CallView_members.size2{grid-template-columns:1fr;grid-template-rows:repeat(2,1fr)}.CallView_members.square.size3,.CallView_members.square.size4{grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,1fr)}.CallView_members.square.size5,.CallView_members.square.size6{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr)}.CallView_members.square.size7,.CallView_members.square.size8,.CallView_members.square.size9{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr)}.CallView_members.square.size10{grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr)}.CallView_members.tall.size3{grid-template-columns:1fr;grid-template-rows:repeat(3,1fr)}.CallView_members.tall.size4{grid-template-columns:1fr;grid-template-rows:repeat(4,1fr)}.CallView_members.tall.size5,.CallView_members.tall.size6{grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.tall.size7,.CallView_members.tall.size8{grid-template-rows:repeat(4,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.tall.size9,.CallView_members.tall.size10{grid-template-rows:repeat(5,1fr);grid-template-columns:repeat(2,1fr)}.CallView_members.wide.size2{grid-template-columns:repeat(2,1fr);grid-template-rows:1fr}.CallView_members.wide.size3{grid-template-rows:1fr;grid-template-columns:repeat(3,1fr)}.CallView_members.wide.size4{grid-template-rows:1fr;grid-template-columns:repeat(4,1fr)}.CallView_members.wide.size5,.CallView_members.wide.size6{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(3,1fr)}.CallView_members.wide.size7,.CallView_members.wide.size8{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(4,1fr)}.CallView_members.wide.size9,.CallView_members.wide.size10{grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(4,1fr)}.ErrorView_block{background:var(--error-color);color:var(--fixed-white);margin:16px}.ErrorView.ErrorView_inline{color:var(--error-color);margin:4px 0;padding:4px 0}.ErrorView.ErrorView_inline>p{margin:0}.ErrorView{font-weight:700;margin:16px;border-radius:8px;padding:12px;display:flex;gap:8px}.ErrorView_message{flex-basis:0;flex-grow:1;margin:0;word-break:break-all;word-break:break-word;align-self:center}.ErrorView_submit{align-self:end}.ErrorView_close{align-self:start;width:16px;height:16px;border:none;background:none;background-repeat:no-repeat;background-size:contain;cursor:pointer}.ErrorView_block .ErrorView_close{background-image:var(--icon-url-12)}.ErrorView_inline .ErrorView_close{background-image:var(--icon-url-13)}:root{font-size:10px;--icon-color: var(--background-color-secondary--darker-40);--light-border: var(--background-color-secondary--darker-5);--light-text-color: var(--background-color-secondary--darker-55);--timeline-time-text-color: var(--background-color-secondary--darker-35);--icon-background: var(--background-color-secondary--darker-7);--right-panel-text-color: var(--background-color-secondary--darker-35)}.hydrogen{font-family:Inter,sans-serif,"emoji";background-color:var(--background-color-primary);color:var(--text-color);font-size:1.4rem;--usercolor1: #368BD6;--usercolor2: #AC3BA8;--usercolor3: #03B381;--usercolor4: #E64F7A;--usercolor5: #FF812D;--usercolor6: #2DC2C5;--usercolor7: #5C56F5;--usercolor8: #74D12C}.hydrogen button{font-family:inherit}.avatar{border-radius:100%;background:var(--background-color-primary);color:var(--fixed-white)}.hydrogen .avatar.usercolor1{background-color:var(--usercolor1)}.hydrogen .avatar.usercolor2{background-color:var(--usercolor2)}.hydrogen .avatar.usercolor3{background-color:var(--usercolor3)}.hydrogen .avatar.usercolor4{background-color:var(--usercolor4)}.hydrogen .avatar.usercolor5{background-color:var(--usercolor5)}.hydrogen .avatar.usercolor6{background-color:var(--usercolor6)}.hydrogen .avatar.usercolor7{background-color:var(--usercolor7)}.hydrogen .avatar.usercolor8{background-color:var(--usercolor8)}.logo{height:48px;min-width:48px;background-image:var(--icon-url-14);background-repeat:no-repeat;background-position:center}.button-row{display:flex}.button-row>*{margin-right:10px}.button-row>*:last-child{margin-right:0}.button-row .button-action{margin:10px 0;flex:1 0 auto}.form-row.text textarea{font-family:Inter,sans-serif;background-color:var(--background-color-secondary);color:inherit}.form-group{margin:24px 0}.form-row{margin:12px 0}.form-row.text>input,.form-row.text>textarea{padding:12px;border:1px solid var(--light-border);border-radius:8px;margin-top:5px;font-size:1em;resize:vertical;background-color:var(--background-color-secondary);color:inherit}.form-row.check{display:flex;align-items:baseline;gap:4px}.form-row.text>label,.form-row.text>input{display:block}.form-row .form-row-description{font-size:1rem;color:var(--light-text-color);margin:8px 0 0}.button-action{cursor:pointer}a.button-action{text-decoration:none;text-align:center;display:block}.button-action.secondary{color:var(--accent-color)}.button-action.primary{background-color:var(--accent-color);border-radius:8px;color:var(--fixed-white);font-weight:700}.button-action.primary:disabled{color:var(--fixed-white--darker-10)}.button-action.primary.destructive{background-color:var(--error-color)}.button-action.secondary.destructive{color:var(--error-color)}.button-action{border:none;padding:10px;background:none;font-weight:500}.button-utility{cursor:pointer;width:32px;height:32px;background-position:center;background-color:var(--icon-background);background-repeat:no-repeat;border:none;border-radius:100%;display:block}.button-utility.grid{background-image:var(--icon-url-15)}.button-utility.settings{background-image:var(--icon-url-16)}.button-utility.create{background-image:var(--icon-url-17)}.button-utility.grid.on{background-image:var(--icon-url-18)}.FilterField{background-image:var(--icon-url-19);background-repeat:no-repeat;background-position:8px center;background-color:var(--icon-background);border:1px solid transparent;border-radius:16px;height:32px;align-items:center;padding-left:30px;box-sizing:border-box}.FilterField:focus-within{border:1px var(--icon-background) solid;background-color:var(--background-color-primary)}.FilterField:focus-within button{border-color:var(--background-color-primary)}.FilterField input{font-family:Inter;font-size:1.3rem;font-weight:500;line-height:1.573rem;outline:none;border:none;background-color:transparent;height:100%;color:var(--text-color)}.FilterField button{width:30px;height:30px;background-position:center;background-color:var(--icon-background);background-repeat:no-repeat;background-image:var(--icon-url-20);border:7px solid transparent;border-radius:100%;box-sizing:border-box}.PreSessionScreen{padding:30px}.PreSessionScreen h1{font-size:16px;text-align:center}.SessionLoadView{padding-top:16px}.StartSSOLoginView_button{border:1px solid var(--accent-color);border-radius:8px}.LoginView_back{background-image:var(--icon-url-21);background-color:transparent}.LoginView_separator{font-weight:500;font-size:1.5rem}.LoginView_forwardInfo{font-size:.9em;margin-left:1em;color:var(--light-text-color)}.CompleteSSOView_title{font-weight:500}@media screen and (min-width: 600px){.PreSessionScreen{box-shadow:0 6px 32px #0000001a;border-radius:8px}}.PreSessionScreen .logo{height:48px;min-width:48px}.LeftPanel{background:var(--background-color-secondary);font-size:1.5rem;padding:12px 8px 0}.LeftPanel>:not(:first-child){margin-top:12px}.LeftPanel .utilities>:not(:first-child){margin-left:8px}.LeftPanel .filter{border-bottom:1px solid var(--background-color-secondary)}.LeftPanel .filter input{padding:.8em;border:none}.LeftPanel .RoomList{padding:0 8px 0 0;margin-right:-8px}.RoomList>li{margin:0;padding:4px 8px 4px 0;align-items:center}.RoomList>li>a{text-decoration:none;align-items:center}.RoomList li:not(:first-child){margin-top:4px}.RoomList li.active{background:var(--background-color-secondary--darker-7);border-radius:5px}.RoomList li>a>*{margin-right:8px}.RoomList .description{align-items:center}.RoomList .name.unread{font-weight:600}.RoomList .badge{min-width:1.6rem;height:1.6rem;border-radius:1.6rem;box-sizing:border-box;padding:.1rem .3rem;background-color:var(--room-badge);color:var(--fixed-white);font-weight:700;font-size:1rem;line-height:1.4rem;text-align:center}.RoomList .badge.highlighted{background-color:var(--error-color)}a{color:inherit}.SessionStatusView{padding:4px;min-height:22px;background-color:var(--accent-color);color:var(--fixed-white);align-items:center}.SessionStatusView button.link{color:currentcolor;text-align:left}.SessionStatusView>.end{flex:1 1;display:flex;justify-content:flex-end;align-self:stretch;align-items:stretch}.SessionStatusView .dismiss{border:none;background:none;background-image:var(--icon-url-22);background-position:center;background-repeat:no-repeat;width:32px;cursor:pointer}.room-placeholder{align-items:center;justify-content:center;text-align:center;padding:20px}.SessionPickerView li{font-size:1.2em}.SessionPickerView .session-info{text-decoration:none;padding:12px;border:1px solid var(--light-border);border-radius:8px;background-image:var(--icon-url-23);background-position:center right 30px;background-repeat:no-repeat;font-weight:500}.SessionPickerView .session-actions{margin:10px 0 20px;display:flex}.SessionPickerView .session-actions>*{margin-right:10px}.SessionPickerView .session-actions>*:last-child{margin-right:0}.SessionPickerView .session-actions button{border:none;background:none;color:inherit}.SessionPickerView button.destructive{color:var(--error-color)}.RoomGridView>div.container{border-right:1px solid var(--background-color-secondary);border-bottom:1px solid var(--background-color-secondary)}.RoomGridView>.focused>.room-placeholder .unfocused{display:none}.RoomGridView>:not(.focused)>.room-placeholder .focused{display:none}.room-placeholder .unfocused{color:var(--right-panel-text-color)}.RoomGridView>div.focus-ring{border:2px solid var(--accent-color--darker-5);border-radius:12px}.middle-header{box-sizing:border-box;flex:0 0 56px;background:var(--background-color-primary);padding:0 16px;border-bottom:1px solid var(--background-color-secondary)}.middle-header h2{font-size:1.8rem;font-weight:600}.middle-header>:not(:last-child){margin-right:8px}.close-middle,.close-session{background-image:var(--icon-url-24);background-position-x:10px}.RoomHeader .topic{font-size:14rem}.RoomHeader .room-options{background-image:var(--icon-url-25)}.RoomView_error{color:var(--error-color);background:#efefef;height:0px;font-weight:700;transition:.25s all ease-out;padding-right:20px;padding-left:20px}.RoomView_error div{overflow:hidden;height:100%;width:100%;position:relative;display:flex;align-items:center}.RoomView_error:not(:empty){height:auto;padding-top:20px;padding-bottom:20px}.RoomView_error p{position:relative;display:block;width:100%;height:auto;margin:0}.RoomView_error button{width:40px;padding-top:20px;padding-bottom:20px;background:none;border:none;position:relative;border-radius:5px;transition:.1s all ease-out;cursor:pointer}.RoomView_error button:hover{background:#cfcfcf}.RoomView_error button:before{content:"\274c";position:absolute;top:15px;left:9px;width:20px;height:10px;font-size:10px;align-self:middle}.MessageComposer_replyPreview .Timeline_message{margin:5px 0 0;max-height:30vh;overflow:auto}.MessageComposer_replyPreview{background:var(--background-color-secondary);margin:0 10px 10px;box-shadow:0 0 5px var(--background-color-secondary--darker-15);border-radius:5px}.MessageComposer_input,.MessageComposer_replyPreview{padding:8px}.MessageComposer_replyPreview>.replying{display:inline-flex;flex-direction:row;align-items:center;font-weight:700}.MessageComposer_replyPreview>button.cancel{width:32px;height:32px;display:block;border:none;text-indent:200%;white-space:nowrap;overflow:hidden;background-color:transparent;background-image:var(--icon-url-26);background-repeat:no-repeat;background-position:center;background-size:18px;cursor:pointer}.MessageComposer_input:first-child{border-top:1px solid var(--background-color-secondary)}.MessageComposer_input>:not(:first-child){margin-left:12px}.MessageComposer_input>textarea{border:none;border-radius:24px;background:var(--background-color-secondary);color:inherit;font-size:14px;font-family:Inter,sans-serif;resize:none;flex:1 1;padding:14px;box-sizing:border-box;overflow:hidden;max-height:113px;overflow-y:auto;overflow-y:overlay}.MessageComposer_input>button.send{width:32px;height:32px;display:block;border-radius:100%;border:none;text-indent:200%;overflow:hidden;background-color:var(--accent-color);background-image:var(--icon-url-27);background-repeat:no-repeat;background-position:center;align-self:end;margin-bottom:8px}.MessageComposer_input>button.sendFile{width:32px;height:32px;display:block;border:none;text-indent:200%;white-space:nowrap;overflow:hidden;background-color:transparent;background-image:var(--icon-url-28);background-repeat:no-repeat;background-position:center}.MessageComposer.MessageComposer_canSend button.sendFile{display:none}.MessageComposer:not(.MessageComposer_canSend) button.send{display:none}.SettingsBody{padding:0 16px}.Settings h3{margin:16px 0 8px}.Settings p{max-width:700px}.Settings .row .label{font-weight:600}.Settings .row .label,.Settings .row .content{margin-top:4px;margin-bottom:4px}.Settings .row .content{margin-left:4px;flex:1 1}.Settings .row.code .content{font-family:monospace}.Settings .row .content button{display:inline-block;margin:0 8px}.Settings .row .content input[type=range]{width:100%;max-width:300px;min-width:160px}.Settings .row{margin:4px 0;display:flex;flex-wrap:wrap;align-items:center}.Settings .row .label{flex:0 0 200px;align-self:flex-start}.Settings .row .content p{margin:8px 0}.Settings .row .content p:first-child{margin-top:0}.Settings .row .content p:last-child{margin-bottom:0}.FeatureView{display:flex;gap:8px}.FeaturesView ul{list-style:none;padding:8px 16px}.FeaturesView input[type=checkbox]{align-self:start}.FeatureView h4{margin:0}.FeatureView p{margin:8px 0}.error{color:var(--error-color);font-weight:600}button.link{font-size:1em;border:none;text-decoration:underline;background:none;cursor:pointer;margin:-12px;padding:12px;color:inherit}.Settings a,.Settings .link{color:var(--accent-color);font-weight:600}.lightbox{background-color:#000000bf;display:grid;grid-template:"content close" auto "content details" 1fr / 1fr auto;color:var(--background-color-primary);padding:4px}@media (max-aspect-ratio: 1/1){.lightbox{grid-template:"close" auto "content" 1fr "details" auto / 1fr}.lightbox .details{width:100%!important}}.lightbox .picture{grid-area:content;background-size:contain;background-position:center;background-repeat:no-repeat;width:100%;height:100%;align-self:center;justify-self:center}.lightbox .loading{grid-area:content;align-self:center;justify-self:center;display:flex}.lightbox .loading>:not(:first-child){margin-left:8px}.lightbox .close{display:block;grid-area:close;justify-self:end;background-image:var(--icon-url-29);background-position:center;background-size:16px;background-repeat:no-repeat;width:16px;height:16px;padding:12px}.lightbox .details{grid-area:details;padding:12px;font-size:1.5rem;width:200px}.menu{border-radius:8px;box-shadow:2px 2px 10px #00000080;padding:4px;background-color:var(--background-color-primary);list-style:none;margin:0}.menu li{margin-bottom:10px}.menu .menu-item{color:var(--text-color)}.menu button{border-radius:4px;border:none;background-color:transparent;text-align:left;padding:8px 32px 8px 8px;font-size:1.5rem;height:24px;cursor:pointer}.menu .destructive button{color:var(--error-color)}.menu .quick-reactions{display:flex;padding:8px 32px 8px 8px}.menu .quick-reactions button{padding:2px 4px;text-align:center}.InviteView_body{display:flex;justify-content:space-around;align-items:center;flex:1 1;overflow:auto}.InviteView_invite{display:flex;width:100%;max-width:400px;flex-direction:column;padding:0 24px}.InviteView_roomProfile{display:grid;gap:4px;grid-template:"avatar name" auto "avatar description" 1fr / 72px 1fr;align-self:center;margin-bottom:24px}.InviteView_roomProfile h3{grid-area:name;margin:0}.InviteView_roomDescription{grid-area:description;font-size:1.2rem;margin:0;color:var(--light-text-color)}.InviteView_roomAvatar{grid-area:avatar}.InviteView_dmAvatar{align-self:center}.InviteView_inviter{text-align:center;margin:24px 0}.InviteView_inviter .avatar{display:inline-block;vertical-align:middle;margin-right:4px}.InviteView_buttonRow{margin:10px auto;max-width:200px;width:100%}.InviteView_buttonRow button{display:block;width:100%}.DisabledComposerView{padding:12px;background-color:var(--background-color-secondary)}.DisabledComposerView h3{margin:0}.UnknownRoomView_container{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.UnknownRoomView_body{height:100%;text-align:center;padding:16px;box-sizing:border-box}.UnknownRoomView h2{word-break:break-all;word-break:break-word}.UnknownRoomView button{max-width:200px;width:100%}.LoadingView{height:100%;width:100%}.LoadingView .spinner{margin-right:5px}.InvitePanelView{display:flex;flex-direction:column;justify-content:center;align-items:center}.InvitePanelView__form{margin-top:8px}.InvitePanelView__input{font-family:Inter;font-size:1.3rem;font-weight:500;line-height:1.573rem;outline:none;border:none;background-color:var(--icon-background);color:var(--text-color);height:32px;box-sizing:border-box;margin:5px;border-radius:16px;padding:15px;width:90%}.InvitePanelView__form,.InvitePanelView__btn{display:flex;flex-direction:column;justify-content:center;align-items:center}.InvitePanelView__btn{width:100px;height:30px;margin-top:8px}.InvitePanelView__heading{width:90%;text-align:center;margin:0}.RightPanelView{background:var(--background-color-secondary)}.RoomDetailsView{padding:0 16px 16px}.RoomDetailsView_id,.MemberDetailsView_id{color:var(--right-panel-text-color);font-size:12px}.RoomDetailsView_rows{margin-top:36px;width:100%}.RoomDetailsView_name h2,.MemberDetailsView_name h2{margin-bottom:4px;font-size:1.8rem}.RoomDetailsView_row{margin-bottom:20px;font-weight:500;font-size:15px;width:100%;background:none;border:none;padding:0}button.RoomDetailsView_row{cursor:pointer}button.RoomDetailsView_row:after{content:var(--icon-url-30);margin-left:12px}.RoomDetailsView_row:not(button):after{content:" ";width:19px}.RoomDetailsView_label:before{padding-right:16px;height:24px;width:20px}.RoomDetailsView_label{width:200px}.RoomDetailsView_value{color:var(--right-panel-text-color);flex:1 1}.MemberCount:before{content:var(--icon-url-31)}.EncryptionStatus:before{content:var(--icon-url-32)}.EncryptionIconView{width:52px;height:52px;border-radius:100%;background:var(--right-panel-text-color);border:3px solid var(--background-color-secondary);margin-left:-16px}.EncryptionIconView_encrypted,.EncryptionIconView_unencrypted{height:24px;width:24px}.EncryptionIconView_encrypted{content:var(--icon-url-33)}.EncryptionIconView_unencrypted{content:var(--icon-url-34)}.RightPanelView_buttons .button-utility{width:24px;height:24px}.RightPanelView_buttons .close{background-image:var(--icon-url-35)}.RightPanelView_buttons .back{background-image:var(--icon-url-36)}.MemberListView__list{padding-left:16px;padding-right:16px;margin:0}.MemberListView{display:flex;flex-direction:column;height:100%}.MemberListView__invite-container{display:flex;justify-content:center;align-items:center}.MemberListView__invite-btn{width:80%;height:32px;display:flex;justify-content:center;align-items:center}.MemberTileView{margin-bottom:8px;list-style:none}.MemberTileView a{text-decoration:none}.MemberTileView .avatar{margin-right:8px}.MemberTileView_name{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;flex:1 1}.MemberDetailsView_section{box-sizing:border-box;padding:16px;width:100%}.MemberDetailsView_label{font-size:12px;font-weight:600;color:var(--right-panel-text-color);text-transform:uppercase}.MemberDetailsView_value,.MemberDetailsView_options{margin-left:8px;margin-top:5px;font-size:12px}.MemberDetailsView_options{display:inline-flex;flex-direction:column}.MemberDetailsView_options a,.MemberDetailsView_options button{color:var(--accent-color);text-decoration:none;margin:0 0 3px;padding:0;border:none;background:none;cursor:pointer;text-align:left}.LazyListParent{overflow-y:auto}.LogoutScreen{height:100vh}.LogoutScreen .content{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}.LogoutScreen .status{display:flex;gap:12px}.CreateRoomView_body,.JoinRoomView_body,.RoomBeingCreated_error{max-width:400px}.RoomBeingCreated_error{margin-top:48px}.centered-column{padding:0 12px;align-self:center;width:100%;box-sizing:border-box}.CreateRoomView_selectAvatar{border:none;background:none;cursor:pointer}.CreateRoomView_selectAvatarPlaceholder{width:64px;height:64px;border-radius:100%;background-color:var(--icon-background);background-image:var(--icon-url-37);background-repeat:no-repeat;background-position:center;background-size:36px}.JoinRoomView_status{display:flex;align-items:center;justify-content:center;margin-top:10px}.JoinRoomView_status .spinner{margin-right:5px}.ToastCollectionView{display:flex;position:fixed;flex-direction:column;z-index:1000;left:44px;top:52px}.ToastCollectionView ul{margin:0;padding:0}.VerificationToastNotificationView:not(:first-child),.CallToastNotificationView:not(:first-child){margin-top:12px}.VerificationToastNotificationView{display:flex;flex-direction:column}.CallToastNotificationView{display:grid;grid-template-rows:40px 1fr 1fr 48px;row-gap:4px}.VerificationToastNotificationView,.CallToastNotificationView{background-color:var(--background-color-secondary);border-radius:8px;color:var(--text-color);box-shadow:2px 2px 10px #00000080}.CallToastNotificationView{width:260px}.VerificationToastNotificationView{width:248px}.VerificationToastNotificationView__top{padding:8px;display:flex}.CallToastNotificationView__top{display:grid;grid-template-columns:auto 176px auto;align-items:center;justify-items:center}.VerificationToastNotificationView__dismiss-btn,.CallToastNotificationView__dismiss-btn{background:center var(--background-color-secondary--darker-5) var(--icon-url-38) no-repeat;border-radius:100%;height:15px;width:15px}.VerificationToastNotificationView__title,.CallToastNotificationView__name{font-weight:600;width:100%}.VerificationToastNotificationView__description{padding:8px}.CallToastNotificationView__description{margin-left:42px}.CallToastNotificationView__call-type:before{content:"";background-image:var(--icon-url-39);background-repeat:no-repeat;background-size:20px 20px;display:flex;width:20px;height:20px;padding-right:5px}.CallToastNotificationView__call-type:after{content:"";width:4px;height:4px;background-color:var(--text-color);border-radius:100%;align-self:center;margin:5px}.CallToastNotificationView__member-count:before{content:"";background-image:var(--icon-url-40);background-repeat:no-repeat;background-size:20px 20px;display:flex;width:20px;height:20px;padding-right:5px}.CallToastNotificationView__member-count,.CallToastNotificationView__call-type{display:flex;align-items:center}.CallToastNotificationView__info{display:flex;margin-left:42px}.CallToastNotificationView__action{display:flex;justify-content:end;margin-right:10px}.VerificationToastNotificationView__action{display:flex;justify-content:space-between;padding:8px}.CallToastNotificationView__action .button-action{width:100px;height:40px}.VerificationToastNotificationView__action .button-action{width:100px;height:32px;display:flex;align-items:center;justify-content:center}.VerifyEmojisView{width:100%}.VerificationCompleteView,.DeviceVerificationView,.SelectMethodView{display:flex;align-items:center;justify-content:center;flex-direction:column;width:100%}.SelectMethodView>div,.SelectMethodView__heading,.SelectMethodView__title{width:inherit;box-sizing:border-box}.VerificationCompleteView__heading,.VerifyEmojisView__heading,.SelectMethodView__heading,.MissingKeysView__heading,.WaitingForOtherUserView__heading{display:flex;align-items:center;gap:16px;flex-wrap:wrap;justify-content:center;padding:8px}.MissingKeysView__heading{text-align:center}.VerificationCompleteView>*,.SelectMethodView>*,.VerifyEmojisView>*,.WaitingForOtherUserView>*{padding:16px}.VerificationCancelledView__title,.VerificationCompleteView__title,.VerifyEmojisView__title,.SelectMethodView__title,.WaitingForOtherUserView__title{font-size:1.5em;text-align:center}.VerificationCompleteView__title,.VerifyEmojisView__title,.SelectMethodView__title,.WaitingForOtherUserView__title,.VerificationCancelledView__description,.MissingKeysView__description,.VerificationCompleteView__description,.VerifyEmojisView__description,.SelectMethodView__description,.WaitingForOtherUserView__description{text-align:center;margin:0}.VerificationCancelledView__actions,.MissingKeysView__actions,.SelectMethodView__actions,.VerifyEmojisView__actions,.WaitingForOtherUserView__actions{display:flex;justify-content:center;gap:12px;padding:16px}.EmojiCollection{display:flex;justify-content:center;gap:16px;flex-wrap:wrap}.EmojiContainer__emoji{font-size:3.2rem}.VerifyEmojisView__waiting,.EmojiContainer__name,.EmojiContainer__emoji{display:flex;justify-content:center;align-items:center}.EmojiContainer__name{font-weight:700}.VerifyEmojisView__waiting{gap:12px}.VerificationCompleteView__icon{background:var(--icon-url-41) no-repeat;background-size:contain;width:128px;height:128px}.SelectMethodView__name{overflow:hidden;text-overflow:ellipsis;width:100%;display:inline-block}.VerificationInProgressTileView,.VerificationCompletedTileView,.VerificationCancelledTileView,.VerificationReadyTileView{display:flex;gap:20px}.VerificationTileView__actions{display:flex;gap:16px}.VerificationTileView__description{display:flex;align-items:center;font-weight:700;font-size:1.4rem;color:var(--text-color);gap:4px;text-align:center}.VerificationInProgressTileView,.VerificationCompletedTileView,.VerificationCancelledTileView,.VerificationReadyTileView{background:var(--background-color-primary--darker-5);padding:8px;box-sizing:border-box;border-radius:8px}.VerificationTileView{display:flex;justify-content:center;padding:5px 10%;box-sizing:border-box}.VerificationInProgressTileView .VerificationTileView__shield,.VerificationReadyTileView .VerificationTileView__shield{background:var(--icon-url-42) no-repeat}.VerificationCompletedTileView .VerificationTileView__shield{background:var(--icon-url-43) no-repeat}.VerificationTileView__shield{width:20px;height:20px;display:flex;align-self:center} diff --git a/hydrogen/assets/theme-element.json b/hydrogen/assets/theme-element.json new file mode 100644 index 0000000..9561cec --- /dev/null +++ b/hydrogen/assets/theme-element.json @@ -0,0 +1 @@ +{"version":1,"name":"Element","id":"element","values":{"variants":{"light":{"base":true,"default":true,"name":"Light","variables":{"background-color-primary":"#fff","background-color-secondary":"#f6f6f6","text-color":"#2E2F32","accent-color":"#03b381","error-color":"#FF4B55","fixed-white":"#fff","room-badge":"#61708b","link-color":"#238cf5"}},"dark":{"dark":true,"default":true,"name":"Dark","variables":{"background-color-primary":"#21262b","background-color-secondary":"#2D3239","text-color":"#fff","accent-color":"#03B381","error-color":"#FF4B55","fixed-white":"#fff","room-badge":"#61708b","link-color":"#238cf5"}}}},"source":{"built-assets":{"element-light":"theme-element-light.78427b5a.css","element-dark":"theme-element-dark.a6fddb2f.css"},"runtime-asset":"theme-element-runtime.054f90d4.css","derived-variables":["background-color-secondary--darker-7","background-color-primary--darker-10","background-color-secondary--darker-15","background-color-secondary--darker-10","accent-color--alpha-11","background-color-secondary--darker-5","text-color--lighter-80","accent-color--lighter-10","error-color--lighter-10","background-color-secondary--darker-40","background-color-secondary--darker-55","background-color-secondary--darker-35","fixed-white--darker-10","accent-color--darker-5","background-color-primary--darker-5","icon-color=background-color-secondary--darker-40","light-border=background-color-secondary--darker-5","light-text-color=background-color-secondary--darker-55","timeline-time-text-color=background-color-secondary--darker-35","icon-background=background-color-secondary--darker-7","right-panel-text-color=background-color-secondary--darker-35"],"icon":{"icon-url-0":"verification-error.80ad562b.svg?primary=error-color","icon-url-1":"verified.b90752ec.svg?primary=accent-color","icon-url-2":"encryption-status.8054183e.svg?primary=text-color","icon-url-3":"chevron-down.9a7440b9.svg?primary=icon-color","icon-url-4":"room-members.35ed0bf9.svg?primary=text-color","icon-url-5":"mic-muted.56aa03b9.svg?primary=text-color--lighter-80","icon-url-6":"cam-muted.9f690631.svg?primary=text-color--lighter-80","icon-url-7":"hangup.8b163c30.svg?primary=background-color-primary","icon-url-8":"mic-muted.56aa03b9.svg?primary=text-color","icon-url-9":"mic-unmuted.c180f63a.svg?primary=background-color-primary","icon-url-10":"cam-muted.9f690631.svg?primary=text-color","icon-url-11":"cam-unmuted.67e18332.svg?primary=background-color-primary","icon-url-12":"clear.0d180c33.svg?primary=fixed-white","icon-url-13":"clear.0d180c33.svg?primary=text-color","icon-url-14":"element-logo.86bc8565.svg?primary=accent-color","icon-url-15":"enable-grid.eef43c65.svg?primary=icon-color","icon-url-16":"settings.45b8e09f.svg?primary=icon-color","icon-url-17":"plus.49560f96.svg?primary=icon-color","icon-url-18":"disable-grid.371ceaaa.svg?primary=icon-color","icon-url-19":"search.21e0fd39.svg?primary=icon-color","icon-url-20":"clear.0d180c33.svg?primary=icon-color","icon-url-21":"chevron-left.b8b2c5fc.svg?primary=icon-color","icon-url-22":"clear.0d180c33.svg?primary=background-color-primary","icon-url-23":"chevron-right.885731d1.svg?primary=icon-color","icon-url-24":"chevron-left.b8b2c5fc.svg?primary=icon-color","icon-url-25":"vertical-ellipsis.70ab5d25.svg?primary=icon-color","icon-url-26":"clear.0d180c33.svg?primary=icon-color","icon-url-27":"send.7a090949.svg?primary=background-color-primary","icon-url-28":"paperclip.ec29fd9d.svg?primary=icon-color","icon-url-29":"clear.0d180c33.svg?primary=fixed-white","icon-url-30":"chevron-small.dfd7e618.svg?primary=icon-color","icon-url-31":"room-members.35ed0bf9.svg?primary=icon-color","icon-url-32":"encryption-status.8054183e.svg?primary=icon-color","icon-url-33":"e2ee-normal.bef76bd4.svg?primary=fixed-white","icon-url-34":"e2ee-disabled.8507165d.svg?primary=fixed-white","icon-url-35":"clear.0d180c33.svg?primary=icon-color","icon-url-36":"chevron-thin-left.d111869b.svg?primary=icon-color","icon-url-37":"plus.49560f96.svg?primary=icon-color","icon-url-38":"clear.0d180c33.svg?primary=text-color","icon-url-39":"video-call.d3cb081e.svg?primary=light-text-color","icon-url-40":"room-members.35ed0bf9.svg?primary=light-text-color","icon-url-41":"verified.b90752ec.svg?primary=accent-color","icon-url-42":"e2ee-normal.bef76bd4.svg?primary=background-color-secondary--darker-40","icon-url-43":"e2ee-normal.bef76bd4.svg?primary=accent-color"}}} \ No newline at end of file diff --git a/hydrogen/assets/verification-error-3007923930.91f5da98.svg b/hydrogen/assets/verification-error-3007923930.91f5da98.svg new file mode 100644 index 0000000..d4326b7 --- /dev/null +++ b/hydrogen/assets/verification-error-3007923930.91f5da98.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/verification-error.80ad562b.svg b/hydrogen/assets/verification-error.80ad562b.svg new file mode 100644 index 0000000..73a5170 --- /dev/null +++ b/hydrogen/assets/verification-error.80ad562b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/verified-1676512664.5538d685.svg b/hydrogen/assets/verified-1676512664.5538d685.svg new file mode 100644 index 0000000..617bc24 --- /dev/null +++ b/hydrogen/assets/verified-1676512664.5538d685.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/verified-3138359829.814d0123.svg b/hydrogen/assets/verified-3138359829.814d0123.svg new file mode 100644 index 0000000..626e186 --- /dev/null +++ b/hydrogen/assets/verified-3138359829.814d0123.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/verified.b90752ec.svg b/hydrogen/assets/verified.b90752ec.svg new file mode 100644 index 0000000..fd6c9f7 --- /dev/null +++ b/hydrogen/assets/verified.b90752ec.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/vertical-ellipsis-3416547705.f619a721.svg b/hydrogen/assets/vertical-ellipsis-3416547705.f619a721.svg new file mode 100644 index 0000000..44c362b --- /dev/null +++ b/hydrogen/assets/vertical-ellipsis-3416547705.f619a721.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/vertical-ellipsis-487061581.e7709afd.svg b/hydrogen/assets/vertical-ellipsis-487061581.e7709afd.svg new file mode 100644 index 0000000..eb1641d --- /dev/null +++ b/hydrogen/assets/vertical-ellipsis-487061581.e7709afd.svg @@ -0,0 +1,3 @@ + + + diff --git a/hydrogen/assets/vertical-ellipsis.70ab5d25.svg b/hydrogen/assets/vertical-ellipsis.70ab5d25.svg new file mode 100644 index 0000000..1d5dd9e --- /dev/null +++ b/hydrogen/assets/vertical-ellipsis.70ab5d25.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/assets/video-call-2591082837.8f09bafc.svg b/hydrogen/assets/video-call-2591082837.8f09bafc.svg new file mode 100644 index 0000000..a0e02c7 --- /dev/null +++ b/hydrogen/assets/video-call-2591082837.8f09bafc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/video-call-3307702325.5e74dd9a.svg b/hydrogen/assets/video-call-3307702325.5e74dd9a.svg new file mode 100644 index 0000000..6461caf --- /dev/null +++ b/hydrogen/assets/video-call-3307702325.5e74dd9a.svg @@ -0,0 +1,4 @@ + + + + diff --git a/hydrogen/assets/video-call.d3cb081e.svg b/hydrogen/assets/video-call.d3cb081e.svg new file mode 100644 index 0000000..1dce1db --- /dev/null +++ b/hydrogen/assets/video-call.d3cb081e.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hydrogen/config.sample.json b/hydrogen/config.sample.json new file mode 100644 index 0000000..c4ef1cc --- /dev/null +++ b/hydrogen/config.sample.json @@ -0,0 +1,16 @@ +{ + "push": { + "appId": "io.element.hydrogen.web", + "gatewayUrl": "https://matrix.org", + "applicationServerKey": "BC-gpSdVHEXhvHSHS0AzzWrQoukv2BE7KzpoPO_FfPacqOo3l1pdqz7rSgmB04pZCWaHPz7XRe6fjLaC-WPDopM" + }, + "defaultHomeServer": "matrix.org", + "bugReportEndpointUrl": "https://element.io/bugreports/submit", + "themeManifests": [ + "assets/theme-element.json" + ], + "defaultTheme": { + "light": "element-light", + "dark": "element-dark" + } +} \ No newline at end of file diff --git a/hydrogen/icon.png b/hydrogen/icon.png new file mode 100644 index 0000000..b6c70c0 Binary files /dev/null and b/hydrogen/icon.png differ diff --git a/hydrogen/index.html b/hydrogen/index.html new file mode 100644 index 0000000..268dfb8 --- /dev/null +++ b/hydrogen/index.html @@ -0,0 +1,24 @@ + + + + + + + + Hydrogen Chat + + + + + + + + + + + + + + + + diff --git a/hydrogen/sw.js b/hydrogen/sw.js new file mode 100644 index 0000000..6d7e3a0 --- /dev/null +++ b/hydrogen/sw.js @@ -0,0 +1,2 @@ +const k="icon.png",H=["config.json","assets/theme-element.json","index.html"],N=["assets/icon-maskable.965d12c4.png","assets/download-sandbox.48a866e9.html","assets/olm.cf9a793b.js","assets/olm.3fc8dbfe.wasm","assets/verification-error-3007923930.91f5da98.svg","assets/verified-3138359829.814d0123.svg","assets/encryption-status-2100926911.a90232b4.svg","assets/chevron-down-1956489915.3389f17f.svg","assets/room-members-871477030.90b799fe.svg","assets/mic-muted-2638557456.4d8c99b4.svg","assets/cam-muted-3489740486.a882d986.svg","assets/hangup-581771896.279a6adf.svg","assets/cam-unmuted-2274150835.69bcdbc4.svg","assets/mic-muted-3642419863.228ee86f.svg","assets/mic-unmuted-211198830.1fde69c5.svg","assets/clear-2743697487.2f1a17f1.svg","assets/element-logo-1551909733.1d59f06a.svg","assets/enable-grid-2288309723.f83895c8.svg","assets/settings-878939771.57cf3680.svg","assets/plus-3937109722.5c243914.svg","assets/disable-grid-4240599831.c8dc25a1.svg","assets/search-261439583.1bffaca1.svg","assets/chevron-left-2611498805.b5555a61.svg","assets/clear-4137897294.7b90e8df.svg","assets/dismiss-2476348673.d0f98560.svg","assets/chevron-right-2390431650.ec9bf561.svg","assets/send-3413346515.b0fb8626.svg","assets/vertical-ellipsis-487061581.e7709afd.svg","assets/paperclip-3961996319.da562307.svg","assets/chevron-small-4098047679.489e66cc.svg","assets/room-members-3084360280.6f64aaef.svg","assets/encryption-status-3449529405.c200a9bb.svg","assets/e2ee-normal-1448349558.af8f5484.svg","assets/e2ee-disabled-1470792300.6863c16d.svg","assets/chevron-thin-left-3078630092.d0d143e3.svg","assets/video-call-2591082837.8f09bafc.svg","assets/room-members-2999414798.6534e8ec.svg","assets/e2ee-normal-3923817510.8737e7ee.svg","assets/e2ee-normal-3127337641.2624a9c9.svg","assets/cam-muted-711199923.069dcf2b.svg","assets/verified-1676512664.5538d685.svg","assets/encryption-status-689620003.8086e625.svg","assets/chevron-down-3300400168.d1a083a1.svg","assets/room-members-3297708388.1a158fe2.svg","assets/mic-muted-2617055184.e8d1962f.svg","assets/cam-muted-2247331037.b0b2cf01.svg","assets/hangup-1798659826.d0cb8438.svg","assets/mic-muted-4213153786.513608a5.svg","assets/clear-2203718389.37dd36a5.svg","assets/cam-muted-1894081672.22150c2b.svg","assets/mic-unmuted-3178778883.b8f57412.svg","assets/element-logo-703176763.fc54fc8d.svg","assets/settings-2175246113.00804666.svg","assets/enable-grid-2071838379.ab4f40c5.svg","assets/cam-unmuted-2215154474.a82b7bf1.svg","assets/clear-426756705.361f7a30.svg","assets/plus-4190356069.084c5e3d.svg","assets/search-3263540198.1511780c.svg","assets/disable-grid-3304422220.8a79cfcb.svg","assets/chevron-left-3506338632.4e437777.svg","assets/chevron-right-847198822.23380c56.svg","assets/vertical-ellipsis-3416547705.f619a721.svg","assets/send-1171052351.caa5c494.svg","assets/paperclip-2441131778.1f5e29f3.svg","assets/chevron-small-781914114.936b4943.svg","assets/room-members-3847743605.9fcf4567.svg","assets/chevron-thin-left-3831175135.13f60c05.svg","assets/video-call-3307702325.5e74dd9a.svg","assets/room-members-1680968332.b4f57622.svg","assets/encryption-status-475927392.2fedc0bd.svg","assets/e2ee-normal-3652557173.2a97dccf.svg","assets/e2ee-normal-2713987956.215b3ddf.svg","assets/index.e65aa065.js","assets/theme-element-light.78427b5a.css","assets/theme-element-dark.a6fddb2f.css","assets/theme-element-runtime.054f90d4.css","assets/verification-error.80ad562b.svg","assets/verified.b90752ec.svg","assets/encryption-status.8054183e.svg","assets/chevron-down.9a7440b9.svg","assets/room-members.35ed0bf9.svg","assets/mic-muted.56aa03b9.svg","assets/cam-muted.9f690631.svg","assets/hangup.8b163c30.svg","assets/mic-unmuted.c180f63a.svg","assets/cam-unmuted.67e18332.svg","assets/clear.0d180c33.svg","assets/element-logo.86bc8565.svg","assets/enable-grid.eef43c65.svg","assets/settings.45b8e09f.svg","assets/plus.49560f96.svg","assets/disable-grid.371ceaaa.svg","assets/search.21e0fd39.svg","assets/chevron-left.b8b2c5fc.svg","assets/chevron-right.885731d1.svg","assets/vertical-ellipsis.70ab5d25.svg","assets/send.7a090949.svg","assets/paperclip.ec29fd9d.svg","assets/chevron-small.dfd7e618.svg","assets/e2ee-normal.bef76bd4.svg","assets/e2ee-disabled.8507165d.svg","assets/chevron-thin-left.d111869b.svg","assets/video-call.d3cb081e.svg","assets/icon.8024c299.png"],b=["assets/main.bdb9a925.js","assets/olm_legacy.bc22f405.js","assets/Inter-Thin.5d8e2ac4.woff2","assets/Inter-ThinItalic.6b3ded18.woff2","assets/Inter-ExtraLight.da47c335.woff2","assets/Inter-Light.0f7dfe72.woff2","assets/Inter-LightItalic.125c7e6a.woff2","assets/Inter-ExtraLightItalic.b3f94cfe.woff2","assets/Inter-MediumItalic.76551c20.woff2","assets/Inter-Regular.89d406b0.woff2","assets/Inter-Italic.bab4e808.woff2","assets/Inter-SemiBoldItalic.d376ade4.woff2","assets/Inter-Medium.5d308f3d.woff2","assets/Inter-BoldItalic.e09dcbe1.woff2","assets/Inter-SemiBold.c7c3befe.woff2","assets/Inter-ExtraBold.0ef4267e.woff2","assets/Inter-ExtraBoldItalic.d1e1f6a0.woff2","assets/Inter-Black.7f1f5616.woff2","assets/Inter-BlackItalic.72d5983b.woff2","assets/Inter-Bold.6f5e9a23.woff2","assets/Inter-Thin.5565b01e.woff","assets/Inter-ThinItalic.c413497b.woff","assets/Inter-ExtraLight.d7be68a4.woff","assets/Inter-Light.38326098.woff","assets/Inter-ExtraLightItalic.762fa4d2.woff","assets/Inter-MediumItalic.1458af9d.woff","assets/Inter-LightItalic.ec6c76a8.woff","assets/Inter-Regular.5b3a854b.woff","assets/Inter-Italic.7b187d57.woff","assets/Inter-Medium.0fc5d904.woff","assets/Inter-SemiBoldItalic.420db54a.woff","assets/Inter-BoldItalic.31a185fa.woff","assets/Inter-SemiBold.04cd699f.woff","assets/Inter-Black.067c82f7.woff","assets/Inter-ExtraBold.45bae435.woff","assets/Inter-ExtraBoldItalic.30a1af87.woff","assets/Inter-BlackItalic.c628a2cf.woff","assets/Inter-Bold.20d46cff.woff","assets/manifest.1f23c85b.json"],u=`hydrogen-assets-${"3895512102"}`,r="hydrogen-assets",A="hydrogen-media-thumbnails-v2";self.addEventListener("install",function(e){e.waitUntil((async()=>{await(await caches.open(u)).addAll(H);const a=await caches.open(r);await Promise.all(N.map(async n=>{await a.match(n)||await a.add(n)}))})())});self.addEventListener("activate",e=>{self.clients.claim(),e.waitUntil(I())});async function I(){const e=await caches.keys();for(const s of e)s!==u&&s!==r&&s!==A&&await caches.delete(s);const t=await caches.open(r),a=await t.keys(),n=N.concat(b).map(s=>new URL(s,self.registration.scope).href);for(const s of a)n.some(i=>i===s.url)||t.delete(s)}self.addEventListener("fetch",e=>{e.request.method==="GET"&&e.respondWith(D(e))});function C(e){if(e.pathname.startsWith("/_matrix/media/r0/thumbnail/")||e.pathname.startsWith("/_matrix/client/v1/media/thumbnail/")){const t=parseInt(e.searchParams.get("width"),10),a=parseInt(e.searchParams.get("height"),10);if(t<=50&&a<=50)return!0}return!1}const m=new URL(self.registration.scope);let w=new AbortController;async function D({request:e,clientId:t}){try{if(e.url.includes("config.json")||/theme-.+\.json/.test(e.url))return F(e);const a=new URL(e.url);if(a.origin===m.origin&&a.pathname===m.pathname&&(e=new Request(new URL("index.html",m.href))),a.pathname.indexOf("/_matrix/client/v1/media")===0){const i=await self.clients.get(t),{accessToken:o,homeserver:p}=await l(i,"getAuthInfo",{});if(!o)throw new Error("Token returned from getAuthInfo message in sw.js is null!");if(!p)throw new Error("homeserver returned from getAuthInfo message in sw.js is null!");if(new URL(p).origin===a.origin){const h=new Headers(e.headers);h.set("authorization",`Bearer ${o}`),e=new Request(e,{mode:"cors",credentials:"omit",headers:h})}}let s=await U(e);return s||(C(a)?s=await fetch(e,{signal:w.signal,mode:"cors",credentials:"omit"}):s=await fetch(e,{signal:w.signal}),await L(e,s)),s}catch(a){throw a.name!=="TypeError"&&a.name!=="AbortError"&&console.error("error in service worker",a),a}}async function F(e){let t=await U(e);const a=O(e);return t||await a}async function O(e){const t=await fetch(e,{signal:w.signal,headers:{"Cache-Control":"no-cache"}});return L(e,t.clone()),t}async function L(e,t){if(t.status>=400)return;const a=new URL(e.url),n=self.registration.scope;if(C(a))(await caches.open(A)).put(e,t.clone());else if(e.url.startsWith(n)){let s=e.url.substr(n.length),i;b.includes(s)?i=r:H.includes(s)&&(i=u),i&&await(await caches.open(i)).put(e,t.clone())}}async function U(e){let a=await(await caches.open(u)).match(e);if(a||(a=await(await caches.open(r)).match(e),a))return a;const s=new URL(e.url);if(C(s)){const i=await caches.open(A);a=await i.match(e),(a==null?void 0:a.status)>=400&&(await i.delete(e),a=null)}return a}self.addEventListener("message",e=>{var n;const t=s=>e.source.postMessage({replyTo:e.data.id,payload:s}),{replyTo:a}=e.data;if(a){const s=E.get(a);s&&(E.delete(a),s(e.data.payload))}else switch((n=e.data)==null?void 0:n.type){case"version":t({version:"0.5.1",buildHash:"3895512102"});break;case"skipWaiting":self.skipWaiting();break;case"haltRequests":e.waitUntil(v().finally(()=>t()));break;case"closeSession":e.waitUntil(M(e.data.payload.sessionId,e.source.id).finally(()=>t()));break}});const y="new_message";async function P(e){if(e.notification.tag!==y){console.log("clicked notif with tag",e.notification.tag);return}const{sessionId:t,roomId:a}=e.notification.data,s=`${`#/session/${t}`}/room/${a}`,i=await T(async o=>await l(o,"hasSessionOpen",{sessionId:t}));if(i){if(console.log("notificationclick: client has session open, showing room there"),i.postMessage({type:"openRoom",payload:{roomId:a}}),"focus"in i)try{await i.focus()}catch(o){console.error(o)}}else if(self.clients.openWindow){console.log("notificationclick: no client found with session open, opening new window");const o=new URL(`./${s}`,m).href;await self.clients.openWindow(o)}}self.addEventListener("notificationclick",e=>{e.notification.close(),e.waitUntil(P(e))});async function W(e){var n;console.log("got a push message",e);const t=e.session_id;let a=e.sender_display_name||e.sender;if(a&&e.event_id){const s=e.room_id;if(!!await T(async c=>{if(c.visibilityState==="visible"&&c.focused)return await l(c,"hasRoomOpen",{sessionId:t,roomId:s})})){console.log("client is focused, room is open, don't show notif");return}const o=Array.from(await self.registration.getNotifications({tag:y})),S=o.filter(c=>c.data.roomId===s).some(c=>c.data.multi),h=o.some(c=>!c.data.multi),f=e.room_name||e.room_alias;let R=!1,d,g;if(S){console.log("already have a multi message, don't do anything");return}else h?(console.log("showing multi message notification"),R=!0,d=f||a,g="New messages"):(console.log("showing new message notification"),f&&f!==a?d=`${a} in ${f}`:d=a,g=((n=e.content)==null?void 0:n.body)||"New message");await self.registration.showNotification(d,{body:g,data:{sessionId:t,roomId:s,multi:R},tag:y,badge:k})}}self.addEventListener("push",e=>{e.waitUntil(W(e.data.json()))});async function M(e,t){const a=await self.clients.matchAll();await Promise.all(a.map(async n=>{n.id!==t&&await l(n,"closeSession",{sessionId:e})}))}async function v(){const e=await self.clients.matchAll({type:"window"});await Promise.all(e.map(t=>l(t,"haltRequests"))),w.abort()}const E=new Map;let _=0;function l(e,t,a){_+=1;const n=_,s=new Promise(i=>{E.set(n,i)});return e.postMessage({type:t,id:n,payload:a}),s}async function T(e){const t=await self.clients.matchAll({type:"window"});for(const a of t)if(await e(a))return a} +//# sourceMappingURL=sw.js.map diff --git a/hydrogen/sw.js.map b/hydrogen/sw.js.map new file mode 100644 index 0000000..44a587b --- /dev/null +++ b/hydrogen/sw.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sw.js","sources":["../src/platform/web/sw.js"],"sourcesContent":["/*\nCopyright 2020 Bruno Windels \nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nconst NOTIFICATION_BADGE_ICON = \"icon.png\";\n\n// These are replaced by rollup plugins\nconst UNHASHED_PRECACHED_ASSETS = DEFINE_UNHASHED_PRECACHED_ASSETS;\nconst HASHED_PRECACHED_ASSETS = DEFINE_HASHED_PRECACHED_ASSETS;\nconst HASHED_CACHED_ON_REQUEST_ASSETS = DEFINE_HASHED_CACHED_ON_REQUEST_ASSETS;\n\nconst unhashedCacheName = `hydrogen-assets-${DEFINE_GLOBAL_HASH}`;\nconst hashedCacheName = `hydrogen-assets`;\nconst mediaThumbnailCacheName = `hydrogen-media-thumbnails-v2`;\n\nself.addEventListener(\"install\", function (e) {\n e.waitUntil(\n (async () => {\n const unhashedCache = await caches.open(unhashedCacheName);\n await unhashedCache.addAll(UNHASHED_PRECACHED_ASSETS);\n const hashedCache = await caches.open(hashedCacheName);\n await Promise.all(\n HASHED_PRECACHED_ASSETS.map(async (asset) => {\n if (!(await hashedCache.match(asset))) {\n await hashedCache.add(asset);\n }\n })\n );\n })()\n );\n});\n\nself.addEventListener(\"activate\", (event) => {\n // on a first page load/sw install,\n // start using the service worker on all pages straight away\n self.clients.claim();\n event.waitUntil(purgeOldCaches());\n});\n\nasync function purgeOldCaches() {\n // remove any caches we don't know about\n const keyList = await caches.keys();\n for (const key of keyList) {\n if (\n key !== unhashedCacheName &&\n key !== hashedCacheName &&\n key !== mediaThumbnailCacheName\n ) {\n await caches.delete(key);\n }\n }\n // remove the cache for any old hashed resource\n const hashedCache = await caches.open(hashedCacheName);\n const keys = await hashedCache.keys();\n const hashedAssetURLs = HASHED_PRECACHED_ASSETS.concat(\n HASHED_CACHED_ON_REQUEST_ASSETS\n ).map((a) => new URL(a, self.registration.scope).href);\n\n for (const request of keys) {\n if (!hashedAssetURLs.some((url) => url === request.url)) {\n hashedCache.delete(request);\n }\n }\n}\n\nself.addEventListener(\"fetch\", (event) => {\n /*\n service worker shouldn't handle xhr uploads because otherwise\n the progress events won't fire.\n This has to do with xhr not being supported in service workers.\n */\n if (event.request.method === \"GET\") {\n event.respondWith(handleRequest(event));\n }\n});\n\nfunction isCacheableThumbnail(url) {\n if (\n url.pathname.startsWith(\"/_matrix/media/r0/thumbnail/\") ||\n url.pathname.startsWith(\"/_matrix/client/v1/media/thumbnail/\")\n ) {\n const width = parseInt(url.searchParams.get(\"width\"), 10);\n const height = parseInt(url.searchParams.get(\"height\"), 10);\n if (width <= 50 && height <= 50) {\n return true;\n }\n }\n return false;\n}\n\nconst baseURL = new URL(self.registration.scope);\nlet pendingFetchAbortController = new AbortController();\n\nasync function handleRequest({ request, clientId }) {\n try {\n // Special caching strategy for config.json and theme json files\n if (\n request.url.includes(\"config.json\") ||\n /theme-.+\\.json/.test(request.url)\n ) {\n return handleStaleWhileRevalidateRequest(request);\n }\n\n // rewrite / to /index.html so it hits the cache\n const url = new URL(request.url);\n if (\n url.origin === baseURL.origin &&\n url.pathname === baseURL.pathname\n ) {\n request = new Request(new URL(\"index.html\", baseURL.href));\n }\n\n // Add access token for authenticated media endpoints\n const pathNameStartsWithMediaPrefix =\n url.pathname.indexOf(\"/_matrix/client/v1/media\") === 0;\n if (pathNameStartsWithMediaPrefix) {\n const client = await self.clients.get(clientId);\n const { accessToken, homeserver } = await sendAndWaitForReply(\n client,\n \"getAuthInfo\",\n {}\n );\n if (!accessToken) {\n throw new Error(\n \"Token returned from getAuthInfo message in sw.js is null!\"\n );\n }\n if (!homeserver) {\n throw new Error(\n \"homeserver returned from getAuthInfo message in sw.js is null!\"\n );\n }\n // Is this request actually going to the homeserver?\n const isRequestForHomeserver =\n new URL(homeserver).origin === url.origin;\n if (isRequestForHomeserver) {\n // Only add the access-token if we know that this request\n // is going to the homeserver.\n const headers = new Headers(request.headers);\n headers.set(\"authorization\", `Bearer ${accessToken}`);\n request = new Request(request, {\n mode: \"cors\",\n credentials: \"omit\",\n headers,\n });\n }\n }\n\n let response = await readCache(request);\n if (!response) {\n // use cors so the resource in the cache isn't opaque and uses up to 7mb\n // https://developers.google.com/web/tools/chrome-devtools/progressive-web-apps?utm_source=devtools#opaque-responses\n if (isCacheableThumbnail(url)) {\n response = await fetch(request, {\n signal: pendingFetchAbortController.signal,\n mode: \"cors\",\n credentials: \"omit\",\n });\n } else {\n response = await fetch(request, {\n signal: pendingFetchAbortController.signal,\n });\n }\n await updateCache(request, response);\n }\n return response;\n } catch (err) {\n if (err.name !== \"TypeError\" && err.name !== \"AbortError\") {\n console.error(\"error in service worker\", err);\n }\n throw err;\n }\n}\n\n/**\n * Stale-while-revalidate caching for certain files\n * see https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate\n */\nasync function handleStaleWhileRevalidateRequest(request) {\n let response = await readCache(request);\n const networkResponsePromise = fetchAndUpdateCache(request);\n if (response) {\n return response;\n } else {\n return await networkResponsePromise;\n }\n}\n\nasync function fetchAndUpdateCache(request) {\n const response = await fetch(request, {\n signal: pendingFetchAbortController.signal,\n headers: {\n \"Cache-Control\": \"no-cache\",\n },\n });\n updateCache(request, response.clone());\n return response;\n}\n\nasync function updateCache(request, response) {\n // don't write error responses to the cache\n if (response.status >= 400) {\n return;\n }\n const url = new URL(request.url);\n const baseURL = self.registration.scope;\n if (isCacheableThumbnail(url)) {\n const cache = await caches.open(mediaThumbnailCacheName);\n cache.put(request, response.clone());\n } else if (request.url.startsWith(baseURL)) {\n let assetName = request.url.substr(baseURL.length);\n let cacheName;\n if (HASHED_CACHED_ON_REQUEST_ASSETS.includes(assetName)) {\n cacheName = hashedCacheName;\n } else if (UNHASHED_PRECACHED_ASSETS.includes(assetName)) {\n cacheName = unhashedCacheName;\n }\n if (cacheName) {\n const cache = await caches.open(cacheName);\n await cache.put(request, response.clone());\n }\n }\n}\n\nasync function readCache(request) {\n const unhashedCache = await caches.open(unhashedCacheName);\n let response = await unhashedCache.match(request);\n if (response) {\n return response;\n }\n const hashedCache = await caches.open(hashedCacheName);\n response = await hashedCache.match(request);\n if (response) {\n return response;\n }\n\n const url = new URL(request.url);\n if (isCacheableThumbnail(url)) {\n const mediaThumbnailCache = await caches.open(mediaThumbnailCacheName);\n response = await mediaThumbnailCache.match(request);\n // added in 0.1.26, remove previously cached error responses, remove this in some time\n if (response?.status >= 400) {\n await mediaThumbnailCache.delete(request);\n response = null;\n }\n }\n return response;\n}\n\nself.addEventListener(\"message\", (event) => {\n const reply = (payload) =>\n event.source.postMessage({ replyTo: event.data.id, payload });\n const { replyTo } = event.data;\n if (replyTo) {\n const resolve = pendingReplies.get(replyTo);\n if (resolve) {\n pendingReplies.delete(replyTo);\n resolve(event.data.payload);\n }\n } else {\n switch (event.data?.type) {\n case \"version\":\n reply({\n version: DEFINE_VERSION,\n buildHash: DEFINE_GLOBAL_HASH,\n });\n break;\n case \"skipWaiting\":\n self.skipWaiting();\n break;\n case \"haltRequests\":\n event.waitUntil(haltRequests().finally(() => reply()));\n break;\n case \"closeSession\":\n event.waitUntil(\n closeSession(\n event.data.payload.sessionId,\n event.source.id\n ).finally(() => reply())\n );\n break;\n }\n }\n});\n\nconst NOTIF_TAG_NEW_MESSAGE = \"new_message\";\n\nasync function openClientFromNotif(event) {\n if (event.notification.tag !== NOTIF_TAG_NEW_MESSAGE) {\n console.log(\"clicked notif with tag\", event.notification.tag);\n return;\n }\n const { sessionId, roomId } = event.notification.data;\n const sessionHash = `#/session/${sessionId}`;\n const roomHash = `${sessionHash}/room/${roomId}`;\n const clientWithSession = await findClient(async (client) => {\n return await sendAndWaitForReply(client, \"hasSessionOpen\", {\n sessionId,\n });\n });\n if (clientWithSession) {\n console.log(\n \"notificationclick: client has session open, showing room there\"\n );\n // use a message rather than clientWithSession.navigate here as this refreshes the page on chrome\n clientWithSession.postMessage({\n type: \"openRoom\",\n payload: { roomId },\n });\n if (\"focus\" in clientWithSession) {\n try {\n await clientWithSession.focus();\n } catch (err) {\n console.error(err);\n } // I've had this throw on me on Android\n }\n } else if (self.clients.openWindow) {\n console.log(\n \"notificationclick: no client found with session open, opening new window\"\n );\n const roomURL = new URL(`./${roomHash}`, baseURL).href;\n await self.clients.openWindow(roomURL);\n }\n}\n\nself.addEventListener(\"notificationclick\", (event) => {\n event.notification.close();\n event.waitUntil(openClientFromNotif(event));\n});\n\nasync function handlePushNotification(n) {\n console.log(\"got a push message\", n);\n const sessionId = n.session_id;\n let sender = n.sender_display_name || n.sender;\n if (sender && n.event_id) {\n const roomId = n.room_id;\n const hasFocusedClientOnRoom = !!(await findClient(async (client) => {\n if (client.visibilityState === \"visible\" && client.focused) {\n return await sendAndWaitForReply(client, \"hasRoomOpen\", {\n sessionId,\n roomId,\n });\n }\n }));\n if (hasFocusedClientOnRoom) {\n console.log(\"client is focused, room is open, don't show notif\");\n return;\n }\n const newMessageNotifs = Array.from(\n await self.registration.getNotifications({\n tag: NOTIF_TAG_NEW_MESSAGE,\n })\n );\n const notifsForRoom = newMessageNotifs.filter(\n (n) => n.data.roomId === roomId\n );\n const hasMultiNotification = notifsForRoom.some((n) => n.data.multi);\n const hasSingleNotifsForRoom = newMessageNotifs.some(\n (n) => !n.data.multi\n );\n const roomName = n.room_name || n.room_alias;\n let multi = false;\n let label;\n let body;\n if (hasMultiNotification) {\n console.log(\"already have a multi message, don't do anything\");\n return;\n } else if (hasSingleNotifsForRoom) {\n console.log(\"showing multi message notification\");\n multi = true;\n label = roomName || sender;\n body = \"New messages\";\n } else {\n console.log(\"showing new message notification\");\n if (roomName && roomName !== sender) {\n label = `${sender} in ${roomName}`;\n } else {\n label = sender;\n }\n body = n.content?.body || \"New message\";\n }\n await self.registration.showNotification(label, {\n body,\n data: { sessionId, roomId, multi },\n tag: NOTIF_TAG_NEW_MESSAGE,\n badge: NOTIFICATION_BADGE_ICON,\n });\n }\n // we could consider hiding previous notifications here based on the unread count\n // (although we can't really figure out which notifications to hide) and also hiding\n // notifications makes it hard to ensure we always show a notification after a push message\n // when no client is visible, see https://goo.gl/yqv4Q4\n}\n\nself.addEventListener(\"push\", (event) => {\n event.waitUntil(handlePushNotification(event.data.json()));\n});\n\nasync function closeSession(sessionId, requestingClientId) {\n const clients = await self.clients.matchAll();\n await Promise.all(\n clients.map(async (client) => {\n if (client.id !== requestingClientId) {\n await sendAndWaitForReply(client, \"closeSession\", {\n sessionId,\n });\n }\n })\n );\n}\n\nasync function haltRequests() {\n // first ask all clients to block sending any more requests\n const clients = await self.clients.matchAll({ type: \"window\" });\n await Promise.all(\n clients.map((client) => {\n return sendAndWaitForReply(client, \"haltRequests\");\n })\n );\n // and only then abort the current requests\n pendingFetchAbortController.abort();\n}\n\nconst pendingReplies = new Map();\nlet messageIdCounter = 0;\nfunction sendAndWaitForReply(client, type, payload) {\n messageIdCounter += 1;\n const id = messageIdCounter;\n const promise = new Promise((resolve) => {\n pendingReplies.set(id, resolve);\n });\n client.postMessage({ type, id, payload });\n return promise;\n}\n\nasync function findClient(predicate) {\n const clientList = await self.clients.matchAll({ type: \"window\" });\n for (const client of clientList) {\n if (await predicate(client)) {\n return client;\n }\n }\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file

>>0?e+1|0:e;v=se(Ia,Ja,18,0);f=v+d|0;d=$+e|0;e=f;f=e>>>0>>0?d+1|0:d;d=m>>25;v=(m&33554431)<<7|R>>>25;m=v+e|0;e=d+f|0;d=m;e=d>>>0>>0?e+1|0:e;v=e>>31>>>6|0;m=v+d|0;S=m;f=m>>>0>>0?e+1|0:e;m=f;v=e;e=S&-67108864;f=v-((e>>>0>d>>>0)+f|0)|0;v=d-e|0;P=f;d=za+Ta|0;f=y+na|0;d=f>>>0>>0?d+1|0:d;e=se(na,za,18,0);f=e+f|0;d=$+d|0;d=e>>>0>f>>>0?d+1|0:d;e=j>>25;y=(j&33554431)<<7|H>>>25;j=y+f|0;f=d+e|0;d=j;f=d>>>0>>0?f+1|0:f;y=f>>31>>>6|0;j=d+y|0;e=f;T=j;e=j>>>0>>0?e+1|0:e;j=e;H=T&-67108864;J=d-H|0;R=J+v|0;d=f-((d>>>0>>0)+e|0)|0;e=d+P|0;F[g+1984>>2]=R;F[g+1988>>2]=J>>>0>R>>>0?e+1|0:e;F[g+1824>>2]=J-v;F[g+1828>>2]=d-((v>>>0>J>>>0)+P|0);e=Ha+Za|0;d=O+Ga|0;e=d>>>0>>0?e+1|0:e;y=se(Ga,Ha,18,0);d=y+d|0;f=$+e|0;f=d>>>0>>0?f+1|0:f;e=d;d=m>>26;m=(m&67108863)<<6|S>>>26;e=e+m|0;d=d+f|0;f=e;d=e>>>0>>0?d+1|0:d;y=d>>31>>>7|0;m=e+y|0;P=m;e=m>>>0>>0?d+1|0:d;m=e;e=P&-33554432;d=d-(m+(e>>>0>f>>>0)|0)|0;y=f-e|0;v=d;d=ra+Sa|0;f=x+ma|0;d=f>>>0>>0?d+1|0:d;x=se(ma,ra,18,0);e=x+f|0;f=$+d|0;f=e>>>0>>0?f+1|0:f;d=e;e=j>>26;j=(j&67108863)<<6|T>>>26;d=d+j|0;e=e+f|0;f=d;e=d>>>0>>0?e+1|0:e;d=e;x=d>>31>>>7|0;j=x+f|0;J=j;d=j>>>0>>0?d+1|0:d;j=d;T=J&-33554432;O=f-T|0;S=O+y|0;d=e-((f>>>0>>0)+d|0)|0;e=d+v|0;F[g+1992>>2]=S;F[g+1996>>2]=O>>>0>S>>>0?e+1|0:e;F[g+1832>>2]=O-y;F[g+1836>>2]=d-((y>>>0>O>>>0)+v|0);d=Fa+Ya|0;f=N+Ea|0;d=f>>>0>>0?d+1|0:d;x=se(Ea,Fa,18,0);f=x+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;d=f;f=m>>25;x=(m&33554431)<<7|P>>>25;m=d+x|0;d=e+f|0;f=m;d=f>>>0>>0?d+1|0:d;x=d>>31>>>6|0;m=f+x|0;N=m;e=m>>>0>>0?d+1|0:d;m=e;e=N&-67108864;d=d-(m+(e>>>0>f>>>0)|0)|0;x=f-e|0;y=d;f=la+Ra|0;d=u+ka|0;f=d>>>0>>0?f+1|0:f;u=se(ka,la,18,0);d=u+d|0;e=$+f|0;e=d>>>0>>0?e+1|0:e;f=d;d=j>>25;j=(j&33554431)<<7|J>>>25;f=f+j|0;e=d+e|0;e=f>>>0>>0?e+1|0:e;d=e;u=d>>31>>>6|0;j=f+u|0;O=j;d=j>>>0>>0?d+1|0:d;j=d;J=O&-67108864;v=f-J|0;P=v+x|0;f=e-((f>>>0>>0)+d|0)|0;d=f+y|0;F[g+2e3>>2]=P;F[g+2004>>2]=v>>>0>P>>>0?d+1|0:d;F[g+1840>>2]=v-x;F[g+1844>>2]=f-((v>>>0>>0)+y|0);d=Da+Xa|0;f=Q+Ca|0;d=f>>>0>>0?d+1|0:d;u=se(Ca,Da,18,0);f=u+f|0;e=$+d|0;e=f>>>0>>0?e+1|0:e;d=e;e=m>>26;u=(m&67108863)<<6|N>>>26;m=u+f|0;f=d+e|0;e=m;f=e>>>0>>0?f+1|0:f;d=f;u=d>>31>>>7|0;m=u+e|0;v=m;d=m>>>0>>0?d+1|0:d;m=d;u=f;f=v&-33554432;d=u-((f>>>0>e>>>0)+d|0)|0;u=e-f|0;x=d;e=ia+Qa|0;d=A+ha|0;e=d>>>0>>0?e+1|0:e;f=se(ha,ia,18,0);d=f+d|0;e=$+e|0;e=d>>>0>>0?e+1|0:e;f=d;d=j>>26;j=(j&67108863)<<6|O>>>26;f=f+j|0;d=d+e|0;d=f>>>0>>0?d+1|0:d;e=f;A=d>>31>>>7|0;j=A+e|0;Q=j;f=j>>>0>>0?d+1|0:d;j=f;O=Q&-33554432;y=e-O|0;N=y+u|0;f=d-((e>>>0>>0)+f|0)|0;d=f+x|0;F[g+2008>>2]=N;F[g+2012>>2]=y>>>0>N>>>0?d+1|0:d;F[g+1848>>2]=y-u;F[g+1852>>2]=f-((u>>>0>y>>>0)+x|0);f=Ba+Wa|0;d=W+Aa|0;f=d>>>0>>0?f+1|0:f;A=se(Aa,Ba,18,0);e=A+d|0;d=$+f|0;d=e>>>0>>0?d+1|0:d;f=e;e=m>>25;m=(m&33554431)<<7|v>>>25;f=f+m|0;e=d+e|0;e=f>>>0>>0?e+1|0:e;d=e;A=d>>31>>>6|0;m=f+A|0;y=m;d=m>>>0>>0?d+1|0:d;m=d;u=e;e=y&-67108864;d=u-((e>>>0>f>>>0)+d|0)|0;A=f-e|0;u=d;e=ea+Pa|0;d=B+da|0;e=d>>>0>>0?e+1|0:e;B=se(da,ea,18,0);f=B+d|0;d=$+e|0;d=f>>>0>>0?d+1|0:d;e=f;f=j>>25;j=(j&33554431)<<7|Q>>>25;e=e+j|0;d=d+f|0;f=e;d=e>>>0>>0?d+1|0:d;B=d>>31>>>6|0;j=e+B|0;v=j;e=j>>>0>>0?d+1|0:d;j=e;Q=v&-67108864;x=f-Q|0;W=x+A|0;d=d-((f>>>0>>0)+e|0)|0;f=d+u|0;F[g+2016>>2]=W;F[g+2020>>2]=x>>>0>W>>>0?f+1|0:f;F[g+1856>>2]=x-A;F[g+1860>>2]=d-((x>>>0>>0)+u|0);f=(m&67108863)<<6|y>>>26;d=f+Va|0;e=(m>>26)+M|0;e=d>>>0>>0?e+1|0:e;f=d;m=d;d=e;B=d>>31>>>7|0;f=B+f|0;x=f;d=f>>>0>>0?d+1|0:d;f=d;u=e;e=x&-33554432;d=u-((e>>>0>m>>>0)+d|0)|0;B=m-e|0;A=d;d=j>>26;j=(j&67108863)<<6|v>>>26;m=j+Oa|0;e=d+t|0;e=j>>>0>m>>>0?e+1|0:e;d=e;t=d>>31>>>7|0;j=m+t|0;y=j;d=j>>>0>>0?d+1|0:d;j=d;M=y&-33554432;u=m-M|0;v=u+B|0;e=e-((m>>>0>>0)+d|0)|0;d=e+A|0;F[g+2024>>2]=v;F[g+2028>>2]=v>>>0>>0?d+1|0:d;F[g+1864>>2]=u-B;F[g+1868>>2]=e-((u>>>0>>0)+A|0);d=o&-33554432;e=c-d|0;m=Y-((c>>>0>>0)+X|0)|0;c=f;f=f>>25;o=(c&33554431)<<7|x>>>25;d=p&-67108864;p=b-d|0;c=o+p|0;d=(V-((b>>>0>>0)+E|0)|0)+f|0;d=c>>>0