/**
 * Minified by jsDelivr using Terser v5.39.0.
 * Original file: /npm/@thirdroom/hydrogen-view-sdk@0.1.2/lib-build/hydrogen.cjs.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
"use strict";var _c,_d,__defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(e,t,s)=>t in e?__defProp(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,__spreadValues=(e,t)=>{for(var s in t||(t={}))__hasOwnProp.call(t,s)&&__defNormalProp(e,s,t[s]);if(__getOwnPropSymbols)for(var s of __getOwnPropSymbols(t))__propIsEnum.call(t,s)&&__defNormalProp(e,s,t[s]);return e},__spreadProps=(e,t)=>__defProps(e,__getOwnPropDescs(t)),__objRest=(e,t)=>{var s={};for(var i in e)__hasOwnProp.call(e,i)&&t.indexOf(i)<0&&(s[i]=e[i]);if(null!=e&&__getOwnPropSymbols)for(var i of __getOwnPropSymbols(e))t.indexOf(i)<0&&__propIsEnum.call(e,i)&&(s[i]=e[i]);return s};Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var anotherjson=require("another-json");require("@matrix-org/olm/olm.js");var base64=require("base64-arraybuffer"),DOMPurify=require("dompurify"),pkg=require("off-color");function _interopDefaultLegacy(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});return e&&Object.keys(e).forEach((function(s){if("default"!==s){var i=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,i.get?i:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var anotherjson__default=_interopDefaultLegacy(anotherjson),base64__default=_interopDefaultLegacy(base64),DOMPurify__default=_interopDefaultLegacy(DOMPurify),pkg__namespace=_interopNamespace(pkg),LogLevel=(e=>(e[e.All=1]="All",e[e.Debug=2]="Debug",e[e.Detail=3]="Detail",e[e.Info=4]="Info",e[e.Warn=5]="Warn",e[e.Error=6]="Error",e[e.Fatal=7]="Fatal",e[e.Off=8]="Off",e))(LogLevel||{});class LogFilter{constructor(e){this._parentFilter=e}filter(e,t){return!(this._parentFilter&&!this._parentFilter.filter(e,t))&&!(void 0!==this._min&&!Array.isArray(t)&&e.logLevel<this._min)}minLevel(e){return this._min=e,this}}class LogItem{constructor(e,t,s,i){this._discard=!1,this._logger=s,this.start=s._now(),this._values="string"==typeof e?{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(){return this.end?this.end-this.start:void 0}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+(null!=i?i:0)}),0):0}log(e,t){const s=this.child(e,t);return s.end=s.start,s}set(e,t){if("object"==typeof e){const t=e;Object.assign(this._values,t)}else this._values[e]=t;return this}serialize(e,t,s){if(this._discard)return;if(this._filterCreator)try{e=this._filterCreator(new LogFilter(e),this)}catch(e){console.error("Error creating log filter",e)}let i=null;if(this._children&&(i=this._children.reduce(((t,s)=>{const i=s.serialize(e,this.start,!1);return i&&(null===t&&(t=[]),t.push(i)),t}),null)),e&&!e.filter(this,i))return;const r={s:"number"==typeof t?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("\n")[0]}),s&&(r.f=!0),i&&(r.c=i),r}run(e){try{const t=e(this);return t instanceof Promise?t.then((e=>(this.finish(),e)),(e=>{throw this.catch(e)})):(this.finish(),t)}catch(e){throw this.catch(e)}}finish(){if(void 0===this.end){if(this._children)for(const e of this._children)e.finish();this.end=this._logger._now()}}forceFinish(){this.finish()}get level(){return LogLevel}catch(e){return this.error=e,this.logLevel=LogLevel.Error,this.finish(),e}child(e,t,s){t||(t=this.logLevel||LogLevel.Info);const i=new LogItem(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 Logger{constructor({platform:e}){this._openItems=new Set,this.reporters=[],this._platform=e}log(e,t=LogLevel.Info){const s=new LogItem(e,t,this);return s.end=s.start,this._persistItem(s,void 0,!1),s}child(e,t=LogLevel.Info,s){const i=new DeferredPersistRootLogItem(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=LogLevel.Info);const r=new LogItem(e,s,this);return this._run(r,t,s,!1,i),r}run(e,t,s,i){void 0===s&&(s=LogLevel.Info);const r=new LogItem(e,s,this);return this._run(r,t,s,!0,i)}_run(e,t,s,i,r){this._openItems.add(e);const n=()=>{let t=new LogFilter;if(r)try{t=r(t,e)}catch(e){console.error("Error while creating log filter",e)}else t=t.minLevel(s);try{this._persistItem(e,t,!1)}catch(e){console.error("Could not persist log item",e)}this._openItems.delete(e)};try{let s=e.run(t);if(s instanceof Promise){if(s=s.then((e=>(n(),e)),(e=>{if(n(),i)throw e})),i)return s}else if(n(),i)return s}catch(e){if(n(),i)throw e}}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 LogFilter,!0)}catch(e){console.error("Could not serialize log item",e)}}this._openItems.clear()}_removeItemFromOpenList(e){this._openItems.delete(e)}_persistItem(e,t,s){for(var i=0;i<this.reporters.length;i+=1)this.reporters[i].reportItem(e,t,s)}get level(){return LogLevel}_now(){return this._platform.clock.now()}_createRefId(){return Math.round(this._platform.random()*Number.MAX_SAFE_INTEGER)}}class DeferredPersistRootLogItem extends LogItem{finish(){super.finish(),this._logger._persistItem(this,void 0,!1),this._logger._removeItemFromOpenList(this)}forceFinish(){super.finish()}}var StoreNames=(e=>(e.session="session",e.roomState="roomState",e.roomSummary="roomSummary",e.archivedRoomSummary="archivedRoomSummary",e.invites="invites",e.roomMembers="roomMembers",e.timelineEvents="timelineEvents",e.timelineRelations="timelineRelations",e.timelineFragments="timelineFragments",e.pendingEvents="pendingEvents",e.userIdentities="userIdentities",e.deviceKeys="deviceKeys",e.olmSessions="olmSessions",e.inboundGroupSessions="inboundGroupSessions",e.outboundGroupSessions="outboundGroupSessions",e.groupSessionDecryptions="groupSessionDecryptions",e.operations="operations",e.accountData="accountData",e.calls="calls",e.crossSigningKeys="crossSigningKeys",e))(StoreNames||{});const STORE_NAMES=Object.values(StoreNames);class StorageError extends Error{constructor(e,t=null){super(e),t&&(this.errcode=t.name),this.cause=t}get name(){return"StorageError"}}const KeyLimits={get minStorageKey(){return 0},get middleStorageKey(){return 2147483647},get maxStorageKey(){return 4294967295}};function _sourceName(e){return"objectStore"in e?`${e.objectStore.name}.${e.name}`:e.name}function _sourceDatabase(e){var t,s,i,r,n;return"objectStore"in e?null==(i=null==(s=null==(t=e.objectStore)?void 0:t.transaction)?void 0:s.db)?void 0:i.name:null==(n=null==(r=e.transaction)?void 0:r.db)?void 0:n.name}class IDBError extends StorageError{constructor(e,t,s=null){const i=t&&"source"in t?t.source:t,r=i?_sourceName(i):"",n=i?_sourceDatabase(i):"";let o=`${e} on ${n}.${r}`;s&&(o+=": ","string"==typeof s.name&&(o+=`(name: ${s.name}) `),"number"==typeof s.code&&(o+=`(code: ${s.code}) `)),s&&(o+=s.message),super(o,s),this.storeName=r,this.databaseName=n}}class IDBRequestError extends IDBError{constructor(e){const t=e.target;super("IDBRequest failed",t.source,t.error),this.errorEvent=e}preventTransactionAbort(){this.errorEvent.preventDefault()}}class IDBRequestAttemptError extends IDBError{constructor(e,t,s,i){super(`${e}(${i.map((e=>JSON.stringify(e))).join(", ")}) failed`,t,s)}}class AbortError extends Error{get name(){return"AbortError"}}const DONE={done:!0},NOT_DONE={done:!1};function encodeUint32(e){const t=e.toString(16);return"0".repeat(8-t.length)+t}function decodeUint32(e){return parseInt(e,16)}function openDatabase(e,t,s,i=window.indexedDB){const r=i.open(e,s);return r.onupgradeneeded=async e=>{const i=e.target,r=i.result,n=i.transaction,o=e.oldVersion;try{await t(r,n,o,s)}catch(e){try{n.abort()}catch(e){}}},reqAsPromise(r)}function reqAsPromise(e){return new Promise(((t,s)=>{e.addEventListener("success",(e=>{t(e.target.result)})),e.addEventListener("error",(e=>{const t=new IDBRequestError(e);s(t)}))}))}function txnAsPromise(e){return new Promise(((t,s)=>{e.addEventListener("complete",(()=>{t()})),e.addEventListener("abort",(e=>{s(new AbortError)}))}))}function iterateCursor(e,t){return new Promise(((s,i)=>{e.onerror=e=>{i(new IDBRequestError(e))},e.onsuccess=e=>{const i=e.target.result;if(!i)return void s(!1);const r=t(i.value,i.key,i),n=null==r?void 0:r.done,o=null==r?void 0:r.jumpTo;n?s(!0):o?i.continue(o):i.continue()}})).catch((e=>{throw new StorageError("iterateCursor failed",e)}))}async function fetchResults(e,t){const s=[];return await iterateCursor(e,(e=>(s.push(e),{done:t(s)}))),s}class IDBLogPersister{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()),null!=(t=this.options.flushInterval)?t:6e4)}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 t=e.transaction(["logs"],"readonly").objectStore("logs"),s=await fetchResults(t.openCursor(),(()=>!1)),i=this.getSerializedOpenItems(),r=s.concat(this._queuedItems).concat(i);return new IDBLogExport(r,this,this.options.platform)}finally{try{e.close()}catch(e){}}}dispose(){window.removeEventListener("pagehide",this,!1),this._flushInterval.dispose()}handleEvent(e){"pagehide"===e.type&&this._finishAllAndFlush()}async _tryFlush(){var e;const t=await this._openDB();try{const s=t.transaction(["logs"],"readwrite"),i=s.objectStore("logs"),r=this._queuedItems.length;for(const e of this._queuedItems)i.add(e);const n=await reqAsPromise(i.count()),o=null!=(e=this.options.limit)?e:3e3;if(n>o){let e=n-o+Math.round(.1*o);await iterateCursor(i.openCursor(),((t,s,i)=>(i.delete(),e-=1,{done:0===e})))}await txnAsPromise(s),this._queuedItems.splice(0,r)}catch(e){console.error("Could not flush logs",e)}finally{try{t.close()}catch(e){}}}_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(e){console.error("Could not load queued log items",e)}return[]}_openDB(){return openDatabase(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(e){console.error("Could not persist queued log items in localStorage, they will likely be lost",e)}}async removeItems(e){const t=await this._openDB();try{const s=t.transaction(["logs"],"readwrite"),i=s.objectStore("logs");for(const t of e)if("number"==typeof t.id)i.delete(t.id);else{const e=this._queuedItems.indexOf(t);-1===e&&this._queuedItems.splice(e,1)}await txnAsPromise(s)}finally{try{t.close()}catch(e){}}}getSerializedOpenItems(){const e=[];if(!this.logger)return e;const t=new LogFilter;for(const s of this.logger.getOpenRootItems()){const i=this.prepareItemForQueue(s,t,!1);i&&e.push(i)}return e}}class IDBLogExport{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 e;const t={formatVersion:1,appVersion:null==(e=this._platform.updateService)?void 0:e.version,platform:this._platform.description,items:this._items.map((e=>JSON.parse(e.json)))};return JSON.stringify(t)}}class ConsoleReporter{reportItem(e){printToConsole(e)}setLogger(e){this.logger=e}printOpenItems(){if(this.logger)for(const e of this.logger.getOpenRootItems())this.reportItem(e)}}const excludedKeysFromTable=["l","id"];function filterValues(e){return Object.entries(e).filter((([e])=>!excludedKeysFromTable.includes(e))).reduce(((e,[t,s])=>((e=e||{})[t]=s,e)),null)}function hasChildWithError(e){if(e.error)return!0;if(e.children)for(const t of e.children)if(hasChildWithError(t))return!0;return!1}function printToConsole(e){const t=`${itemCaption(e)} (@${e.start}ms, duration: ${e.duration}ms)`,s=filterValues(e.values),i=e.children||s;if(i?(hasChildWithError(e)?console.group(t):console.groupCollapsed(t),e.error&&console.error(e.error)):e.error?console.error(e.error):console.log(t),s&&console.table(s),e.children)for(const t of e.children)printToConsole(t);i&&console.groupEnd()}function itemCaption(e){return"network"===e.values.t?`${e.values.method} ${e.values.url}`:e.values.l&&void 0!==e.values.id?`${e.values.l} ${e.values.id}`:e.values.l&&void 0!==e.values.status?`${e.values.l} (${e.values.status})`:e.values.l&&void 0!==e.values.type?`${e.values.l} (${e.values.type})`:e.values.l&&e.error?`${e.values.l} failed`:void 0!==e.values.ref?`ref ${e.values.ref}`:e.values.l||e.values.type}class WrappedError extends Error{constructor(e,t){super(`${e}: ${t.message}`),this.cause=t}get name(){return"WrappedError"}}class HomeServerError 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 ConnectionError extends Error{constructor(e,t){super(e||"ConnectionError"),this.isTimeout=t}get name(){return"ConnectionError"}}class BaseObservable{constructor(){this._handlers=new Set}onSubscribeFirst(){}onUnsubscribeLast(){}subscribe(e){return this._handlers.add(e),1===this._handlers.size&&this.onSubscribeFirst(),()=>this.unsubscribe(e)}unsubscribe(e){e&&(this._handlers.delete(e),0===this._handlers.size&&this.onUnsubscribeLast())}unsubscribeAll(){0!==this._handlers.size&&(this._handlers.clear(),this.onUnsubscribeLast())}get hasSubscriptions(){return 0!==this._handlers.size}}class BaseObservableValue$1 extends BaseObservable{emit(e){for(const t of this._handlers)t(e)}waitFor(e){return e(this.get())?new ResolvedWaitForHandle$1(Promise.resolve(this.get())):new WaitForHandle$1(this,e)}flatMap(e){return new FlatMapObservableValue$1(this,e)}}class WaitForHandle$1{constructor(e,t){this._promise=new Promise(((s,i)=>{this._reject=i,this._subscription=e.subscribe((e=>{t(e)&&(this._reject=null,s(e),this.dispose())}))}))}get promise(){return this._promise}dispose(){this._subscription&&(this._subscription(),this._subscription=null),this._reject&&(this._reject(new AbortError),this._reject=null)}}class ResolvedWaitForHandle$1{constructor(e){this.promise=e}dispose(){}}class EventObservableValue extends BaseObservableValue$1{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 ObservableValue$1 extends BaseObservableValue$1{constructor(e){super(),this._value=e}get(){return this._value}set(e){e!==this._value&&(this._value=e,this.emit(this._value))}}class FlatMapObservableValue$1 extends BaseObservableValue$1{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)return void(this.targetSubscription||(this.targetSubscription=t.subscribe((()=>this.emit(this.get())))))}this.targetSubscription&&(this.targetSubscription=this.targetSubscription())}get(){const e=this.source.get();if(!e)return;const t=this.mapper(e);return null==t?void 0:t.get()}}function pickLowestKey(e,t){return t<e}class PickMapObservableValue extends BaseObservableValue$1{constructor(e,t=pickLowestKey){super(),this.map=e,this.pickKey=t}updateKey(e){return!(void 0!==this.key&&!this.pickKey(this.key,e))&&(this.key=e,!0)}onReset(){this.key=void 0,this.emit(this.get())}onAdd(e,t){this.updateKey(e)&&this.emit(this.get())}onUpdate(e,t,s){this.emit(this.get())}onRemove(e,t){if(e===this.key){this.key=void 0;for(const[e]of this.map)this.updateKey(e);this.emit(this.get())}}onSubscribeFirst(){this.mapSubscription=this.map.subscribe(this);for(const[e]of this.map)this.updateKey(e)}onUnsubscribeLast(){this.mapSubscription(),this.key=void 0}get(){if(void 0!==this.key)return this.map.get(this.key)}}class RetainedObservableValue extends ObservableValue$1{constructor(e,t,s=()=>{}){super(e),this.freeCallback=t,this.startCallback=s}onSubscribeFirst(){this.startCallback()}onUnsubscribeLast(){super.onUnsubscribeLast(),this.freeCallback()}}class BaseObservableList extends BaseObservable{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 <https://lodash.com/>
 * Copyright JS Foundation and other contributors <https://js.foundation/>
 * Released under MIT license <https://lodash.com/license>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 */function sortedIndex(e,t,s){let i=0,r=e.length;for(;i<r;){let n=i+r>>>1,o=s(t,e[n]);o>0?i=n+1:o<0?r=n:i=r=n}return r}class ObservableArray extends BaseObservableList{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<this._items.length&&t<this._items.length){const[s]=this._items.splice(e,1);this._items.splice(t,0,s),this.emitMove(e,t,s)}}update(e,t,s=null){e<this._items.length&&(this._items[e]=t,this.emitUpdate(e,t,s))}get array(){return this._items}at(e){if(this._items&&e>=0&&e<this._items.length)return this._items[e]}get length(){return this._items.length}[Symbol.iterator](){return this._items.values()}}function findAndUpdateInArray(e,t,s,i){const r=t.findIndex(e);if(-1!==r){const e=t[r],n=i(e);return!1!==n&&s.emitUpdate(r,e,n),!0}return!1}class SortedArray extends BaseObservableList{constructor(e){super(),this._items=[],this._comparator=e}setManyUnsorted(e){this.setManySorted(e)}setManySorted(e){for(let t of e)this.set(t)}findAndUpdate(e,t){return findAndUpdateInArray(e,this._items,this,t)}getAndUpdate(e,t,s=null){const i=this.indexOf(e);if(-1!==i){const r=t(this._items[i],e);this._items[i]=r,this.emitUpdate(i,r,s)}}update(e,t=null){const s=this.indexOf(e);-1!==s&&(this._items[s]=e,this.emitUpdate(s,e,t))}indexOf(e){const t=sortedIndex(this._items,e,this._comparator);return t<this._items.length&&0===this._comparator(this._items[t],e)?t:-1}_getNext(e){let t=sortedIndex(this._items,e,this._comparator);for(;t<this._items.length&&this._comparator(this._items[t],e)<=0;)t+=1;return this.get(t)}set(e,t=null){const s=sortedIndex(this._items,e,this._comparator);s>=this._items.length||0!==this._comparator(this._items[s],e)?(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 Iterator(this)}}class Iterator{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 BaseMappedList extends BaseObservableList{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 findAndUpdateInArray(e,this._mappedValues,this,t)}get length(){return this._mappedValues.length}[Symbol.iterator](){return this._mappedValues.values()}}function runAdd(e,t,s){e._mappedValues.splice(t,0,s),e.emitAdd(t,s)}function runUpdate(e,t,s,i){const r=e._mappedValues[t];e._updater&&e._updater(r,i,s),e.emitUpdate(t,r,i)}function runRemove(e,t){const s=e._mappedValues[t];e._mappedValues.splice(t,1),e._removeCallback&&e._removeCallback(s),e.emitRemove(t,s)}function runMove(e,t,s){const i=e._mappedValues[t];e._mappedValues.splice(t,1),e._mappedValues.splice(s,0,i),e.emitMove(t,s,i)}function runReset(e){e._mappedValues=[],e.emitReset()}class MappedList extends BaseMappedList{onSubscribeFirst(){this._sourceUnsubscribe=this._sourceList.subscribe(this),this._mappedValues=[];for(const e of this._sourceList)this._mappedValues.push(this._mapper(e))}onReset(){runReset(this)}onAdd(e,t){runAdd(this,e,this._mapper(t))}onUpdate(e,t,s){this._mappedValues&&runUpdate(this,e,t,s)}onRemove(e){runRemove(this,e)}onMove(e,t){runMove(this,e,t)}onUnsubscribeLast(){this._sourceUnsubscribe()}}class AsyncMappedList extends BaseMappedList{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 AddEvent(e,t)),e+=1;this._flush()}async _flush(){if(!this._flushing){this._flushing=!0;try{for(;this._eventQueue.length;){const e=this._eventQueue.shift();await e.run(this)}}finally{this._flushing=!1}}}onReset(){this._eventQueue&&(this._eventQueue.push(new ResetEvent),this._flush())}onAdd(e,t){this._eventQueue&&(this._eventQueue.push(new AddEvent(e,t)),this._flush())}onUpdate(e,t,s){this._eventQueue&&(this._eventQueue.push(new UpdateEvent(e,t,s)),this._flush())}onRemove(e){this._eventQueue&&(this._eventQueue.push(new RemoveEvent(e)),this._flush())}onMove(e,t){this._eventQueue&&(this._eventQueue.push(new MoveEvent(e,t)),this._flush())}onUnsubscribeLast(){this._sourceUnsubscribe(),this._eventQueue=null,this._mappedValues=null}}class AddEvent{constructor(e,t){this.index=e,this.value=t}async run(e){const t=await e._mapper(this.value);runAdd(e,this.index,t)}}class UpdateEvent{constructor(e,t,s){this.index=e,this.value=t,this.params=s}async run(e){runUpdate(e,this.index,this.value,this.params)}}class RemoveEvent{constructor(e){this.index=e}async run(e){runRemove(e,this.index)}}class MoveEvent{constructor(e,t){this.fromIdx=e,this.toIdx=t}async run(e){runMove(e,this.fromIdx,this.toIdx)}}class ResetEvent{async run(e){runReset(e)}}class ConcatList extends BaseObservableList{constructor(...e){super(),this._sourceUnsubscribes=null,this._sourceLists=e}_offsetForSource(e){const t=this._sourceLists.indexOf(e);let s=0;for(let e=0;e<t;++e)s+=this._sourceLists[e].length;return s}onSubscribeFirst(){this._sourceUnsubscribes=this._sourceLists.map((e=>e.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<this._sourceLists.length;++t)e+=this._sourceLists[t].length;return e}[Symbol.iterator](){let e=0,t=this._sourceLists[0][Symbol.iterator]();return{next:()=>{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 SortedMapList extends BaseObservableList{constructor(e,t){super(),this._sourceMap=e,this._comparator=(e,s)=>t(e.value,s.value),this._sortedPairs=null,this._mapSubscription=null}onAdd(e,t){const s={key:e,value:t},i=sortedIndex(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=sortedIndex(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((t=>t.key===e));this._sortedPairs.splice(i,1);const r={key:e,value:t},n=sortedIndex(this._sortedPairs,r,this._comparator);this._sortedPairs.splice(n,0,r),i!==n&&this.emitMove(i,n,t),this.emitUpdate(n,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 BaseObservableMap extends BaseObservable{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 JoinedMap([this].concat(e))}mapValues(e,t){return new MappedMap(this,e,t)}sortValues(e){return new SortedMapList(this,e)}filterValues(e){return new FilteredMap(this,e)}observeSize(){return new MapSizeObservableValue(this)}}class ApplyMap extends BaseObservableMap{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 FilteredMap extends BaseObservableMap{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){const t=this._included;this._included=this._included||new Map;for(const[s,i]of this._source){const r=this._filter(i,s);if(this._included.set(s,r),!e){const e=!t||t.get(s);this._emitForUpdate(e,r,s,i)}}}else{if(this._included&&!e)for(const[e,t]of this._source)this._included.get(e)||this.emitAdd(e,t);this._included=void 0}}onAdd(e,t){if(this._filter){if(!this._included)throw new Error("Internal logic error: FilteredMap._included used before initialized");{const s=this._filter(t,e);if(this._included.set(e,s),!s)return}}this.emitAdd(e,t)}onRemove(e,t){var s;const i=!this._filter||(null==(s=this._included)?void 0:s.get(e));if(!this._included)throw new Error("Internal logic error: FilteredMap._included used before initialized");this._included.delete(e),i&&this.emitRemove(e,t)}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 FilterIterator(this._source,this._included)}get size(){var e;let t=0;return null==(e=this._included)||e.forEach((e=>{e&&(t+=1)})),t}get(e){const t=this._source.get(e);if(t&&this._filter(t,e))return t}}class FilterIterator{constructor(e,t){this._included=t,this._sourceIterator=e[Symbol.iterator]()}next(){for(var e;;){const t=this._sourceIterator.next();if(t.done)return t;const s=t.value[0];if(null==(e=this._included)?void 0:e.get(s))return t}}}class JoinedMap extends BaseObservableMap{constructor(e){super(),this._sources=e}onAdd(e,t,s){if(!this._isKeyAtSourceOccluded(e,t)){const i=this._getValueFromOccludedSources(e,t);void 0!==i&&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);void 0!==i&&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 SourceSubscriptionHandler(e,this).subscribe())),super.onSubscribeFirst()}_isKeyAtSourceOccluded(e,t){const s=this._sources.indexOf(e);for(let e=0;e<s;e+=1)if(void 0!==this._sources[e].get(t))return!0;return!1}_getValueFromOccludedSources(e,t){for(let s=this._sources.indexOf(e)+1;s<this._sources.length;s+=1){const e=this._sources[s].get(t);if(void 0!==e)return e}}onUnsubscribeLast(){if(super.onUnsubscribeLast(),this._subscriptions)for(const e of this._subscriptions)e.dispose()}[Symbol.iterator](){return new JoinedIterator(this._sources)}get size(){return this._sources.reduce(((e,t)=>e+t.size),0)}get(e){for(const t of this._sources){const s=t.get(e);if(s)return s}}}class JoinedIterator{constructor(e){this._sourceIndex=-1,this._encounteredKeys=new Set,this._sources=e}next(){var e;let t;for(;!t;){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=null==(e=this._currentIterator)?void 0:e.next();if(s&&!s.done){const e=s.value[0];this._encounteredKeys.has(e)||(this._encounteredKeys.add(e),t=s)}else this._currentIterator=void 0}return t}}class SourceSubscriptionHandler{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 MappedMap extends BaseObservableMap{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 i;if(!this._mappedValues)return;const r=this._mappedValues.get(e);void 0!==r&&(null==(i=this._updater)||i.call(this,s,r,t),this.emitUpdate(e,r,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 ObservableMap extends BaseObservableMap{constructor(e){super(),this._values=new Map(e)}update(e,t){const s=this._values.get(e);return void 0!==s&&(this._values.set(e,s),this.emitUpdate(e,s,t),!0)}add(e,t){return!this._values.has(e)&&(this._values.set(e,t),this.emitAdd(e,t),!0)}remove(e){const t=this._values.get(e);return void 0!==t&&(this._values.delete(e),this.emitRemove(e,t),!0)}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 ObservableValueMap extends BaseObservableMap{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 MapSizeObservableValue extends BaseObservableValue$1{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=null==(e=this.subscription)?void 0:e.call(this)}get(){return this.map.size}}function abortOnTimeout(e,t,s,i){const r=e(t);let n=!1;return r.elapsed().then((()=>{n=!0,s.abort()}),(()=>{})),i.then((e=>(r.abort(),e)),(e=>{throw r.abort(),"AbortError"===e.name&&n?new ConnectionError(`Request timed out after ${t}ms`,!0):e}))}function addCacheBuster(e,t=Math.random){return e.includes("?")?e+="&":e+="?",e+`_cacheBuster=${Math.ceil(t()*Number.MAX_SAFE_INTEGER)}`}function mapAsFormData(e){var t;const s=new FormData;for(const[i,r]of e)(null==(t=r.blob)?void 0:t.nativeBlob)&&r.name?s.set(i,r.blob.nativeBlob,r.name):s.set(i,r);return s}class RequestResult$1{constructor(e,t){this._promise=e,this._xhr=t}abort(){this._xhr.abort()}response(){return this._promise}}function createXhr(e,{method:t,headers:s,timeout:i,format:r,uploadProgress:n}){const o=new XMLHttpRequest;if(n&&o.upload.addEventListener("progress",(e=>n(e.loaded))),o.open(t,e),"buffer"===r&&(o.responseType="arraybuffer"),s)for(const[e,t]of s.entries())try{o.setRequestHeader(e,t)}catch(t){console.info(`Could not set ${e} header: ${t.message}`)}return i&&(o.timeout=i),o}function xhrAsPromise(e,t,s){return new Promise(((i,r)=>{e.addEventListener("load",(()=>i(e))),e.addEventListener("abort",(()=>r(new AbortError))),e.addEventListener("error",(()=>r(new ConnectionError(`Error ${t} ${s}`)))),e.addEventListener("timeout",(()=>r(new ConnectionError(`Timeout ${t} ${s}`,!0))))}))}function xhrRequest(e,t){let{cache:s,format:i,body:r,method:n}=t;s||(e=addCacheBuster(e));const o=createXhr(e,t),a=xhrAsPromise(o,n,e).then((e=>{const{status:t}=e;let s=null;return"buffer"===i?s=e.response:"application/json"===e.getResponseHeader("Content-Type")&&(s=JSON.parse(e.responseText)),{status:t,body:s}}));return(null==r?void 0:r.nativeBlob)&&(r=r.nativeBlob),r instanceof Map&&(r=mapAsFormData(r)),o.send(r||null),new RequestResult$1(a,o)}class RequestResult{constructor(e,t){if(t)this.promise=e,this._controller=t;else{const t=new Promise(((e,t)=>{this._controller={abort(){const e=new Error("fetch request aborted");e.name="AbortError",t(e)}}}));this.promise=Promise.race([e,t])}}abort(){this._controller.abort()}response(){return this.promise}}function createFetchRequest(e,t){return function(s,i){if(null==t?void 0:t.haltRequests)return new RequestResult(new Promise((()=>{})),{});if(null==i?void 0:i.uploadProgress)return xhrRequest(s,i);let{method:r,headers:n,body:o,timeout:a,format:l,cache:c=!1}=i;const d="function"==typeof AbortController?new AbortController:null;(null==o?void 0:o.nativeBlob)&&(o=o.nativeBlob),o instanceof Map&&(o=mapAsFormData(o));let h={method:r,body:o};if(d&&(h=Object.assign(h,{signal:d.signal})),c||(s=addCacheBuster(s)),h=Object.assign(h,{mode:"cors",credentials:"omit",referrer:"no-referrer",cache:"default"}),n){const e=new Headers;for(const[t,s]of n.entries())e.append(t,s);h.headers=e}const u=fetch(s,h).then((async e=>{const{status:t}=e;let s;try{"json"===l?s=await e.json():"buffer"===l?s=await e.arrayBuffer():"text"===l&&(s=await e.text())}catch(e){if(!("SyntaxError"===e.name&&t>=400))throw e}return{status:t,body:s}}),(e=>{if("AbortError"===e.name)throw new AbortError;if(e instanceof TypeError)throw new ConnectionError(`${r} ${s}: ${e.message}`);throw e})),m=new RequestResult(u,d);return a&&(m.promise=abortOnTimeout(e,a,m,m.promise)),m}}function noop(){}class NullLogger{constructor(){this.item=new NullLogItem(this)}log(e){return this.item}addReporter(){}get reporters(){return[]}getOpenRootItems(){return[]}forceFinish(){}child(e){return this.item}run(e,t){return t(this.item)}wrapOrRun(e,t,s){return e?e.wrap(t,s):this.run(t,s)}runDetached(e,t){return new Promise((e=>e(t(this.item)))).then(noop,noop),this.item}get level(){return LogLevel}}class NullLogItem{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((e=>e(t(this)))).then(noop,noop),this}wrapDetached(e,t){return this.refDetached()}refDetached(){}ensureRefId(){}get level(){return LogLevel}get duration(){return 0}catch(e){return e}child(){return this}finish(){}forceFinish(){}serialize(){}}const Instance=new NullLogger;class QueryTarget{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 reqAsPromise(this._target.count(e))}get(e){return reqAsPromise(this._target.get(e))}getKey(e){return this._target.supports("getKey")?reqAsPromise(this._target.getKey(e)):reqAsPromise(this._target.get(e)).then((e=>{if(e){let t=this._target.keyPath;return"string"==typeof t&&(t=[t]),t.reduce(((e,t)=>e[t]),e)}}))}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 iterateCursor(s,(e=>(i.push(e),NOT_DONE))),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 iterateCursor(t,((e,t)=>(s=t,DONE))),s}async iterateValues(e,t){const s=this._target.openCursor(e,"next");await iterateCursor(s,((e,s,i)=>({done:t(e,s,i)})))}async iterateKeys(e,t){const s=this._target.openKeyCursor(e,"next");await iterateCursor(s,((e,s,i)=>({done:t(s,i)})))}async findExistingKeys(e,t,s){const i=(e,s)=>t?-this.idbFactory.cmp(e,s):this.idbFactory.cmp(e,s),r=e.slice().sort(i),n=r[0],o=r[r.length-1],a=t?"prev":"next",l=this._target.openKeyCursor(this.IDBKeyRange.bound(n,o),a);let c=0;await iterateCursor(l,((e,t,n)=>{for(;c<r.length&&i(r[c],t)<0;)c+=1;let o=!1;if(r[c]===t){const e=n.primaryKey;o=s(t,e),c+=1}return o||c>=r.length?DONE:{done:!1,jumpTo:r[c]}}))}_reduce(e,t,s,i){let r=s;return iterateCursor(this._openCursor(e,i),(e=>(r=t(r,e),NOT_DONE)))}_selectLimit(e,t,s){return this._selectUntil(e,(e=>e.length===t),s)}async _selectUntil(e,t,s){const i=this._openCursor(e,s),r=[];return await iterateCursor(i,(e=>(r.push(e),{done:t(r,e)}))),r}async _selectWhile(e,t,s){const i=this._openCursor(e,s),r=[];return await iterateCursor(i,(e=>{const s=t(e);return s&&r.push(e),{done:!s}})),r}async iterateWhile(e,t){const s=this._openCursor(e,"next");await iterateCursor(s,(e=>({done:!t(e)})))}async _find(e,t,s){const i=this._openCursor(e,s);let r;if(await iterateCursor(i,(e=>{const s=t(e);return s&&(r=e),{done:s}})))return r}}const LOG_REQUESTS=!1;function logRequest(e,t,s){var i,r;const n=null==s?void 0:s.name,o=null==(r=null==(i=null==s?void 0:s.transaction)?void 0:i.db)?void 0:r.name;console.info(`${o}.${n}.${e}(${t.map((e=>JSON.stringify(e))).join(", ")})`)}class QueryTargetWrapper{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?this._qt.openKeyCursor(e,t):this.openCursor(e,t)}catch(s){throw new IDBRequestAttemptError("openKeyCursor",this._qt,s,[e,t])}}openCursor(e,t){try{return this._qt.openCursor(e,t)}catch(s){throw new IDBRequestAttemptError("openCursor",this._qt,s,[e,t])}}put(e,t){try{return this._qtStore.put(e,t)}catch(s){throw new IDBRequestAttemptError("put",this._qt,s,[e,t])}}add(e,t){try{return this._qtStore.add(e,t)}catch(s){throw new IDBRequestAttemptError("add",this._qt,s,[e,t])}}get(e){try{return this._qt.get(e)}catch(t){throw new IDBRequestAttemptError("get",this._qt,t,[e])}}getKey(e){try{return this._qt.getKey(e)}catch(t){throw new IDBRequestAttemptError("getKey",this._qt,t,[e])}}delete(e){try{return this._qtStore.delete(e)}catch(t){throw new IDBRequestAttemptError("delete",this._qt,t,[e])}}count(e){try{return this._qt.count(e)}catch(t){throw new IDBRequestAttemptError("count",this._qt,t,[e])}}index(e){try{return this._qtStore.index(e)}catch(t){throw new IDBRequestAttemptError("index",this._qt,t,[e])}}get indexNames(){return Array.from(this._qtStore.indexNames)}}class Store extends QueryTarget{constructor(e,t){super(new QueryTargetWrapper(e),t)}get _idbStore(){return this._target}index(e){return new QueryTarget(new QueryTargetWrapper(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 reqAsPromise(this._idbStore.add(e)),!0}catch(s){if(s instanceof IDBRequestError)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)}_prepareErrorLog(e,t,s,i,r){t&&t.ensureRefId(),reqAsPromise(e).catch((e=>{let n;r?n=this._getKeys(r):i&&(n=[i]),this._transaction.addWriteError(e,t,s,n)}))}_getKeys(e){const t=[],{keyPath:s}=this._idbStore;try{t.push(this._readKeyPath(e,s))}catch(e){console.warn("could not read keyPath",s)}for(const s of this._idbStore.indexNames)try{const i=this._idbStore.index(s);t.push(this._readKeyPath(e,i.keyPath))}catch(e){console.warn("could not read index",s)}return t}_readKeyPath(e,t){if(Array.isArray(t)){let s=e;for(const e of t){if("object"!=typeof s)break;s=s[e]}return s}return e[t]}}var DecryptionSource=(e=>(e[e.Sync=0]="Sync",e[e.Timeline=1]="Timeline",e[e.Retry=2]="Retry",e))(DecryptionSource||{});const SESSION_E2EE_KEY_PREFIX="e2ee:",OLM_ALGORITHM="m.olm.v1.curve25519-aes-sha2",MEGOLM_ALGORITHM="m.megolm.v1.aes-sha2";class DecryptionError$1 extends Error{constructor(e,t,s){super(`Decryption error ${e}${s?": "+JSON.stringify(s):""}`),this.code=e,this.event=t,this.detailsObj=s}}const SIGNATURE_ALGORITHM="ed25519";function getDeviceEd25519Key(e){return e.keys[`ed25519:${e.device_id}`]}function getDeviceCurve25519Key(e){return e.keys[`curve25519:${e.device_id}`]}function getEd25519Signature(e,t,s){var i,r;return null==(r=null==(i=null==e?void 0:e.signatures)?void 0:i[t])?void 0:r[`ed25519:${s}`]}var SignatureVerification=(e=>(e[e.Valid=0]="Valid",e[e.Invalid=1]="Invalid",e[e.NotSigned=2]="NotSigned",e))(SignatureVerification||{});function verifyEd25519Signature(e,t,s,i,r,n){const o=getEd25519Signature(r,t,s);if(!o)return null==n||n.set("no_signature",!0),2;const a=Object.assign({},r);delete a.unsigned,delete a.signatures;const l=anotherjson__default.default.stringify(a);try{return e.ed25519_verify(i,l,o),0}catch(e){if(n){const t=n.log({l:"Invalid signature, ignoring.",ed25519Key:i,canonicalJson:l,signature:o});t.error=e,t.logLevel=n.level.Warn}return 1}}function createRoomEncryptionEvent(){return{type:"m.room.encryption",state_key:"",content:{algorithm:MEGOLM_ALGORITHM,rotation_period_ms:6048e5,rotation_period_msgs:100}}}function shouldShareKey(e,t){switch(t){case"world_readable":return!0;case"shared":return void 0!==e;case"joined":return"join"===e;case"invited":return"invite"===e||"join"===e;default:return!1}}function stringify(e){return JSON.stringify(encodeValue(e))}function parse(e){return decodeValue(JSON.parse(e))}function encodeValue(e){if("object"!=typeof e||null===e||Array.isArray(e))return e;{if(e.byteLength)return{_type:e.constructor.name,value:Array.from(e)};let t={};for(const s in e)e.hasOwnProperty(s)&&(t[s]=encodeValue(e[s]));return t}}function decodeValue(e){if("object"!=typeof e||null===e||Array.isArray(e))return e;{if("string"==typeof e._type)switch(e._type){case"Int8Array":return Int8Array.from(e.value);case"Uint8Array":return Uint8Array.from(e.value);case"Uint8ClampedArray":return Uint8ClampedArray.from(e.value);case"Int16Array":return Int16Array.from(e.value);case"Uint16Array":return Uint16Array.from(e.value);case"Int32Array":return Int32Array.from(e.value);case"Uint32Array":return Uint32Array.from(e.value);case"Float32Array":return Float32Array.from(e.value);case"Float64Array":return Float64Array.from(e.value);case"BigInt64Array":return BigInt64Array.from(e.value);case"BigUint64Array":return BigUint64Array.from(e.value);default:return e.value}let t={};for(const s in e)e.hasOwnProperty(s)&&(t[s]=decodeValue(e[s]));return t}}function getLocalStorageKeyPrefix(e){return`${e}.session.`}function clearKeysFromLocalStorage(e,t){const s=[];for(let i=0;i<e.length;i++){const r=e.key(i);(null==r?void 0:r.startsWith(getLocalStorageKeyPrefix(t)))&&s.push(r)}for(const t of s)e.removeItem(t)}class SessionStore{constructor(e,t){this._sessionStore=e,this._localStorage=t}get _localStorageKeyPrefix(){return getLocalStorageKeyPrefix(this._sessionStore.databaseName)}async get(e){const t=await this._sessionStore.get(e);if(t)return t.value}_writeKeyToLocalStorage(e,t){try{const s=this._localStorageKeyPrefix+e,i=stringify(t);this._localStorage.setItem(s,i)}catch(e){console.error("could not write to localStorage",e)}}writeE2EEIdentityToLocalStorage(){this._sessionStore.iterateValues(void 0,((e,t)=>(t.startsWith("e2ee:")&&this._writeKeyToLocalStorage(t,e.value),!1)))}async tryRestoreE2EEIdentityFromLocalStorage(e){let t=!1;const s=this._localStorageKeyPrefix,i=s+"e2ee:";for(let r=0;r<this._localStorage.length;r+=1){const n=this._localStorage.key(r);if(n.startsWith(i)){const i=parse(this._localStorage.getItem(n)),r=n.substr(s.length),o=await this._sessionStore.getKey(r)===r;e.set(r,!o),o||(this._sessionStore.put({key:r,value:i}),t=!0)}}return t}set(e,t){e.startsWith("e2ee:")&&this._writeKeyToLocalStorage(e,t),this._sessionStore.put({key:e,value:t})}add(e,t){e.startsWith("e2ee:")&&this._writeKeyToLocalStorage(e,t),this._sessionStore.add({key:e,value:t})}remove(e){e.startsWith("e2ee:")&&this._localStorage.removeItem(this._localStorageKeyPrefix+e),this._sessionStore.delete(e)}}class RoomSummaryStore{constructor(e){this._summaryStore=e}getAll(){return this._summaryStore.selectAll()}set(e){this._summaryStore.put(e)}get(e){return this._summaryStore.get(e)}async has(e){return e===await this._summaryStore.getKey(e)}remove(e){this._summaryStore.delete(e)}}class InviteStore{constructor(e){this._inviteStore=e}getAll(){return this._inviteStore.selectAll()}set(e){this._inviteStore.put(e)}remove(e){this._inviteStore.delete(e)}}class EventKey{constructor(e,t){this.fragmentId=e,this.eventIndex=t}nextFragmentKey(){return new EventKey(this.fragmentId+1,KeyLimits.middleStorageKey)}nextKeyForDirection(e){return e.isForward?this.nextKey():this.previousKey()}previousKey(){return new EventKey(this.fragmentId,this.eventIndex-1)}nextKey(){return new EventKey(this.fragmentId,this.eventIndex+1)}static get maxKey(){return new EventKey(KeyLimits.maxStorageKey,KeyLimits.maxStorageKey)}static get minKey(){return new EventKey(KeyLimits.minStorageKey,KeyLimits.minStorageKey)}static get defaultLiveKey(){return EventKey.defaultFragmentKey(KeyLimits.minStorageKey)}static defaultFragmentKey(e){return new EventKey(e,KeyLimits.middleStorageKey)}toString(){return`[${this.fragmentId}/${this.eventIndex}]`}equals(e){return this.fragmentId===(null==e?void 0:e.fragmentId)&&this.eventIndex===(null==e?void 0:e.eventIndex)}}function createEventEntry(e,t,s){return{fragmentId:e.fragmentId,eventIndex:e.eventIndex,roomId:t,event:s}}function directionalAppend(e,t,s){s.isForward?e.push(t):e.unshift(t)}function directionalConcat(e,t,s){return s.isForward?e.concat(t):t.concat(e)}function encodeKey$b(e,t,s){return`${e}|${encodeUint32(t)}|${encodeUint32(s)}`}function decodeKey$5(e){const[t,s,i]=e.split("|");return{roomId:t,eventKey:new EventKey(decodeUint32(s),decodeUint32(i))}}function encodeEventIdKey(e,t){return`${e}|${t}`}function decodeEventIdKey(e){const[t,s]=e.split("|");return{roomId:t,eventId:s}}class Range$1{constructor(e,t,s,i,r=!1,n=!1){this._IDBKeyRange=e,this._only=t,this._lower=s,this._upper=i,this._lowerOpen=r,this._upperOpen=n}asIDBKeyRange(e){try{if(this._only)return this._IDBKeyRange.only(encodeKey$b(e,this._only.fragmentId,this._only.eventIndex));if(this._lower&&!this._upper)return this._IDBKeyRange.bound(encodeKey$b(e,this._lower.fragmentId,this._lower.eventIndex),encodeKey$b(e,this._lower.fragmentId,KeyLimits.maxStorageKey),this._lowerOpen,!1);if(!this._lower&&this._upper)return this._IDBKeyRange.bound(encodeKey$b(e,this._upper.fragmentId,KeyLimits.minStorageKey),encodeKey$b(e,this._upper.fragmentId,this._upper.eventIndex),!1,this._upperOpen);if(this._lower&&this._upper)return this._IDBKeyRange.bound(encodeKey$b(e,this._lower.fragmentId,this._lower.eventIndex),encodeKey$b(e,this._upper.fragmentId,this._upper.eventIndex),this._lowerOpen,this._upperOpen)}catch(e){throw new StorageError("IDBKeyRange failed with data: "+JSON.stringify(this),e)}}}class TimelineEventStore{constructor(e){this._timelineStore=e}onlyRange(e){return new Range$1(this._timelineStore.IDBKeyRange,e)}upperBoundRange(e,t=!1){return new Range$1(this._timelineStore.IDBKeyRange,void 0,void 0,e,void 0,t)}lowerBoundRange(e,t=!1){return new Range$1(this._timelineStore.IDBKeyRange,void 0,e,void 0,t)}boundRange(e,t,s=!1,i=!1){return new Range$1(this._timelineStore.IDBKeyRange,void 0,e,t,s,i)}async lastEvents(e,t,s){const i=EventKey.maxKey;return i.fragmentId=t,this.eventsBefore(e,i,s)}async firstEvents(e,t,s){const i=EventKey.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((t=>encodeEventIdKey(e,t))),r=new Map;return await s.findExistingKeys(i,!1,((e,t)=>{const{eventId:s}=decodeEventIdKey(e),{eventKey:i}=decodeKey$5(t);return r.set(s,i),!1})),r}async findFirstOccurringEventId(e,t){const s=this._timelineStore.index("byEventId"),i=t.map((t=>encodeEventIdKey(e,t))),r=new Array(i.length);let n;return await s.findExistingKeys(i,!1,((e,t)=>{const s=i.indexOf(e);return r[s]=t,n=function(){for(let e=0;e<r.length;++e){if(void 0===r[e])return;if(!0===r[e])return i[e]}}(),!!n})),n&&decodeEventIdKey(n).eventId}tryInsert(e,t){return e.key=encodeKey$b(e.roomId,e.fragmentId,e.eventIndex),e.eventIdKey=encodeEventIdKey(e.roomId,e.event.event_id),this._timelineStore.tryAdd(e,t)}update(e){this._timelineStore.put(e)}get(e,t){return this._timelineStore.get(encodeKey$b(e,t.fragmentId,t.eventIndex))}getByEventId(e,t){return this._timelineStore.index("byEventId").get(encodeEventIdKey(e,t))}removeAllForRoom(e){const t=encodeKey$b(e,KeyLimits.minStorageKey,KeyLimits.minStorageKey),s=encodeKey$b(e,KeyLimits.maxStorageKey,KeyLimits.maxStorageKey),i=this._timelineStore.IDBKeyRange.bound(t,s);this._timelineStore.delete(i)}}const MIN_UNICODE="\0",MAX_UNICODE="􏿿";function encodeKey$a(e,t,s,i){return`${e}|${t}|${s}|${i}`}function decodeKey$4(e){const[t,s,i,r]=e.split("|");return{roomId:t,targetEventId:s,relType:i,sourceEventId:r}}class TimelineRelationStore{constructor(e){this._store=e}add(e,t,s,i){this._store.add({key:encodeKey$a(e,t,s,i)})}remove(e,t,s,i){this._store.delete(encodeKey$a(e,t,s,i))}removeAllForTarget(e,t){const s=this._store.IDBKeyRange.bound(encodeKey$a(e,t,"\0","\0"),encodeKey$a(e,t,"􏿿","􏿿"),!0,!0);this._store.delete(s)}removeAllForRoom(e){const t=this._store.IDBKeyRange.bound(encodeKey$a(e,"\0","\0","\0"),encodeKey$a(e,"􏿿","􏿿","􏿿"),!0,!0);this._store.delete(t)}async getForTargetAndType(e,t,s){const i=this._store.IDBKeyRange.bound(encodeKey$a(e,t,s,"\0"),encodeKey$a(e,t,s,"􏿿"),!0,!0);return(await this._store.selectAll(i)).map((e=>decodeKey$4(e.key)))}async getAllForTarget(e,t){const s=this._store.IDBKeyRange.bound(encodeKey$a(e,t,"\0","\0"),encodeKey$a(e,t,"􏿿","􏿿"),!0,!0);return(await this._store.selectAll(s)).map((e=>decodeKey$4(e.key)))}}function encodeKey$9(e,t,s){return`${e}|${t}|${s}`}class RoomStateStore{constructor(e){this._roomStateStore=e}get(e,t,s){const i=encodeKey$9(e,t,s);return this._roomStateStore.get(i)}getAllForType(e,t){const s=this._roomStateStore.IDBKeyRange.bound(encodeKey$9(e,t,""),encodeKey$9(e,t,"􏿿"),!1,!0);return this._roomStateStore.selectAll(s)}set(e,t){const s={roomId:e,event:t,key:encodeKey$9(e,t.type,t.state_key)};this._roomStateStore.put(s)}removeAllForRoom(e){const t=this._roomStateStore.IDBKeyRange.bound(e,`${e}|􏿿`,!0,!0);this._roomStateStore.delete(t)}}function encodeKey$8(e,t){return`${e}|${t}`}function decodeKey$3(e){const[t,s]=e.split("|");return{roomId:t,userId:s}}class RoomMemberStore{constructor(e){this._roomMembersStore=e}get(e,t){return this._roomMembersStore.get(encodeKey$8(e,t))}set(e){e.key=encodeKey$8(e.roomId,e.userId),this._roomMembersStore.put(e)}getAll(e){const t=this._roomMembersStore.IDBKeyRange.lowerBound(encodeKey$8(e,""));return this._roomMembersStore.selectWhile(t,(t=>t.roomId===e))}async getAllUserIds(e){const t=[],s=this._roomMembersStore.IDBKeyRange.lowerBound(encodeKey$8(e,""));return await this._roomMembersStore.iterateKeys(s,(s=>{const i=decodeKey$3(s);return i.roomId!==e||(t.push(i.userId),!1)})),t}removeAllForRoom(e){const t=this._roomMembersStore.IDBKeyRange.bound(e,`${e}|􏿿`,!0,!0);this._roomMembersStore.delete(t)}}function encodeKey$7(e,t){return`${e}|${encodeUint32(t)}`}class TimelineFragmentStore{constructor(e){this._store=e}_allRange(e){try{return this._store.IDBKeyRange.bound(encodeKey$7(e,KeyLimits.minStorageKey),encodeKey$7(e,KeyLimits.maxStorageKey))}catch(t){throw new StorageError(`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),(e=>"number"!=typeof e.nextId&&"string"!=typeof e.nextToken))}add(e){e.key=encodeKey$7(e.roomId,e.id),this._store.add(e)}update(e){this._store.put(e)}get(e,t){return this._store.get(encodeKey$7(e,t))}removeAllForRoom(e){this._store.delete(this._allRange(e))}}function encodeKey$6(e,t){return`${e}|${encodeUint32(t)}`}function decodeKey$2(e){const[t,s]=e.split("|");return{roomId:t,queueIndex:decodeUint32(s)}}class PendingEventStore{constructor(e){this._eventStore=e}async getMaxQueueIndex(e){const t=this._eventStore.IDBKeyRange.bound(encodeKey$6(e,KeyLimits.minStorageKey),encodeKey$6(e,KeyLimits.maxStorageKey),!1,!1),s=await this._eventStore.findMaxKey(t);if(s)return decodeKey$2(s).queueIndex}remove(e,t){const s=this._eventStore.IDBKeyRange.only(encodeKey$6(e,t));this._eventStore.delete(s)}async exists(e,t){const s=this._eventStore.IDBKeyRange.only(encodeKey$6(e,t));return!!await this._eventStore.getKey(s)}add(e){e.key=encodeKey$6(e.roomId,e.queueIndex),this._eventStore.add(e)}update(e){this._eventStore.put(e)}getAll(){return this._eventStore.selectAll()}removeAllForRoom(e){const t=encodeKey$6(e,KeyLimits.minStorageKey),s=encodeKey$6(e,KeyLimits.maxStorageKey),i=this._eventStore.IDBKeyRange.bound(t,s);this._eventStore.delete(i)}}class UserIdentityStore{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 encodeKey$5(e,t){return`${e}|${t}`}function decodeKey$1(e){const[t,s]=e.split("|");return{userId:t,deviceId:s}}class DeviceKeyStore{constructor(e){this._store=e}async getAllForUserId(e){const t=this._store.IDBKeyRange.lowerBound(encodeKey$5(e,"\0"));return(await this._store.selectWhile(t,(t=>t.deviceKey.user_id===e))).map((e=>e.deviceKey))}async getAllDeviceIds(e){const t=[],s=this._store.IDBKeyRange.lowerBound(encodeKey$5(e,"\0"));return await this._store.iterateKeys(s,(s=>{const i=decodeKey$1(s);return i.userId!==e||(t.push(i.deviceId),!1)})),t}async get(e,t){var s;return null==(s=await this._store.get(encodeKey$5(e,t)))?void 0:s.deviceKey}set(e){this._store.put({key:encodeKey$5(e.user_id,e.device_id),curve25519Key:getDeviceCurve25519Key(e),deviceKey:e})}async getByCurve25519Key(e){const t=await this._store.index("byCurve25519Key").get(e);return null==t?void 0:t.deviceKey}remove(e,t){this._store.delete(encodeKey$5(e,t))}removeAllForUser(e){const t=this._store.IDBKeyRange.bound(encodeKey$5(e,"\0"),encodeKey$5(e,"􏿿"),!0,!0);this._store.delete(t)}}function encodeKey$4(e,t){return`${e}|${t}`}class CrossSigningKeyStore{constructor(e){this._store=e}async get(e,t){var s;return null==(s=await this._store.get(encodeKey$4(e,t)))?void 0:s.crossSigningKey}set(e){this._store.put({key:encodeKey$4(e.user_id,e.usage[0]),crossSigningKey:e})}remove(e,t){this._store.delete(encodeKey$4(e,t))}removeAllForUser(e){const t=this._store.IDBKeyRange.bound(encodeKey$4(e,"\0"),encodeKey$4(e,"􏿿"),!0,!0);this._store.delete(t)}}function encodeKey$3(e,t){return`${e}|${t}`}function decodeKey(e){const[t,s]=e.split("|");return{senderKey:t,sessionId:s}}class OlmSessionStore{constructor(e){this._store=e}async getSessionIds(e){const t=[],s=this._store.IDBKeyRange.lowerBound(encodeKey$3(e,""));return await this._store.iterateKeys(s,(s=>{const i=decodeKey(s);return i.senderKey!==e||(t.push(i.sessionId),!1)})),t}getAll(e){const t=this._store.IDBKeyRange.lowerBound(encodeKey$3(e,""));return this._store.selectWhile(t,(t=>t.senderKey===e))}get(e,t){return this._store.get(encodeKey$3(e,t))}set(e){e.key=encodeKey$3(e.senderKey,e.sessionId),this._store.put(e)}remove(e,t){this._store.delete(encodeKey$3(e,t))}}var BackupStatus=(e=>(e[e.NotBackedUp=0]="NotBackedUp",e[e.BackedUp=1]="BackedUp",e))(BackupStatus||{}),KeySource=(e=>(e[e.DeviceMessage=1]="DeviceMessage",e[e.Backup=2]="Backup",e[e.Outbound=3]="Outbound",e))(KeySource||{});function encodeKey$2(e,t,s){return`${e}|${t}|${s}`}class InboundGroupSessionStore{constructor(e){this._store=e}async has(e,t,s){const i=encodeKey$2(e,t,s);return i===await this._store.getKey(i)}get(e,t,s){return this._store.get(encodeKey$2(e,t,s))}set(e){const t=e;t.key=encodeKey$2(e.roomId,e.senderKey,e.sessionId),this._store.put(t)}removeAllForRoom(e){const t=this._store.IDBKeyRange.bound(encodeKey$2(e,"\0","\0"),encodeKey$2(e,"􏿿","􏿿"));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(encodeKey$2(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,((e,s,i)=>(e.backup=0,i.update(e),t+=1,!1))),t}}class OutboundGroupSessionStore{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 encodeKey$1(e,t,s){return`${e}|${t}|${s}`}class GroupSessionDecryptionStore{constructor(e){this._store=e}get(e,t,s){return this._store.get(encodeKey$1(e,t,s))}set(e,t,s,i){i.key=encodeKey$1(e,t,s),this._store.put(i)}removeAllForRoom(e){const t=this._store.IDBKeyRange.bound(encodeKey$1(e,"\0","\0"),encodeKey$1(e,"􏿿","􏿿"));this._store.delete(t)}}function encodeScopeTypeKey(e,t){return`${e}|${t}`}class OperationStore{constructor(e){this._store=e}getAll(){return this._store.selectAll()}async getAllByTypeAndScope(e,t){const s=encodeScopeTypeKey(t,e),i=[];return await this._store.index("byScopeAndType").iterateWhile(s,(e=>e.scopeTypeKey===s&&(i.push(e),!0))),i}add(e){e.scopeTypeKey=encodeScopeTypeKey(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(encodeScopeTypeKey(e,"\0"),encodeScopeTypeKey(e,"􏿿")),s=this._store.index("byScopeAndType");await s.iterateValues(t,((e,t,s)=>(s.delete(),!0)))}}class AccountDataStore{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 encodeKey(e,t,s){return`${e}|${t}|${s}`}function decodeStorageEntry(e){const[t,s,i]=e.key.split("|");return{intent:t,roomId:s,callId:i,timestamp:e.timestamp}}class CallStore{constructor(e){this._callStore=e}async getByIntent(e){const t=this._callStore.IDBKeyRange.bound(encodeKey(e,"\0","\0"),encodeKey(e,"􏿿","􏿿"),!0,!0);return(await this._callStore.selectAll(t)).map((e=>decodeStorageEntry(e)))}async getByIntentAndRoom(e,t){const s=this._callStore.IDBKeyRange.bound(encodeKey(e,t,"\0"),encodeKey(e,t,"􏿿"),!0,!0);return(await this._callStore.selectAll(s)).map((e=>decodeStorageEntry(e)))}add(e){const t={key:encodeKey(e.intent,e.roomId,e.callId),timestamp:e.timestamp};this._callStore.add(t)}remove(e,t,s){this._callStore.delete(encodeKey(e,t,s))}}class WriteErrorInfo{constructor(e,t,s,i){this.error=e,this.refItem=t,this.operationName=s,this.keys=i}}class Transaction{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 StorageError(`Invalid store for transaction: ${e}, only ${this._allowedStoreNames.join(", ")} are allowed.`);return new Store(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(StoreNames.session,(e=>new SessionStore(e,this._storage.localStorage)))}get roomSummary(){return this._store(StoreNames.roomSummary,(e=>new RoomSummaryStore(e)))}get archivedRoomSummary(){return this._store(StoreNames.archivedRoomSummary,(e=>new RoomSummaryStore(e)))}get invites(){return this._store(StoreNames.invites,(e=>new InviteStore(e)))}get timelineFragments(){return this._store(StoreNames.timelineFragments,(e=>new TimelineFragmentStore(e)))}get timelineEvents(){return this._store(StoreNames.timelineEvents,(e=>new TimelineEventStore(e)))}get timelineRelations(){return this._store(StoreNames.timelineRelations,(e=>new TimelineRelationStore(e)))}get roomState(){return this._store(StoreNames.roomState,(e=>new RoomStateStore(e)))}get roomMembers(){return this._store(StoreNames.roomMembers,(e=>new RoomMemberStore(e)))}get pendingEvents(){return this._store(StoreNames.pendingEvents,(e=>new PendingEventStore(e)))}get userIdentities(){return this._store(StoreNames.userIdentities,(e=>new UserIdentityStore(e)))}get deviceKeys(){return this._store(StoreNames.deviceKeys,(e=>new DeviceKeyStore(e)))}get crossSigningKeys(){return this._store(StoreNames.crossSigningKeys,(e=>new CrossSigningKeyStore(e)))}get olmSessions(){return this._store(StoreNames.olmSessions,(e=>new OlmSessionStore(e)))}get inboundGroupSessions(){return this._store(StoreNames.inboundGroupSessions,(e=>new InboundGroupSessionStore(e)))}get outboundGroupSessions(){return this._store(StoreNames.outboundGroupSessions,(e=>new OutboundGroupSessionStore(e)))}get groupSessionDecryptions(){return this._store(StoreNames.groupSessionDecryptions,(e=>new GroupSessionDecryptionStore(e)))}get operations(){return this._store(StoreNames.operations,(e=>new OperationStore(e)))}get accountData(){return this._store(StoreNames.accountData,(e=>new AccountDataStore(e)))}get calls(){return this._store(StoreNames.calls,(e=>new CallStore(e)))}async complete(e){try{await txnAsPromise(this._txn)}catch(t){if(this._writeErrors.length)throw this._logWriteErrors(e),this._writeErrors[0].error;throw t}}getCause(e){return e instanceof StorageError&&"AbortError"===e.errcode&&this._writeErrors.length?this._writeErrors[0].error:e}abort(e){try{this._txn.abort()}catch(t){null==e||e.set("couldNotAbortTxn",!0)}this._writeErrors.length&&this._logWriteErrors(e)}addWriteError(e,t,s,i){"AbortError"===e.errcode&&0!==this._writeErrors.length||this._writeErrors.push(new WriteErrorInfo(e,t,s,i))}_logWriteErrors(e){const t=t=>{e||t.set("allowedStoreNames",this._allowedStoreNames);for(const e of this._writeErrors)t.wrap({l:e.operationName,id:e.keys},(t=>{e.refItem&&t.refDetached(e.refItem),t.catch(e.error)}))},s=`${this._writeErrors.length} storage write operation(s) failed`;e?e.wrap(s,t):this.logger.run(s,t)}}const WEBKITEARLYCLOSETXNBUG_BOGUS_KEY="782rh281re38-boguskey";class Storage{constructor(e,t,s,i,r,n){this._db=e,this.idbFactory=t,this.IDBKeyRange=s,this._hasWebkitEarlyCloseTxnBug=i,this.storeNames=StoreNames,this.localStorage=r,this.logger=n}_validateStoreNames(e){const t=e.findIndex((e=>!STORE_NAMES.includes(e)));if(-1!==t)throw new StorageError(`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 reqAsPromise(t.objectStore(e[0]).get("782rh281re38-boguskey")),new Transaction(t,e,this)}catch(e){throw new StorageError("readTxn failed",e)}}async readWriteTxn(e){this._validateStoreNames(e);try{const t=this._db.transaction(e,"readwrite");return this._hasWebkitEarlyCloseTxnBug&&await reqAsPromise(t.objectStore(e[0]).get("782rh281re38-boguskey")),new Transaction(t,e,this)}catch(e){throw new StorageError("readWriteTxn failed",e)}}close(){this._db.close()}get databaseName(){return this._db.name}}async function exportSession(e){const t=e.transaction(STORE_NAMES,"readonly"),s={};return await Promise.all(STORE_NAMES.map((async e=>{const i=s[e]=[],r=t.objectStore(e);await iterateCursor(r.openCursor(),(e=>(i.push(e),NOT_DONE)))}))),s}async function importSession(e,t){const s=e.transaction(STORE_NAMES,"readwrite");for(const e of STORE_NAMES){const i=s.objectStore(e);for(const s of t[e])i.add(s)}await txnAsPromise(s)}function getPrevContentFromStateEvent(e){var t;return(null==(t=e.unsigned)?void 0:t.prev_content)||e.prev_content}const REDACTION_TYPE="m.room.redaction";function isRedacted(e){var t;return!!(null==(t=null==e?void 0:e.unsigned)?void 0:t.redacted_because)}var RoomStatus=(e=>(e[e.None=1]="None",e[e.BeingCreated=2]="BeingCreated",e[e.Invited=4]="Invited",e[e.Joined=8]="Joined",e[e.Replaced=16]="Replaced",e[e.Archived=32]="Archived",e))(RoomStatus||{}),RoomVisibility=(e=>(e[e.DirectMessage=0]="DirectMessage",e[e.Private=1]="Private",e[e.Public=2]="Public",e))(RoomVisibility||{}),RoomType=(e=>(e[e.World=0]="World",e[e.Profile=1]="Profile",e))(RoomType||{});function iterateResponseStateEvents(e,t){var s,i;let r;const n=e=>{const s=t(e);s instanceof Promise&&(r=null!=r?r:[],r.push(s))},o=null==(s=e.state)?void 0:s.events;if(o)for(let e=0;e<o.length;e++)n(o[e]);let a=null==(i=e.timeline)?void 0:i.events;if(a)for(let e=0;e<a.length;e++){const t=a[e];"string"==typeof t.state_key&&n(t)}if(r)return Promise.all(r).then((()=>{}))}const EVENT_TYPE$1="m.room.member";class RoomMember{constructor(e){this._data=e}static fromUserId(e,t,s){return new RoomMember({roomId:e,userId:t,membership:s})}static fromMemberEvent(e,t){const s=null==t?void 0:t.state_key;if("string"!=typeof s)return;const i=t.content,r=getPrevContentFromStateEvent(t),n=null==i?void 0:i.membership,o=(null==i?void 0:i.displayname)||(null==r?void 0:r.displayname),a=(null==i?void 0:i.avatar_url)||(null==r?void 0:r.avatar_url);return this._validateAndCreateMember(e,s,n,o,a)}static fromReplacingMemberEvent(e,t){const s=t&&t.state_key;if("string"!=typeof s)return;const i=getPrevContentFromStateEvent(t);return this._validateAndCreateMember(e,s,null==i?void 0:i.membership,null==i?void 0:i.displayname,null==i?void 0:i.avatar_url)}static _validateAndCreateMember(e,t,s,i,r){if("string"==typeof s)return new RoomMember({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 MemberChange{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"invite"===this.previousMembership&&"invite"!==this.membership}get hasLeft(){return"join"===this.previousMembership&&"join"!==this.membership}get hasJoined(){return"join"!==this.previousMembership&&"join"===this.membership}}function pkSign(e,t,s,i,r){let n=!1;if(s instanceof Uint8Array){const t=new e.PkSigning;r=t.init_with_seed(s),s=t,n=!0}const o=t.signatures||{};delete t.signatures;const a=t.unsigned;t.unsigned&&delete t.unsigned;try{const e=o[i]||{};return o[i]=e,e["ed25519:"+r]=s.sign(anotherjson__default.default.stringify(t))}finally{t.signatures=o,a&&(t.unsigned=a),n&&s.free()}}class BaseSASVerificationStage{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 VerificationEventType=(e=>(e.Request="m.key.verification.request",e.Ready="m.key.verification.ready",e.Start="m.key.verification.start",e.Accept="m.key.verification.accept",e.Key="m.key.verification.key",e.Cancel="m.key.verification.cancel",e.Mac="m.key.verification.mac",e.Done="m.key.verification.done",e))(VerificationEventType||{}),CancelReason=(e=>(e.UserCancelled="m.user",e.TimedOut="m.timeout",e.UnknownTransaction="m.unknown_transaction",e.UnknownMethod="m.unknown_method",e.UnexpectedMessage="m.unexpected_message",e.KeyMismatch="m.key_mismatch",e.UserMismatch="m.user_mismatch",e.InvalidMessage="m.invalid_message",e.OtherDeviceAccepted="m.accepted",e.MismatchedCommitment="m.mismatched_commitment",e.MismatchedSAS="m.mismatched_sas",e))(CancelReason||{});const KEY_AGREEMENT_LIST=["curve25519-hkdf-sha256","curve25519"],HASHES_LIST=["sha256"],MAC_LIST=["hkdf-hmac-sha256.v2","org.matrix.msc3783.hkdf-hmac-sha256","hkdf-hmac-sha256","hmac-sha256"],SAS_LIST=["decimal","emoji"],SAS_SET=new Set(SAS_LIST),emojiMapping=[["🐶","dog"],["🐱","cat"],["🦁","lion"],["🐎","horse"],["🦄","unicorn"],["🐷","pig"],["🐘","elephant"],["🐰","rabbit"],["🐼","panda"],["🐓","rooster"],["🐧","penguin"],["🐢","turtle"],["🐟","fish"],["🐙","octopus"],["🦋","butterfly"],["🌷","flower"],["🌳","tree"],["🌵","cactus"],["🍄","mushroom"],["🌏","globe"],["🌙","moon"],["☁️","cloud"],["🔥","fire"],["🍌","banana"],["🍎","apple"],["🍓","strawberry"],["🌽","corn"],["🍕","pizza"],["🎂","cake"],["❤️","heart"],["🙂","smiley"],["🤖","robot"],["🎩","hat"],["👓","glasses"],["🔧","spanner"],["🎅","santa"],["👍","thumbs up"],["☂️","umbrella"],["⌛","hourglass"],["⏰","clock"],["🎁","gift"],["💡","light bulb"],["📕","book"],["✏️","pencil"],["📎","paperclip"],["✂️","scissors"],["🔒","lock"],["🔑","key"],["🔨","hammer"],["☎️","telephone"],["🏁","flag"],["🚂","train"],["🚲","bicycle"],["✈️","aeroplane"],["🚀","rocket"],["🏆","trophy"],["⚽","ball"],["🎸","guitar"],["🎺","trumpet"],["🔔","bell"],["⚓️","anchor"],["🎧","headphones"],["📁","folder"],["📌","pin"]];function generateEmojiSas(e){return[e[0]>>2,(3&e[0])<<4|e[1]>>4,(15&e[1])<<2|e[2]>>6,63&e[2],e[3]>>2,(3&e[3])<<4|e[4]>>4,(15&e[4])<<2|e[5]>>6].map((e=>emojiMapping[e]))}const macMethods={"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 createCalculateMAC(e,t){return function(s,i,r){return r.wrap({l:"calculate MAC",method:t},(()=>e[macMethods[t]](s,i)))}}class SendDoneStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("SendDoneStage.completeStage",(async e=>{await this.channel.send(VerificationEventType.Done,{},e),await this.channel.waitForEvent(VerificationEventType.Done),this.eventEmitter.emit("VerificationCompleted",this.otherUserDeviceId)}))}}class VerifyMacStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("VerifyMacStage.completeStage",(async e=>{const t=this.channel.acceptMessage.content.message_authentication_code,s=createCalculateMAC(this.olmSAS,t);await this.checkMAC(s,e),this.setNextStage(new SendDoneStage(this.options))}))}async checkMAC(e,t){const{content:s}=this.channel.getReceivedMessage(VerificationEventType.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)return t.log({l:"MAC verification failed for keys field",keys:s.keys,calculated:r}),void this.channel.cancelVerification(CancelReason.KeyMismatch);await this.verifyKeys(s.mac,((s,r,n)=>{const o=e(r,i+s,t),a=n===o;return a||(t.log({l:"Mac verification failed for key",keyMac:n,calculatedMAC:o,keyId:s,key:r}),this.channel.cancelVerification(CancelReason.KeyMismatch)),a}),t)}async verifyKeys(e,t,s){const i=this.otherUserId;for(const[r,n]of Object.entries(e)){const e=r.split(":",2)[1],o=await this.deviceTracker.deviceForId(i,e,this.hsApi,s);if(o)t(r,getDeviceEd25519Key(o),n)&&await s.wrap("signing device",(async e=>{const t=await this.options.crossSigning.signDevice(o.device_id,e);e.set("success",!!t)}));else{const e=await this.deviceTracker.getCrossSigningKeyForUser(i,KeyUsage.Master,this.hsApi,s);if(!e)throw s.log({l:"Fetching msk failed",userId:i}),new Error("Fetching MSK for user failed!");const o=getKeyEd25519Key(e);o&&t(r,o,n)&&await s.wrap("signing user",(async e=>{const t=await this.options.crossSigning.signUser(i,e);e.set("success",!!t)}))}}}}class SendMacStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("SendMacStage.completeStage",(async e=>{const t=this.channel.acceptMessage.content.message_authentication_code,s=createCalculateMAC(this.olmSAS,t);await this.sendMAC(s,e),await this.channel.waitForEvent(VerificationEventType.Mac),this.setNextStage(new VerifyMacStage(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,n=`ed25519:${this.ourUserDeviceId}`,o=this.e2eeAccount.getUnsignedDeviceKey();s[n]=e(o.keys[n],r+n,t),i.push(n);const a=await this.deviceTracker.getCrossSigningKeyForUser(this.ourUserId,KeyUsage.Master,this.hsApi,t);if(!a)throw t.log({l:"Fetching msk failed",userId:this.ourUserId}),new Error("Fetching MSK for user failed!");const l=getKeyEd25519Key(a);if(l){const n=`ed25519:${l}`;s[n]=e(l,r+n,t),i.push(n)}const c=e(i.sort().join(","),r+"KEY_IDS",t);await this.channel.send(VerificationEventType.Mac,{mac:s,keys:c},t)}}class VerificationCancelledError extends Error{get name(){return"VerificationCancelledError"}get message(){return"Verification is cancelled!"}}const calculateKeyAgreement={"curve25519-hkdf-sha256":function(e,t,s){const i=`${e.our.userId}|${e.our.deviceId}|${e.our.publicKey}|`,r=`${e.their.userId}|${e.their.deviceId}|${e.their.publicKey}|`,n="MATRIX_KEY_VERIFICATION_SAS|"+(e.initiatedByMe?i+r:r+i)+e.id;return t.generate_bytes(n,s)},curve25519:function(e,t,s){const i=`${e.our.userId}${e.our.deviceId}`,r=`${e.their.userId}${e.their.deviceId}`,n="MATRIX_KEY_VERIFICATION_SAS"+(e.initiatedByMe?i+r:r+i)+e.id;return t.generate_bytes(n,s)}};class CalculateSASStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("CalculateSASStage.completeStage",(async e=>{if(this.channel.initiatedByUs&&!await this.verifyHashCommitment(e))return;const t=new Promise(((e,t)=>{this.resolve=e,this.reject=t}));this.olmSAS.set_their_key(this.theirKey);const s=this.generateSASBytes();this.emoji=generateEmojiSas(Array.from(s)),this.eventEmitter.emit("EmojiGenerated",this),await t,this.setNextStage(new SendMacStage(this.options))}))}async verifyHashCommitment(e){return await e.wrap("CalculateSASStage.verifyHashCommitment",(async()=>{const t=this.channel.getReceivedMessage(VerificationEventType.Accept).content,s=this.channel.getReceivedMessage(VerificationEventType.Key).content.key+anotherjson__default.default.stringify(this.channel.startMessage.content),i=t.commitment,r=this.olmUtil.sha256(s);return r===i||(e.log({l:"Commitment mismatched!",received:i,calculated:r}),await this.channel.cancelVerification(CancelReason.MismatchedCommitment),!1)}))}generateSASBytes(){const e=this.channel.acceptMessage.content.key_agreement_protocol,t=this.otherUserDeviceId;return calculateKeyAgreement[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(CancelReason.MismatchedSAS),this.reject(new VerificationCancelledError))}get theirKey(){const{content:e}=this.channel.getReceivedMessage(VerificationEventType.Key);return e.key}}class SendKeyStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("SendKeyStage.completeStage",(async e=>{const t=this.olmSAS.get_pubkey();await this.channel.send(VerificationEventType.Key,{key:t},e),await this.channel.waitForEvent(VerificationEventType.Key),this.setNextStage(new CalculateSASStage(this.options))}))}}function intersection(e,t){return Array.isArray(e)?e.filter((e=>t.has(e))):[]}class SendAcceptVerificationStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("SendAcceptVerificationStage.completeStage",(async e=>{const{content:t}=this.channel.startMessage,s=intersection(KEY_AGREEMENT_LIST,new Set(t.key_agreement_protocols))[0],i=intersection(HASHES_LIST,new Set(t.hashes))[0],r=intersection(MAC_LIST,new Set(t.message_authentication_codes))[0],n=intersection(t.short_authentication_string,SAS_SET);if(!(s&&i&&r&&n.length))return void await this.channel.cancelVerification(CancelReason.UnknownMethod);const o=this.olmSAS.get_pubkey()+anotherjson__default.default.stringify(t),a={key_agreement_protocol:s,hash:i,message_authentication_code:r,short_authentication_string:n,commitment:this.olmUtil.sha256(o)};await this.channel.send(VerificationEventType.Accept,a,e),await this.channel.waitForEvent(VerificationEventType.Key),this.setNextStage(new SendKeyStage(this.options))}))}}class SelectVerificationMethodStage extends BaseSASVerificationStage{constructor(){super(...arguments),this.hasSentStartMessage=!1,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(VerificationEventType.Start),s=this.channel.waitForEvent(VerificationEventType.Accept),{content:i}=await Promise.race([t,s]);i.method?(this.allowSelection=!1,this.hasSentStartMessage?await this.resolveStartConflict(e):this.channel.setStartMessage(this.channel.getReceivedMessage(VerificationEventType.Start))):this.channel.setStartMessage(this.channel.getSentMessage(VerificationEventType.Start)),this.channel.initiatedByUs?(await s,this.setNextStage(new SendKeyStage(this.options))):this.setNextStage(new SendAcceptVerificationStage(this.options))}))}async resolveStartConflict(e){await e.wrap("resolveStartConflict",(async()=>{const t=this.channel.getReceivedMessage(VerificationEventType.Start),s=this.channel.getSentMessage(VerificationEventType.Start);if(t.content.method!==s.content.method)return e.log({l:"Methods don't match for the start messages",received:t.content.method,sent:s.content.method}),void await this.channel.cancelVerification(CancelReason.UnexpectedMessage);const i=this.ourUserId===this.otherUserId?this.ourUserDeviceId:this.ourUserId,r=this.ourUserId===this.otherUserId?this.otherUserDeviceId:this.otherUserId,n=i<r?s:t;e.log({l:"Start message resolved",message:n,our:i,their:r}),this.channel.setStartMessage(n)}))}async findDeviceName(e){await e.wrap("SelectVerificationMethodStage.findDeviceName",(async()=>{var t;const s=await this.options.deviceTracker.deviceForId(this.otherUserId,this.otherUserDeviceId,this.options.hsApi,e);if(!s)throw e.log({l:"Cannot find device",userId:this.otherUserId,deviceId:this.otherUserDeviceId}),new Error("Cannot find device");this.otherDeviceName=null!=(t=s.unsigned.device_display_name)?t:s.device_id}))}async selectEmojiMethod(e){if(!this.allowSelection)return;const t={method:"m.sas.v1",from_device:this.ourUserDeviceId,key_agreement_protocols:KEY_AGREEMENT_LIST,hashes:HASHES_LIST,message_authentication_codes:MAC_LIST,short_authentication_string:SAS_LIST};await this.channel.send(VerificationEventType.Start,t,e),this.hasSentStartMessage=!0}}class SendRequestVerificationStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("SendRequestVerificationStage.completeStage",(async e=>{const t={from_device:this.ourUserDeviceId,methods:["m.sas.v1"]};await this.channel.send(VerificationEventType.Request,t,e),this.setNextStage(new SelectVerificationMethodStage(this.options)),await this.channel.waitForEvent(VerificationEventType.Ready)}))}}class SendReadyStage extends BaseSASVerificationStage{async completeStage(){await this.log.wrap("SendReadyStage.completeStage",(async e=>{const t={from_device:this.ourUserDeviceId,methods:["m.sas.v1"]};await this.channel.send(VerificationEventType.Ready,t,e),this.setNextStage(new SelectVerificationMethodStage(this.options))}))}}class EventEmitter{constructor(){this._handlersByName={}}emit(e,t){const s=this._handlersByName[e];s&&s.forEach((e=>e(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),0===s.size&&(delete this._handlersByName[e],this.onLastSubscriptionRemoved(e)))}onFirstSubscriptionAdded(e){}onLastSubscriptionRemoved(e){}}class SASVerification extends EventEmitter{constructor(e){super(),this.finished=!1;const{olm:t,channel:s,clock:i}=e,r=new t.SAS;this.olmSas=r,this.channel=s,this.setupCancelAfterTimeout(i);const n=__spreadProps(__spreadValues({},e),{olmSas:r,eventEmitter:this});s.getReceivedMessage(VerificationEventType.Start)?this.startStage=new SelectVerificationMethodStage(n):s.getReceivedMessage(VerificationEventType.Request)?this.startStage=new SendReadyStage(n):this.startStage=new SendRequestVerificationStage(n)}async setupCancelAfterTimeout(e){try{const t=6e5;this.timeout=e.createTimeout(t),await this.timeout.elapsed(),await this.channel.cancelVerification(CancelReason.TimedOut)}catch{}}async abort(){await this.channel.cancelVerification(CancelReason.UserCancelled)}async start(){try{let e=this.startStage;do{await e.completeStage(),e=e.nextStage}while(e)}catch(e){if(!(e instanceof VerificationCancelledError))throw e}finally{this.channel.isCancelled&&this.emit("VerificationCancelled",this.channel.cancellation),this.olmSas.free(),this.timeout.abort(),this.finished=!0}}}function groupBy(e,t){return groupByWithCreator(e,t,(()=>[]),((e,t)=>e.push(t)))}function groupByWithCreator(e,t,s,i){return e.reduce(((e,r)=>{const n=t(r);let o=e.get(n);return o||(o=s(),e.set(n,o)),i(o,r),e}),new Map)}function countBy(e,t){return e.reduce(((e,s)=>{const i=t(s);return e[i]?e[i]+=1:e[i]=1,e}),{})}function makeTxnId(){return makeId("t")}function makeId(e){const t=Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16);return e+"0".repeat(14-t.length)+t}function isTxnId(e){return e.startsWith("t")&&15===e.length}function formatToDeviceMessagesPayload(e){const t=groupBy(e,(e=>e.device.user_id));return{messages:Array.from(t.entries()).reduce(((e,[t,s])=>(e[t]=s.reduce(((e,t)=>(e[t.device.device_id]=t.content,e)),{}),e)),{})}}function disposeValue(e){"function"==typeof e?e():e.dispose()}function isDisposable(e){return e&&("function"==typeof e||"function"==typeof e.dispose)}class Disposables{constructor(){this._disposables=[]}track(e){if(!isDisposable(e))throw new Error("Not a disposable");return this.isDisposed?(console.warn("Disposables already disposed, disposing new value"),disposeValue(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)disposeValue(e);this._disposables=void 0}}get isDisposed(){return void 0===this._disposables}disposeTracked(e){if(null==e||this.isDisposed)return;const t=this._disposables.indexOf(e);if(-1!==t){const[e]=this._disposables.splice(t,1);disposeValue(e)}else console.warn("disposable not found, did it leak?",e)}}class Deferred{constructor(){let e,t;this.promise=new Promise(((s,i)=>{e=s,t=i})),this.resolve=t=>{this._value=t,e(t)},this.reject=t}get value(){return this._value}}const messageFromErrorType={[CancelReason.UserCancelled]:"User declined",[CancelReason.InvalidMessage]:"Invalid Message.",[CancelReason.KeyMismatch]:"Key Mismatch.",[CancelReason.OtherDeviceAccepted]:"Another device has accepted this request.",[CancelReason.TimedOut]:"Timed Out",[CancelReason.UnexpectedMessage]:"Unexpected Message.",[CancelReason.UnknownMethod]:"Unknown method.",[CancelReason.UnknownTransaction]:"Unknown Transaction.",[CancelReason.UserMismatch]:"User Mismatch",[CancelReason.MismatchedCommitment]:"Hash commitment does not match.",[CancelReason.MismatchedSAS]:"Emoji/decimal does not match."};class ToDeviceChannel extends Disposables{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:e})=>await this.handleDeviceMessage(e)))),this.track((()=>{this.waitMap.forEach((e=>{e.reject(new VerificationCancelledError)}))})),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 VerificationCancelledError;if(e===VerificationEventType.Request)return void await this.handleRequestEventSpecially(e,t,s);Object.assign(t,{transaction_id:this.id});const i={messages:{[this.otherUserId]:{[this.otherUserDeviceId]:t}}};await this.hsApi.sendToDevice(e,i,makeTxnId(),{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=makeTxnId();this.id=r,Object.assign(t,{timestamp:i,transaction_id:r});const n={messages:{[this.otherUserId]:{"*":t}}};await this.hsApi.sendToDevice(e,n,makeTxnId(),{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 null!=(e=this.receivedMessages.get(VerificationEventType.Accept))?e:this.sentMessages.get(VerificationEventType.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)return console.log("Received event with unknown transaction id: ",e),void await this.cancelVerification(CancelReason.UnknownTransaction);if(console.log("event",e),t.log({l:"event",event:e}),this.resolveAnyWaits(e),this.receivedMessages.set(e.type,e),e.type!==VerificationEventType.Ready)return e.type===VerificationEventType.Cancel?(this._cancellation={code:e.content.code,cancelledByUs:!1},void this.dispose()):void 0;this.handleReadyMessage(e,t)}}))}async handleReadyMessage(e,t){const s=e.content.from_device;this.otherUserDeviceId=s;const i=(await this.deviceTracker.devicesForUsers([this.otherUserId],this.hsApi,t)).filter((e=>e.device_id!==s&&e.device_id!==this.ourDeviceId)),r={code:CancelReason.OtherDeviceAccepted,reason:messageFromErrorType[CancelReason.OtherDeviceAccepted],transaction_id:this.id},n=i.reduce(((e,t)=>(e[t.device_id]=r,e)),{}),o={messages:{[this.otherUserId]:n}};await this.hsApi.sendToDevice(VerificationEventType.Cancel,o,makeTxnId(),{log:t}).response()}async cancelVerification(e){await this.log.wrap("Channel.cancelVerification",(async t=>{var s;if(this.isCancelled)throw new VerificationCancelledError;const i={messages:{[this.otherUserId]:{[null!=(s=this.otherUserDeviceId)?s:"*"]:{code:e,reason:messageFromErrorType[e],transaction_id:this.id}}}};await this.hsApi.sendToDevice(VerificationEventType.Cancel,i,makeTxnId(),{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 VerificationCancelledError;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 Deferred;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 SASRequest{constructor(e){this.startingMessage=e}get deviceId(){return this.startingMessage.content.from_device}get sender(){return this.startingMessage.sender}get id(){return this.startingMessage.content.transaction_id}}var KeyUsage=(e=>(e.Master="master",e.SelfSigning="self_signing",e.UserSigning="user_signing",e))(KeyUsage||{}),UserTrust=(e=>(e[e.Trusted=1]="Trusted",e[e.UserNotSigned=2]="UserNotSigned",e[e.UserSignatureMismatch=3]="UserSignatureMismatch",e[e.UserDeviceNotSigned=4]="UserDeviceNotSigned",e[e.UserDeviceSignatureMismatch=5]="UserDeviceSignatureMismatch",e[e.UserSetupError=6]="UserSetupError",e[e.OwnSetupError=7]="OwnSetupError",e))(UserTrust||{});class CrossSigning{constructor(e){this._isMasterKeyTrusted=!1,this.observedUsers=new Map,this.receivedSASVerifications=new ObservableMap,this.storage=e.storage,this.secretStorage=e.secretStorage,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 0!==await this.verifyMSKFrom4S(!1,e)}async start(e){this.isMasterKeyTrusted||await this.verifyMSKFrom4S(!0,e)}async verifyMSKFrom4S(e,t){return await t.wrap("CrossSigning.verifyMSKFrom4S",(async t=>{const s=await this.getSigningKey("master");if(!s)return t.set("failure","no_priv_msk"),0;const i=new this.olm.PkSigning;let r;try{r=i.init_with_seed(s)}finally{i.free()}const n=await this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"master",e?this.hsApi:void 0,t);if(!n)return t.set("failure","no_pub_msk"),1;const o=n&&getKeyEd25519Key(n);return t.set({publishedMasterKey:o,derivedPublicKey:r}),this._isMasterKeyTrusted=!!o&&o===r,this._isMasterKeyTrusted?3:(t.set("failure","mismatch"),2)}))}get isMasterKeyTrusted(){return this._isMasterKeyTrusted}startVerification(e,t){if(this.sasVerificationInProgress&&!this.sasVerificationInProgress.finished)return;const s=e instanceof SASRequest?e.sender:e,i=e instanceof SASRequest?e.startingMessage:void 0,r=new ToDeviceChannel({deviceTracker:this.deviceTracker,hsApi:this.hsApi,otherUserId:s,clock:this.platform.clock,deviceMessageHandler:this.deviceMessageHandler,ourUserDeviceId:this.deviceId,log:t},i);return this.sasVerificationInProgress=new SASVerification({olm:this.olm,olmUtil:this.olmUtil,ourUserId:this.ownUserId,ourUserDeviceId:this.deviceId,otherUserId:s,log:t,channel:r,e2eeAccount:this.e2eeAccount,deviceTracker:this.deviceTracker,hsApi:this.hsApi,clock:this.platform.clock,crossSigning:this}),this.sasVerificationInProgress}handleSASDeviceMessage({unencrypted:e}){var t;const s=e.content.transaction_id;if(!((null==(t=this.sasVerificationInProgress)?void 0:t.channel.id)===s))switch(e.type){case VerificationEventType.Cancel:return void this.receivedSASVerifications.remove(s);case VerificationEventType.Request:case VerificationEventType.Start:return void this.platform.logger.run("Create SASRequest",(()=>{this.receivedSASVerifications.set(s,new SASRequest(e))}));default:return}}async signOwnDevice(e){return e.wrap("CrossSigning.signOwnDevice",(async e=>{if(!this._isMasterKeyTrusted)return void e.set("mskNotTrusted",!0);const t=this.e2eeAccount.getUnsignedDeviceKey();return this.signDeviceKey(t,e)}))}async signDevice(e,t){return t.wrap("CrossSigning.signDevice",(async t=>{if(t.set("id",e),!this._isMasterKeyTrusted)return void t.set("mskNotTrusted",!0);const s=await this.deviceTracker.deviceForId(this.ownUserId,e,this.hsApi,t);return s?(delete s.signatures,this.signDeviceKey(s,t)):void 0}))}async signUser(e,t){return t.wrap("CrossSigning.signUser",(async t=>{if(t.set("id",e),!this._isMasterKeyTrusted)return void t.set("mskNotTrusted",!0);if(e===this.ownUserId)return;const s=await this.deviceTracker.getCrossSigningKeyForUser(e,"master",this.hsApi,t);if(!s)return;const i=await this.getSigningKey("user_signing");if(!i)return;delete s.signatures,this.signKey(s,i);const r={[s.user_id]:{[getKeyEd25519Key(s)]:s}},n=this.hsApi.uploadSignatures(r,{log:t});return await n.response(),await this.deviceTracker.invalidateUserKeys(e),this.emitUserTrustUpdate(e,t),s}))}getUserTrust(e,t){return t.wrap("CrossSigning.getUserTrust",(async t=>{t.set("id",e);const s=e=>(t.set("result",e),e);if(!this.isMasterKeyTrusted)return s(7);const i=await t.wrap("get our msk",(e=>this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"master",this.hsApi,e)));if(!i)return s(7);const r=await t.wrap("get our usk",(e=>this.deviceTracker.getCrossSigningKeyForUser(this.ownUserId,"user_signing",this.hsApi,e)));if(!r)return s(7);if(t.wrap("verify our usk",(e=>this.hasValidSignatureFrom(r,i,e)))!==SignatureVerification.Valid)return s(7);const n=await t.wrap("get their msk",(t=>this.deviceTracker.getCrossSigningKeyForUser(e,"master",this.hsApi,t)));if(!n)return s(2);const o=t.wrap("verify their msk",(e=>this.hasValidSignatureFrom(n,r,e)));if(o!==SignatureVerification.Valid)return o===SignatureVerification.NotSigned?s(2):s(3);const a=await t.wrap("get their ssk",(t=>this.deviceTracker.getCrossSigningKeyForUser(e,"self_signing",this.hsApi,t)));if(!a)return s(6);if(t.wrap("verify their ssk",(e=>this.hasValidSignatureFrom(a,n,e)))!==SignatureVerification.Valid)return s(6);const l=(await t.wrap("get their devices",(t=>this.deviceTracker.devicesForUsers([e],this.hsApi,t)))).reduce(((e,s)=>t.wrap({l:"verify device",id:s.device_id},(t=>{const i=this.hasValidSignatureFrom(s,a,t);return e===SignatureVerification.Invalid||i===SignatureVerification.Invalid?SignatureVerification.Invalid:e===SignatureVerification.NotSigned||i===SignatureVerification.NotSigned?SignatureVerification.NotSigned:e===SignatureVerification.Valid||i===SignatureVerification.Valid?SignatureVerification.Valid:SignatureVerification.Invalid}))),SignatureVerification.Valid);return l!==SignatureVerification.Valid?l===SignatureVerification.NotSigned?s(4):s(5):s(1)}))}dispose(){this.deviceMessageHandler.off("message",this.handleSASDeviceMessage)}observeUserTrust(e,t){const s=this.observedUsers.get(e);if(s)return s;const i=new RetainedObservableValue(void 0,(()=>{this.observedUsers.delete(e)}));return this.observedUsers.set(e,i),t.wrapDetached("get user trust",(async t=>{void 0===i.get()&&i.set(await this.getUserTrust(e,t))})),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}},r=this.hsApi.uploadSignatures(i,{log:t});return await r.response(),await this.deviceTracker.invalidateUserKeys(this.ownUserId),this.emitUserTrustUpdate(this.ownUserId,t),e}async getSigningKey(e){const t=await this.secretStorage.readSecret(`m.cross_signing.${e}`);if(t)return new Uint8Array(this.platform.encoding.base64.decode(t))}signKey(e,t){pkSign(this.olm,e,t,this.ownUserId,"")}hasValidSignatureFrom(e,t,s){const i=getKeyEd25519Key(t);return i?verifyEd25519Signature(this.olmUtil,t.user_id,i,i,e,s):SignatureVerification.NotSigned}emitUserTrustUpdate(e,t){const s=this.observedUsers.get(e);s&&void 0!==s.get()&&(s.set(void 0),t.wrapDetached("update user trust",(async t=>{s.set(await this.getUserTrust(e,t))})))}}function getKeyUsage(e){if(!Array.isArray(e.usage)||1!==e.usage.length)return;const t=e.usage[0];return"master"===t||"self_signing"===t||"user_signing"===t?t:void 0}const algorithm="ed25519",prefix="ed25519:";function getKeyEd25519Key(e){const t=Object.keys(e.keys).filter((e=>e.startsWith(prefix)));if(1!==t.length)return;const s=t[0];return e.keys[s]}function getKeyUserId(e){return e.user_id}var KeysTrackingStatus=(e=>(e[e.Outdated=0]="Outdated",e[e.UpToDate=1]="UpToDate",e))(KeysTrackingStatus||{});function createUserIdentity(e,t){return{userId:e,roomIds:t?[t]:[],keysTrackingStatus:0}}function addRoomToIdentity(e,t,s){return e?e.roomIds.includes(s)?void 0:(e.roomIds.push(s),e):e=createUserIdentity(t,s)}class DeviceTracker{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 e=>{const t=await i.get(e);t&&(s.log({l:"outdated",id:e}),t.keysTrackingStatus=0,i.set(t))})))}async writeMemberChanges(e,t,s,i){const r=[],n=[];return await Promise.all(Array.from(t.values()).map((async e=>{if(shouldShareKey(e.membership,s))await this._addRoomToUserIdentity(e.roomId,e.userId,i)&&r.push(e.userId);else if(shouldShareKey(e.previousMembership,s)){const{roomId:t}=e;if(e.userId===this._ownUserId){const e=await i.roomMembers.getAllUserIds(t);await Promise.all(e.map((e=>this._removeRoomFromUserIdentity(t,e,i))))}else await this._removeRoomFromUserIdentity(t,e.userId,i);n.push(e.userId)}}))),{added:r,removed:n}}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 n;try{n=e.writeIsTrackingMembers(!0,r);const o=Array.from(i.members.values());s.set("members",o.length),await Promise.all(o.map((async e=>{shouldShareKey(e.membership,t)?await this._addRoomToUserIdentity(e.roomId,e.userId,r):await this._removeRoomFromUserIdentity(e.roomId,e.userId,r)})))}catch(e){throw r.abort(),e}await r.complete(),e.applyIsTrackingMembersChanges(n)}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 i=>{const r=await this._storage.readTxn([this._storage.storeNames.userIdentities,this._storage.storeNames.crossSigningKeys]),n=await r.userIdentities.get(e);if(n&&0!==n.keysTrackingStatus)return await r.crossSigningKeys.get(e,t);if(!s)return;const o=await this._queryKeys([e],s,i);switch(t){case KeyUsage.Master:return o.masterKeys.get(e);case KeyUsage.SelfSigning:return o.selfSigningKeys.get(e);case KeyUsage.UserSigning:return o.userSigningKeys.get(e)}}))}async writeHistoryVisibility(e,t,s,i){const r=[],n=[];return e.isTrackingMembers&&e.isEncrypted&&await i.wrap("rewriting userIdentities",(async i=>{const o=await e.loadMemberList(s,i);try{const e=Array.from(o.members.values());i.set("members",e.length),await Promise.all(e.map((async e=>{shouldShareKey(e.membership,t)?await this._addRoomToUserIdentity(e.roomId,e.userId,s)&&r.push(e.userId):await this._removeRoomFromUserIdentity(e.roomId,e.userId,s)&&n.push(e.userId)})))}finally{o.release()}})),{added:r,removed:n}}async _addRoomToUserIdentity(e,t,s){const{userIdentities:i}=s,r=addRoomToIdentity(await i.get(t),t,e);return!!r&&(i.set(r),!0)}async _removeRoomFromUserIdentity(e,t,s){const{userIdentities:i,deviceKeys:r}=s,n=await i.get(t);return!!n&&(n.roomIds=n.roomIds.filter((t=>t!==e)),0===n.roomIds.length?(i.remove(t),r.removeAllForUser(t)):i.set(n),!0)}async _queryKeys(e,t,s){const i=await t.queryKeys({timeout:1e4,device_keys:e.reduce(((e,t)=>(e[t]=[],e)),{}),token:this._getSyncToken()},{log:s}).response(),r=s.wrap("master keys",(e=>this._filterVerifiedCrossSigningKeys(i.master_keys,KeyUsage.Master,e))),n=s.wrap("self-signing keys",(e=>this._filterVerifiedCrossSigningKeys(i.self_signing_keys,KeyUsage.SelfSigning,e))),o=s.wrap("user-signing keys",(e=>this._filterVerifiedCrossSigningKeys(i.user_signing_keys,KeyUsage.UserSigning,e))),a=s.wrap("device keys",(e=>this._filterVerifiedDeviceKeys(i.device_keys,e))),l=await this._storage.readWriteTxn([this._storage.storeNames.userIdentities,this._storage.storeNames.deviceKeys,this._storage.storeNames.crossSigningKeys]);try{for(const e of r.values())l.crossSigningKeys.set(e);for(const e of n.values())l.crossSigningKeys.set(e);for(const e of o.values())l.crossSigningKeys.set(e);let e=0;await Promise.all(Array.from(a.keys()).map((async t=>{let s=a.get(t);e+=s.length,s=await this._storeQueriedDevicesForUserId(t,s,l),a.set(t,s)}))),s.set("devices",e)}catch(e){throw l.abort(),e}return await l.complete(),{deviceKeys:a,masterKeys:r,selfSigningKeys:n,userSigningKeys:o}}async _storeQueriedDevicesForUserId(e,t,s){const i=await s.deviceKeys.getAllDeviceIds(e);for(const r of i)t.every((e=>e.device_id!==r))&&s.deviceKeys.remove(e,r);const r=[],n=[];await Promise.all(t.map((async e=>{if(i.includes(e.device_id)){const t=await s.deviceKeys.get(e.user_id,e.device_id);if(t&&getDeviceEd25519Key(t)!==getDeviceEd25519Key(e))return void r.push(t)}r.push(e),n.push(e)})));for(const e of n)s.deviceKeys.set(e);let o=await s.userIdentities.get(e);return o||(o=createUserIdentity(e)),o.keysTrackingStatus=1,s.userIdentities.set(o),r}_filterVerifiedCrossSigningKeys(e,t,s){const i=new Map;if(!e)return i;for(const[r,n]of Object.entries(e))s.wrap({l:r},(e=>{this._validateCrossSigningKey(r,n,t,e)&&i.set(getKeyUserId(n),n)}));return i}_validateCrossSigningKey(e,t,s,i){if(getKeyUserId(t)!==e)return i.log({l:"user_id mismatch",userId:t.user_id}),!1;if(getKeyUsage(t)!==s)return i.log({l:"usage mismatch",usage:t.usage}),!1;return!!getKeyEd25519Key(t)||(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,n]of Object.entries(e))t.wrap(r,(e=>{const o=Object.entries(n).filter((([i,n])=>e.wrap(i,(e=>{if(this._validateDeviceKey(r,i,n,e)){const e=getDeviceCurve25519Key(n);return s.has(e)?(t.log({l:"ignore device with duplicate curve25519 key",keys:n},t.level.Warn),!1):(s.add(e),!0)}return!1})))).map((([,e])=>e));i.set(r,o)}));return i}_validateDeviceKey(e,t,s,i){const r=s.device_id,n=s.user_id;if(n!==e)return i.log("user_id mismatch"),!1;if(r!==t)return i.log("device_id mismatch"),!1;const o=getDeviceEd25519Key(s),a=getDeviceCurve25519Key(s);if("string"!=typeof o||"string"!=typeof a)return i.log("ed25519 and/or curve25519 key invalid").set({deviceKey:s}),!1;const l=verifyEd25519Signature(this._olmUtil,n,r,o,s,i)===SignatureVerification.Valid;return l||i.log({l:"ignore device with invalid signature",keys:s},i.level.Warn),l}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=[],n=[];return await Promise.all(e.map((async e=>{const t=await i.userIdentities.get(e);t&&1===t.keysTrackingStatus?r.push(t):t&&0!==t.keysTrackingStatus||n.push(e)}))),this._devicesForUserIdentities(r,n,t,s)}async deviceForId(e,t,s,i){var r;const n=await this._storage.readTxn([this._storage.storeNames.deviceKeys]);let o=await n.deviceKeys.get(e,t);if(o)i.set("existingDevice",!0);else{const n=await s.queryKeys({timeout:1e4,device_keys:{[e]:[t]},token:this._getSyncToken()},{log:i}).response(),a=null==(r=i.wrap("verify",(e=>this._filterVerifiedDeviceKeys(n.device_keys,e))).get(e))?void 0:r.find((e=>e.device_id===t));if(!a)return;const l=await this._storage.readWriteTxn([this._storage.storeNames.deviceKeys]),c=await l.deviceKeys.get(e,t);if(c)o=c,i.set("existingDeviceAfterFetch",!0);else{try{l.deviceKeys.set(a),o=a,i.set("newDevice",!0)}catch(e){throw l.abort(),e}await l.complete()}}return o}async _devicesForUserIdsInTrackedRoom(e,t,s,i,r){const n=(await Promise.all(t.map((e=>s.userIdentities.get(e))))).filter((t=>t&&t.roomIds.includes(e))),o=n.filter((e=>1===e.keysTrackingStatus)),a=n.filter((e=>0===e.keysTrackingStatus)).map((e=>e.userId));let l=await this._devicesForUserIdentities(o,a,i,r);return l=l.filter((e=>!(e.user_id===this._ownUserId&&e.device_id===this._ownDeviceId))),l}async _devicesForUserIdentities(e,t,s,i){let r;if(i.set("uptodate",e.length),i.set("outdated",t.length),t.length){const{deviceKeys:e}=await this._queryKeys(t,s,i);r=e}const n=await this._storage.readTxn([this._storage.storeNames.deviceKeys]);let o=(await Promise.all(e.map((e=>n.deviceKeys.getAllForUserId(e.userId))))).reduce(((e,t)=>e.concat(t)),[]);if(r&&r.size)for(const e of r.values())o=o.concat(e);return o}async getDeviceByCurve25519Key(e,t){return await t.deviceKeys.getByCurve25519Key(e)}}const schema=[createInitialStores,createMemberStore,migrateSession,createE2EEStores,migrateEncryptionFlag,createAccountDataStore,createInviteStore,createArchivedRoomSummaryStore,migrateOperationScopeIndex,createTimelineRelationsStore,fixMissingRoomsInUserIdentities,changeSSSSKeyPrefix,backupAndRestoreE2EEAccountToLocalStorage,clearAllStores,addInboundSessionBackupIndex,migrateBackupStatus,createCallStore,applyCrossSigningChanges];function createDatabaseNameHelper(e){return{databaseName:e.name,get idbFactory(){throw new Error("unused")},get IDBKeyRange(){throw new Error("unused")},addWriteError(){}}}function createInitialStores(e){e.createObjectStore("session",{keyPath:"key"}),e.createObjectStore("roomSummary",{keyPath:"roomId"}),e.createObjectStore("timelineFragments",{keyPath:"key"});e.createObjectStore("timelineEvents",{keyPath:"key"}).createIndex("byEventId","eventIdKey",{unique:!0}),e.createObjectStore("roomState",{keyPath:"key"}),e.createObjectStore("pendingEvents",{keyPath:"key"})}async function createMemberStore(e,t){const s=new RoomMemberStore(e.createObjectStore("roomMembers",{keyPath:"key"})),i=t.objectStore("roomState");await iterateCursor(i.openCursor(),(e=>{if(e.event.type===EVENT_TYPE$1){i.delete(e.key);const t=RoomMember.fromMemberEvent(e.roomId,e.event);t&&s.set(t.serialize())}return NOT_DONE}))}async function migrateSession(e,t,s){const i=t.objectStore("session");try{const e=1,t=await reqAsPromise(i.get(e));if(t){i.delete(e);const{syncToken:r,syncFilterId:n,serverVersions:o}=t.value,a=new SessionStore(i,s);a.set("sync",{token:r,filterId:n}),a.set("serverVersions",o)}}catch(e){t.abort(),console.error("could not migrate session",e.stack)}}function createE2EEStores(e){e.createObjectStore("userIdentities",{keyPath:"userId"});e.createObjectStore("deviceIdentities",{keyPath:"key"}).createIndex("byCurve25519Key","curve25519Key",{unique:!0}),e.createObjectStore("olmSessions",{keyPath:"key"}),e.createObjectStore("inboundGroupSessions",{keyPath:"key"}),e.createObjectStore("outboundGroupSessions",{keyPath:"roomId"}),e.createObjectStore("groupSessionDecryptions",{keyPath:"key"});e.createObjectStore("operations",{keyPath:"id"}).createIndex("byTypeAndScope","typeScopeKey",{unique:!1})}async function migrateEncryptionFlag(e,t){var s;const i=t.objectStore("roomSummary"),r=t.objectStore("roomState"),n=[];await iterateCursor(i.openCursor(),(e=>(n.push(e),NOT_DONE)));for(const e of n){const t=await reqAsPromise(r.get(`${e.roomId}|m.room.encryption|`));t&&(e.encryption=null==(s=null==t?void 0:t.event)?void 0:s.content,delete e.isEncrypted,i.put(e))}}function createAccountDataStore(e){e.createObjectStore("accountData",{keyPath:"type"})}function createInviteStore(e){e.createObjectStore("invites",{keyPath:"roomId"})}function createArchivedRoomSummaryStore(e){e.createObjectStore("archivedRoomSummary",{keyPath:"summary.roomId"})}async function migrateOperationScopeIndex(e,t){try{const e=t.objectStore("operations");e.deleteIndex("byTypeAndScope"),await iterateCursor(e.openCursor(),((e,t,s)=>{const{typeScopeKey:i}=e;delete e.typeScopeKey;const[r,n]=i.split("|");return e.scopeTypeKey=encodeScopeTypeKey(n,r),s.update(e),NOT_DONE})),e.createIndex("byScopeAndType","scopeTypeKey",{unique:!1})}catch(e){t.abort(),console.error("could not migrate operations",e.stack)}}function createTimelineRelationsStore(e){e.createObjectStore("timelineRelations",{keyPath:"key"})}function fixMissingRoomsInUserIdentities(){}async function changeSSSSKeyPrefix(e,t){const s=t.objectStore("session"),i=await reqAsPromise(s.get("ssssKey"));i&&s.put({key:"e2ee:ssssKey",value:i.value})}async function backupAndRestoreE2EEAccountToLocalStorage(e,t,s,i){const r=t.objectStore("session"),n=new SessionStore(new Store(r,createDatabaseNameHelper(e)),s);n.writeE2EEIdentityToLocalStorage();const o=await n.tryRestoreE2EEIdentityFromLocalStorage(i);i.set("restored",o)}async function clearAllStores(e,t){for(const s of e.objectStoreNames){const e=t.objectStore(s);switch(s){case"inboundGroupSessions":case"outboundGroupSessions":case"olmSessions":case"operations":continue;case"session":await iterateCursor(e.openCursor(),((e,t,s)=>(t.startsWith("e2ee:")||s.delete(),NOT_DONE)));break;default:e.clear()}}}async function addInboundSessionBackupIndex(e,t,s,i){t.objectStore("inboundGroupSessions").createIndex("byBackup","backup",{unique:!1})}async function migrateBackupStatus(e,t,s,i){const r=t.objectStore("inboundGroupSessions");let n=0,o=0;await iterateCursor(r.openCursor(),((e,t,s)=>(e.session?(e.backup=BackupStatus.NotBackedUp,e.source=KeySource.DeviceMessage,s.update(e),n+=1):o+=1,NOT_DONE))),i.set("countWithoutSession",o),i.set("countWithSession",n)}function createCallStore(e){e.createObjectStore("calls",{keyPath:"key"})}async function applyCrossSigningChanges(e,t,s,i){e.createObjectStore("crossSigningKeys",{keyPath:"key"}),e.deleteObjectStore("deviceIdentities");e.createObjectStore("deviceKeys",{keyPath:"key"}).createIndex("byCurve25519Key","curve25519Key",{unique:!0});const r=t.objectStore("userIdentities");let n=0;await iterateCursor(r.openCursor(),((e,t,s)=>(delete e.deviceTrackingStatus,delete e.crossSigningKeys,e.keysTrackingStatus=KeysTrackingStatus.Outdated,s.update(e),n+=1,NOT_DONE))),i.set("marked_outdated",n)}async function detectWebkitEarlyCloseTxnBug(e){try{const t=await openDatabase("hydrogen_webkit_test_inactive_txn_bug",(e=>{e.createObjectStore("test",{keyPath:"key"})}),1,e),s=t.transaction(["test"],"readonly");await reqAsPromise(s.objectStore("test").get("somekey")),await new Promise((e=>setTimeout(e,0)));const i=t.transaction(["test"],"readwrite");await Promise.resolve(),i.objectStore("test").add({key:"somekey",value:"foo"}),await txnAsPromise(i),t.close()}catch(e){if("TransactionInactiveError"===e.name)return!0}return!1}const sessionName=e=>`hydrogen_session_${e}`,openDatabaseWithSessionId=function(e,t,s,i){return openDatabase(sessionName(e),((e,t,r,n)=>createStores(e,t,r,n,s,i)),schema.length,t)};async function requestPersistedStorage(){var e,t;const s=this;if(null==(t=null==(e=null==s?void 0:s.navigator)?void 0:e.storage)?void 0:t.persist)return await s.navigator.storage.persist();if(!(null==s?void 0:s.document.requestStorageAccess))return!1;try{return await s.document.requestStorageAccess(),!0}catch(e){return console.warn("requestStorageAccess threw an error:",e),!1}}class StorageFactory{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 s;await(null==(s=this._serviceWorkerHandler)?void 0:s.preventConcurrentSessionAccess(e)),requestPersistedStorage().then((e=>{e||t.log("no persisted storage, database can be evicted by browser",t.level.Warn)}));const i=await detectWebkitEarlyCloseTxnBug(this._idbFactory),r=await openDatabaseWithSessionId(e,this._idbFactory,this._localStorage,t);return new Storage(r,this._idbFactory,this._IDBKeyRange,i,this._localStorage,t.logger)}async delete(e){const t=sessionName(e);try{clearKeysFromLocalStorage(this._localStorage,t)}catch(e){}try{const e=this._idbFactory.deleteDatabase(t);await reqAsPromise(e)}catch(e){}}async export(e,t){const s=await openDatabaseWithSessionId(e,this._idbFactory,this._localStorage,t);return await exportSession(s)}async import(e,t,s){const i=await openDatabaseWithSessionId(e,this._idbFactory,this._localStorage,s);return await importSession(i,t)}}async function createStores(e,t,s,i,r,n){const o=s||0;return n.wrap({l:"storage migration",oldVersion:s,version:i},(async s=>{for(let n=o;n<i;++n){const i=schema[n];await s.wrap(`v${n+1}`,(s=>i(e,t,r,s)))}}))}class SessionInfoStorage{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 updateLastUsed(e,t){const s=await this.getAll();if(s){const i=s.find((t=>t.id===e));i&&(i.lastUsed=t,localStorage.setItem(this._name,JSON.stringify(s)))}}async updateToken(e,t,s,i){const r=await this.getAll();if(r){const n=r.find((t=>t.id===e));n&&(n.accessToken=t,n.accessTokenExpiresAt=s,n.refreshToken=i,localStorage.setItem(this._name,JSON.stringify(r)))}}async get(e){const t=await this.getAll();if(t)return t.find((t=>t.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((t=>t.id!==e)),localStorage.setItem(this._name,JSON.stringify(t))}}class SettingsStorage{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"string"==typeof s?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"string"==typeof s?"true"===s: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 UTF8{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)}}class Base64{encodeUnpadded(e){const t=base64__default.default.encode(e),s=t.indexOf("=");return-1!==s?t.substr(0,s):t}encode(e){return base64__default.default.encode(e)}decode(e){return base64__default.default.decode(e)}}function getAugmentedNamespace(e){if(e.__esModule)return e;var t=Object.defineProperty({},"__esModule",{value:!0});return Object.keys(e).forEach((function(s){var i=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,i.get?i:{enumerable:!0,get:function(){return e[s]}})})),t}var Buffer={isBuffer:function(e){return e instanceof Uint8Array},from:function(e){return e},allocUnsafe:function(e){return Buffer.alloc(e)},alloc:function(e){return new Uint8Array(e)}},safeBuffer=Object.freeze(Object.defineProperty({__proto__:null,Buffer:Buffer},Symbol.toStringTag,{value:"Module"})),require$$0=getAugmentedNamespace(safeBuffer),_Buffer=require$$0.Buffer;function base(e){if(e.length>=255)throw new TypeError("Alphabet too long");for(var t=new Uint8Array(256),s=0;s<t.length;s++)t[s]=255;for(var i=0;i<e.length;i++){var r=e.charAt(i),n=r.charCodeAt(0);if(255!==t[n])throw new TypeError(r+" is ambiguous");t[n]=i}var o=e.length,a=e.charAt(0),l=Math.log(o)/Math.log(256),c=Math.log(256)/Math.log(o);function d(e){if("string"!=typeof e)throw new TypeError("Expected String");if(0===e.length)return _Buffer.alloc(0);var s=0;if(" "!==e[s]){for(var i=0,r=0;e[s]===a;)i++,s++;for(var n=(e.length-s)*l+1>>>0,c=new Uint8Array(n);e[s];){var d=t[e.charCodeAt(s)];if(255===d)return;for(var h=0,u=n-1;(0!==d||h<r)&&-1!==u;u--,h++)d+=o*c[u]>>>0,c[u]=d%256>>>0,d=d/256>>>0;if(0!==d)throw new Error("Non-zero carry");r=h,s++}if(" "!==e[s]){for(var m=n-r;m!==n&&0===c[m];)m++;var p=_Buffer.allocUnsafe(i+(n-m));p.fill(0,0,i);for(var g=i;m!==n;)p[g++]=c[m++];return p}}}return{encode:function(t){if((Array.isArray(t)||t instanceof Uint8Array)&&(t=_Buffer.from(t)),!_Buffer.isBuffer(t))throw new TypeError("Expected Buffer");if(0===t.length)return"";for(var s=0,i=0,r=0,n=t.length;r!==n&&0===t[r];)r++,s++;for(var l=(n-r)*c+1>>>0,d=new Uint8Array(l);r!==n;){for(var h=t[r],u=0,m=l-1;(0!==h||u<i)&&-1!==m;m--,u++)h+=256*d[m]>>>0,d[m]=h%o>>>0,h=h/o>>>0;if(0!==h)throw new Error("Non-zero carry");i=u,r++}for(var p=l-i;p!==l&&0===d[p];)p++;for(var g=a.repeat(s);p<l;++p)g+=e.charAt(d[p]);return g},decodeUnsafe:d,decode:function(e){var t=d(e);if(t)return t;throw new Error("Non-base"+o+" character")}}}var src=base,basex=src,ALPHABET="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",bs58=basex(ALPHABET);class Base58{encode(e){return bs58.encode(e)}decode(e){return bs58.decode(e)}}class Encoding{constructor(){this.utf8=new UTF8,this.base64=new Base64,this.base58=new Base58}}class OlmWorker{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(32*t))]);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 n;window.msCrypto&&(n=[window.msCrypto.getRandomValues(new Uint8Array(64))]);const o=await this._workerPool.send({type:"olm_create_outbound",accountPickle:r,theirIdentityKey:s,theirOneTimeKey:i,randomValues:n}).response();t.unpickle("",o)}dispose(){this._workerPool.dispose()}}function isChildren(e){return"object"!=typeof e||"nodeType"in e||Array.isArray(e)}function classNames(e,t){return Object.entries(e).reduce(((e,[s,i])=>("function"==typeof i&&(i=i(t)),i?e+(e.length?" ":"")+s:e)),"")}function setAttribute(e,t,s){"className"===t&&(t="class"),!1===s?e.removeAttribute(t):(!0===s&&(s=t),e.setAttribute(t,s))}function el(e,t,s){return elNS(HTML_NS,e,t,s)}function elNS(e,t,s,i){s&&isChildren(s)&&(i=s,s=void 0);const r=document.createElementNS(e,t);if(s)for(let[e,t]of Object.entries(s))"object"==typeof t&&(t=null!==t&&"className"===e&&classNames(t,void 0)),setAttribute(r,e,t);if(i){Array.isArray(i)||(i=[i]);for(let e of i)"string"==typeof e&&(e=text(e)),r.appendChild(e)}return r}function text(e){return document.createTextNode(e)}const HTML_NS="http://www.w3.org/1999/xhtml",SVG_NS="http://www.w3.org/2000/svg",TAG_NAMES={[HTML_NS]:["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"],[SVG_NS]:["svg","g","path","circle","ellipse","rect","use"]},tag={};for(const[e,t]of Object.entries(TAG_NAMES))for(const s of t)tag[s]=function(t,i){return elNS(e,s,t,i)};function mountView(e,t){let s;try{s=e.mount(t)}catch(e){console.error(e),s=errorToDOM(e)}return s}function errorToDOM(e){const t=(new Error).stack;let s=null;return t&&(s=t.split("\n")[1]),tag.div([tag.h2("Something went wrong…"),tag.h3(e.message),tag.p(`This occurred while running ${s}.`),tag.pre(e.stack)])}function insertAt(e,t,s){if(t===e.childElementCount)e.appendChild(s);else{const i=e.children[t];e.insertBefore(s,i)}}function removeChildren(e){e.innerHTML=""}function disableTargetCallback$1(e){return async t=>{var s,i;null==(s=t.target)||s.setAttribute("disabled","disabled"),await e(t),null==(i=t.target)||i.removeAttribute("disabled")}}class ListView{constructor({list:e,onItemClick:t,className:s,tagName:i="ul",parentProvidesUpdates:r=!0},n){this._onItemClick=t,this._list=e,this._className=s,this._tagName=i,this._root=void 0,this._subscription=void 0,this._childCreator=n,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=el(this._tagName,e);return this.loadList(),this._onItemClick&&t.addEventListener("click",this),t}handleEvent(e){"click"===e.type&&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(mountView(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),insertAt(this._root,e,mountView(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(),insertAt(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){const[t]=this._childInstances.splice(e,1,s);this._root.replaceChild(s.mount(this._mountArgs),t.root()),t.unmount()}else this.onRemove(e,t)}}getChildInstanceByIndex(e){var t;return null==(t=this._childInstances)?void 0:t[e]}}class BaseUpdateView{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;"function"==typeof(null==(e=this._value)?void 0:e.on)&&(this._boundUpdateFromValue=this._updateFromValue.bind(this),this._value.on("change",this._boundUpdateFromValue))}_unsubscribe(){this._boundUpdateFromValue&&("function"==typeof this._value.off&&this._value.off("change",this._boundUpdateFromValue),this._boundUpdateFromValue=null)}}function objHasFns(e){for(const t of Object.values(e))if("function"==typeof t)return!0;return!1}class TemplateView extends BaseUpdateView{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 TemplateBuilder(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 e of this._bindings)e()}_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);-1!==t&&this._subViews.splice(t,1)}updateSubViews(e,t){if(this._subViews)for(const s of this._subViews)s.update(e,t)}}class TemplateBuilder{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 r=s(this._value);i!==r&&(i=r,setAttribute(e,t,r))};this._addBinding(r),r()}_addClassNamesBinding(e,t){this._addAttributeBinding(e,"className",(e=>classNames(t,e)))}_addTextBinding(e){const t=e(this._value)+"",s=text(t);let i=t;return this._addBinding((()=>{const t=e(this._value)+"";i!==t&&(i=t,s.textContent=t)})),s}_isEventHandler(e,t){return e.startsWith("on")&&e.length>2&&"function"==typeof t}_setNodeAttributes(e,t){for(let[s,i]of Object.entries(t))if("object"==typeof i){if("className"!==s||null===i)continue;objHasFns(i)?this._addClassNamesBinding(e,i):setAttribute(e,s,classNames(i,this._value))}else if(this._isEventHandler(s,i)){const t=s.substr(2,1).toLowerCase()+s.substr(3),r=i;this._templateView._addEventListener(e,t,r)}else"function"==typeof i?this._addAttributeBinding(e,s,i):setAttribute(e,s,i)}_setNodeChildren(e,t){Array.isArray(t)||(t=[t]);for(let s of t)"function"==typeof s?s=this._addTextBinding(s):"string"==typeof s&&(s=text(s)),e.appendChild(s)}_addReplaceNodeBinding(e,t){let s=e(this._value),i=t(null);return this._addBinding((()=>{const r=e(this._value);if(s!==r){s=r;const e=t(i);i.parentNode&&i.parentNode.replaceChild(e,i),i=e}})),i}el(e,t,s){return this.elNS(HTML_NS,e,t,s)}elNS(e,t,s,i){let r;s&&(isChildren(s)?i=s:r=s);const n=document.createElementNS(e,t);return r&&this._setNodeAttributes(n,r),i&&this._setNodeChildren(n,i),n}view(e,t){return this._templateView.addSubView(e),mountView(e,t)}mapView(e,t){return this._addReplaceNodeBinding(e,(s=>{if(s&&s.nodeType!==Node.COMMENT_NODE){const e=this._templateView._subViews;if(e){const t=e.findIndex((e=>e.root()===s));if(-1!==t){const[s]=e.splice(t,1);s.unmount()}}}const i=t(e(this._value));return i?this.view(i):document.createComment("node binding placeholder")}))}map(e,t){return this.mapView(e,(e=>new InlineTemplateView(this._value,((s,i)=>{const r=t(e,s,i);return r||document.createComment("map placeholder")}))))}ifView(e,t){return this.mapView((t=>!!e(t)),(e=>e?t(this._value):null))}if(e,t){return this.ifView(e,(e=>new InlineTemplateView(e,t)))}mapSideEffect(e,t){let s=e(this._value);this._addBinding((()=>{const i=e(this._value);s!==i&&(t(i,s,this._value),s=i)})),t(s,void 0,this._value)}}for(const[e,t]of Object.entries(TAG_NAMES))for(const s of t)TemplateBuilder.prototype[s]=function(t,i){return this.elNS(e,s,t,i)};class InlineTemplateView extends TemplateView{constructor(e,t){super(e),this._render=t}render(e,t){return this._render(e,t)}}function renderStaticAvatar(e,t,s=void 0){const i=!!e.avatarUrl(t);let r=classNames({avatar:!0,[`size-${t}`]:!0,[`usercolor${e.avatarColorNumber}`]:!i});s&&(r+=` ${s}`);const n=i?renderImg(e,t):text(e.avatarLetter),o=tag.div({className:r,title:e.avatarTitle,"data-testid":"avatar"},[n]);return i&&(setAttribute(o,"data-avatar-letter",e.avatarLetter),setAttribute(o,"data-avatar-color",e.avatarColorNumber)),o}function renderImg(e,t){const s=t.toString();return tag.img({src:e.avatarUrl(t),width:s,height:s,title:e.avatarTitle})}function isAvatarEvent(e){const t=e.target,s=t.parentElement;return"IMG"===t.tagName&&s.classList.contains("avatar")}function handleAvatarError(e){if(!isAvatarEvent(e))return;const t=e.target.parentElement,s=t.getAttribute("data-avatar-color");t.classList.add(`usercolor${s}`);const i=t.getAttribute("data-avatar-letter");t.textContent=i}class AvatarView extends BaseUpdateView{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)}_avatarTitleChanged(){return this.value.avatarTitle!==this._avatarTitle&&(this._avatarTitle=this.value.avatarTitle,!0)}_avatarLetterChanged(){return this.value.avatarLetter!==this._avatarLetter&&(this._avatarLetter=this.value.avatarLetter,!0)}mount(e){return this._avatarUrlChanged(),this._avatarLetterChanged(),this._avatarTitleChanged(),this._root=renderStaticAvatar(this.value,this._size),this.subscribeOnMount(e),this._root}root(){return this._root}update(e){if(this._avatarUrlChanged()){const t=`usercolor${e.avatarColorNumber}`;e.avatarUrl(this._size)?(this._root.replaceChild(renderImg(e,this._size),this._root.firstChild),this._root.classList.remove(t)):(this._root.textContent=e.avatarLetter,this._root.classList.add(t))}const t=!!e.avatarUrl(this._size);if(this._avatarTitleChanged()&&t){const t=this._root.firstChild;"IMG"===t.tagName&&t.setAttribute("title",e.avatarTitle)}this._avatarLetterChanged()&&!t&&(this._root.textContent=e.avatarLetter)}}let container;function spinner(e,t=void 0){void 0===container&&(container=document.querySelector(".hydrogen"));const s=Object.assign({spinner:!0},t);return(null==container?void 0:container.classList.contains("legacy"))?e.div({className:s},[e.div(),e.div(),e.div(),e.div()]):e.svg({className:s,viewBox:"0 0 100 100"},e.circle({cx:"50%",cy:"50%",r:"45%",pathLength:"100"}))}class RoomTileView extends TemplateView{render(e,t){return e.li({className:{active:e=>e.isOpen,hidden:e=>e.hidden}},[e.a({href:t.url},[e.view(new AvatarView(t,32),{parentProvidesUpdates:!0}),e.div({className:"description"},[e.div({className:{name:!0,unread:e=>e.isUnread}},(e=>e.name)),e.map((e=>e.busy),(t=>t?spinner(e):e.div({className:{badge:!0,highlighted:e=>e.isHighlighted,hidden:e=>!e.badgeCount}},(e=>e.badgeCount))))])])])}update(e,t){super.update(e),this.updateSubViews(e,t)}}class Menu extends TemplateView{static option(e,t){return new MenuOption(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 MenuOption{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 Popup{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=tag.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=findScrollParent(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){"scroll"===e.type?this._position()||this.close():"click"===e.type&&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<i.top||e.right<i.left)return!1;if(i.bottom>=e.bottom+s)this._popup.style.top=`${e.bottom+this._verticalPadding}px`;else{if(!(i.top<=e.top-s))return!1;this._popup.style.top=e.top-s-this._verticalPadding+"px"}if(i.right>=e.right+t)this._popup.style.left=`${e.left}px`;else{if(!(i.left<=e.left-t))return!1;this._popup.style.left=e.right-t+"px"}return!0}root(){return this._fakeRoot}mount(){return this._fakeRoot=document.createComment("popup"),this._fakeRoot}unmount(){this.close()}update(){}}function findScrollParent(e){let t=e;do{if(t=t.parentElement,t.scrollHeight>t.clientHeight){const e=window.getComputedStyle(t).getPropertyValue("overflow-y");if("auto"===e||"scroll"===e)return t}}while(t!==document.body)}class FilterField extends TemplateView{render(e,t){const s=()=>{i.value="",i.blur(),r.blur(),t.clear()},i=e.input({type:"text",placeholder:null==t?void 0:t.label,"aria-label":null==t?void 0:t.label,autocomplete:null==t?void 0:t.autocomplete,enterkeyhint:"search",name:null==t?void 0:t.name,onInput:e=>t.set(e.target.value),onKeydown:e=>{"Escape"!==e.key&&"Esc"!==e.key||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 LeftPanelView extends TemplateView{constructor(e){super(e),this._createMenuPopup=null}render(e,t){const s=e=>e.gridEnabled?e.i18n`Show single room`:e.i18n`Enable grid layout`,i=e.view(new ListView({className:"RoomList",list:t.tileViewModels},(e=>new RoomTileView(e)))),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 FilterField({i18n:t.i18n,label:t.i18n`Filter rooms…`,name:"room-filter",autocomplete:!0,set:e=>{t.setFilter(e)&&(i.scrollTop=0)},clear:()=>t.clearFilter()})),e.button({onClick:()=>t.toggleGrid(),className:{"button-utility":!0,grid:!0,on:e=>e.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:e=>this._toggleCreateMenu(e)})]);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(Menu.option(t.i18n`Create Room`,(()=>t.showCreateRoomView()))),s.push(Menu.option(t.i18n`Join Room`,(()=>t.showJoinRoomView()))),this._createMenuPopup=new Popup(new Menu(s)),this._createMenuPopup.trackInTemplateView(this),this._createMenuPopup.showRelativeTo(e.target,10)}}}function bottom(e){return e.offsetTop+e.clientHeight}function findFirstNodeIndexAtOrBelow(e,t,s=e.children.length-1){for(var i=s;i>=0;i--){if(e.children[i].offsetTop<t)return i}return 0}class TimelineView extends TemplateView{constructor(e,t){super(e),this.viewClassForTile=t,this.anchoredBottom=0,this.stickToBottom=!0}render(e,t){requestAnimationFrame((()=>{this.restoreScrollPosition()})),this.tilesView=new TilesListView(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:e=>!e.showJumpDown},title:"Jump down",onClick:()=>this.jumpDown()})]);return"function"==typeof ResizeObserver&&(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 e=this.value.tiles.length;this.updateVisibleRange(0,e-1)}else if(t.style.removeProperty("margin-top"),this.stickToBottom)e.scrollTop=e.scrollHeight;else if(this.anchoredNode){const t=bottom(this.anchoredNode);if(t!==this.anchoredBottom){const s=t-this.anchoredBottom;"function"==typeof e.scrollBy?e.scrollBy(0,s):e.scrollTop=e.scrollTop+s,this.anchoredBottom=t}}}onScroll(){const{scrollNode:e,tilesNode:t}=this,{scrollHeight:s,scrollTop:i,clientHeight:r}=e;let n;if(this.stickToBottom=Math.abs(s-(i+r))<1,this.stickToBottom){n=this.value.tiles.length-1}else{const e=findFirstNodeIndexAtOrBelow(t,i+r);this.anchoredNode=t.childNodes[e],this.anchoredBottom=bottom(this.anchoredNode),n=e}let o=findFirstNodeIndexAtOrBelow(t,i,n);this.updateVisibleRange(o,n)}updateVisibleRange(e,t){const s=this.tilesView.getChildInstanceByIndex(e),i=this.tilesView.getChildInstanceByIndex(t);this.value.setVisibleTileRange(null==s?void 0:s.value,null==i?void 0:i.value)}}class TilesListView extends ListView{constructor(e,t,s){super({list:e,onItemClick:(e,t)=>e.onClick(t)},(e=>new(s(e))(e,s))),this.viewClassForTile=s,this.onChanged=t}onReset(){super.onReset(),this.onChanged()}onUpdate(e,t,s){if("shape"===s){const s=this.viewClassForTile(t),i=this.getChildInstanceByIndex(e);if(!(s&&i instanceof s))return void super.recreateItem(e,t)}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 TimelineLoadingView extends TemplateView{render(e,t){return e.div({className:"TimelineLoadingView"},[spinner(e),e.div(t.isEncrypted?t.i18n`Loading encrypted messages…`:t.i18n`Loading messages…`)])}}class MessageComposer extends TemplateView{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:e=>this._onKeyDown(e),onInput:()=>{t.setInput(this._input.value),this._input.value?this._adjustHeight():this._clearHeight()},placeholder:e=>e.isEncrypted?"Send an encrypted message…":"Send a message…",rows:"1"}),this._focusInput=()=>this._input.focus(),this.value.on("focus",this._focusInput);const s=e.map((e=>e.replyViewModel),((e,t)=>{const s=e&&this._viewClassForTile(e);return s?t.div({className:"MessageComposer_replyPreview"},[t.span({className:"replying"},"Replying"),t.button({className:"cancel",onClick:()=>this._clearReplyingTo()},"Close"),t.view(new s(e,this._viewClassForTile,{interactive:!1},"div"))]):null})),i=e.div({className:"MessageComposer_input"},[this._input,e.button({className:"sendFile",title:t.i18n`Pick attachment`,onClick:e=>this._toggleAttachmentMenu(e)},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:e=>e.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(e){t(),console.error(e)}}_onKeyDown(e){"Enter"!==e.key||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 Popup(new Menu([Menu.option(t.i18n`Send video`,(()=>t.sendVideo())).setIcon("video"),Menu.option(t.i18n`Send picture`,(()=>t.sendPicture())).setIcon("picture"),Menu.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 DisabledComposerView extends TemplateView{render(e){return e.div({className:"DisabledComposerView"},e.h3((e=>e.description)))}}class ErrorView$1 extends TemplateView{constructor(e,t={inline:!1}){super(e),this.options=t}render(e,t){const s=e.button({className:"ErrorView_submit",onClick:disableTargetCallback$1((async e=>{e.stopPropagation(),await t.submitLogs()?alert("Logs submitted!"):alert("Could not submit logs")}))},"Submit logs"),i=e.button({className:"ErrorView_close",onClick:e=>{e.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 CallView extends TemplateView{render(e,t){const s=e.view(new ListView({className:"CallView_members",list:t.memberViewModels},(e=>new StreamView(e))));return this.bindMembersCssClasses(e,s),e.div({class:"CallView"},[s,e.div({class:"CallView_buttons"},[e.button({className:{CallView_mutedMicrophone:e=>e.isMicrophoneMuted,CallView_unmutedMicrophone:e=>!e.isMicrophoneMuted},onClick:disableTargetCallback((()=>t.toggleMicrophone()))}),e.button({className:{CallView_mutedCamera:e=>e.isCameraMuted,CallView_unmutedCamera:e=>!e.isCameraMuted},onClick:disableTargetCallback((()=>t.toggleCamera()))}),e.button({className:"CallView_hangup",onClick:disableTargetCallback((()=>t.hangup()))})]),e.if((e=>!!e.errorViewModel),(e=>e.div({className:"CallView_error"},e.view(new ErrorView$1(t.errorViewModel)))))])}bindMembersCssClasses(e,t){if(e.mapSideEffect((e=>e.memberCount),(e=>{t.classList.forEach(((e,t,s)=>{e.startsWith("size")&&s.remove(e)})),t.classList.add(`size${e}`)})),"function"==typeof ResizeObserver){const e=(e,s)=>{s?t.classList.add(e):t.classList.remove(e)};this.resizeObserver=new ResizeObserver((()=>{const s=t.clientWidth/t.clientHeight,i=s<.5,r=!i&&s<1.8,n=!i&&!r;e("tall",i),e("square",r),e("wide",n)})),this.resizeObserver.observe(t)}}unmount(){this.resizeObserver&&(this.resizeObserver.unobserve(this.root().querySelector(".CallView_members")),this.resizeObserver=void 0),super.unmount()}}class StreamView extends TemplateView{render(e,t){const s=e.video({autoplay:!0,disablePictureInPicture:!0,className:{hidden:e=>e.isCameraMuted}});return e.mapSideEffect((e=>e.stream),(e=>{s.srcObject=e})),e.div({className:"StreamView"},[s,e.div({className:{StreamView_avatar:!0,hidden:e=>!e.isCameraMuted}},e.view(new AvatarView(t,96),{parentProvidesUpdates:!0})),e.div({className:{StreamView_muteStatus:!0,hidden:e=>!e.isCameraMuted&&!e.isMicrophoneMuted,microphoneMuted:e=>e.isMicrophoneMuted&&!e.isCameraMuted,cameraMuted:e=>e.isCameraMuted}}),e.if((e=>!!e.errorViewModel),(e=>e.div({className:"StreamView_error"},e.view(new ErrorView$1(t.errorViewModel)))))])}update(e,t){super.update(e),this.updateSubViews(e,t)}}function disableTargetCallback(e){return async t=>{var s,i;null==(s=t.target)||s.setAttribute("disabled","disabled"),await e(t),null==(i=t.target)||i.removeAttribute("disabled")}}class RoomView extends TemplateView{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 AvatarView(t,32)),e.div({className:"room-description"},[e.h2((e=>e.name))]),e.button({className:"button-utility room-options","aria-label":t.i18n`Room options`,onClick:e=>this._toggleOptionsMenu(e)})]),e.div({className:"RoomView_body"},[e.if((e=>e.errorViewModel),(e=>e.div({className:"RoomView_error"},e.view(new ErrorView$1(t.errorViewModel))))),e.mapView((e=>e.callViewModel),(e=>e?new CallView(e):null)),e.mapView((e=>e.timelineViewModel),(e=>e?new TimelineView(e,this._viewClassForTile):new TimelineLoadingView(t))),e.mapView((e=>e.composerViewModel),(e=>{switch(null==e?void 0:e.kind){case"composer":return new MessageComposer(t.composerViewModel,this._viewClassForTile);case"disabled":return new DisabledComposerView(t.composerViewModel)}}))])])}_toggleOptionsMenu(e){if(this._optionsPopup&&this._optionsPopup.isOpen)this._optionsPopup.close();else{const t=this.value,s=[];if(s.push(Menu.option(t.i18n`Room details`,(()=>t.openDetailsPanel()))),t.features.calls&&s.push(Menu.option(t.i18n`Start call`,(()=>t.startCall()))),t.canLeave&&s.push(Menu.option(t.i18n`Leave room`,(()=>this._confirmToLeaveRoom())).setDestructive()),t.canForget&&s.push(Menu.option(t.i18n`Forget room`,(()=>t.forgetRoom())).setDestructive()),t.canRejoin&&s.push(Menu.option(t.i18n`Rejoin room`,(()=>t.rejoinRoom()))),!s.length)return;this._optionsPopup=new Popup(new Menu(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 UnknownRoomView extends TemplateView{render(e,t){return e.main({className:"UnknownRoomView middle"},e.div([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:e=>e.busy},t.i18n`Join room`),e.if((e=>e.error),(e=>e.p({className:"error"},t.error)))]))}}class StaticView{constructor(e,t=void 0){"function"!=typeof e||t||(t=e,e=null),this._root=t?t(tag,e):this.render(tag,e)}mount(){return this._root}root(){return this._root}unmount(){}update(){}}class LoadingView extends StaticView{constructor(e="Loading"){super(e,((e,t)=>e.div({className:"LoadingView"},[spinner(e),t])))}}class RoomBeingCreatedView extends TemplateView{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 AvatarView(t,32)),e.div({className:"room-description"},[e.h2((e=>e.name))])]),e.div({className:"RoomView_body"},[e.mapView((e=>e.error),(e=>e?new ErrorView(t):new LoadingView(t.i18n`Setting up the room…`)))])])}}class ErrorView extends TemplateView{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 InviteView extends TemplateView{render(e,t){var s;let i,r=[];return t.isDirectMessage&&r.push(renderStaticAvatar(t,128,"InviteView_dmAvatar")),i=t.isDirectMessage?[e.strong(t.name),` (${null==(s=t.inviter)?void 0:s.id}) wants to chat with you.`]:t.inviter?[renderStaticAvatar(t.inviter,24),e.strong(t.inviter.name),` (${t.inviter.id}) invited you.`]:"You were invited to join.",r.push(e.p({className:"InviteView_inviter"},i)),t.isDirectMessage||r.push(e.div({className:"InviteView_roomProfile"},[renderStaticAvatar(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`}),renderStaticAvatar(t,32),e.div({className:"room-description"},[e.h2((e=>e.name))])]),e.if((e=>e.error),(e=>e.div({className:"RoomView_error"},(e=>e.error)))),e.div({className:"InviteView_body"},[e.div({className:"InviteView_invite"},[...r,e.div({className:"InviteView_buttonRow"},e.button({className:"button-action primary",disabled:e=>e.busy,onClick:()=>t.accept()},t.i18n`Accept`)),e.div({className:"InviteView_buttonRow"},e.button({className:"button-action primary destructive",disabled:e=>e.busy,onClick:()=>t.reject()},t.i18n`Reject`))])])])}}class LightboxView extends TemplateView{render(e,t){const s=e.a({href:t.closeUrl,title:t.i18n`Close`,className:"close"}),i=e.div({role:"img","aria-label":e=>e.name,title:e=>e.name,className:{picture:!0,hidden:e=>!e.imageUrl},style:e=>`background-image: url('${e.imageUrl}'); max-width: ${e.imageWidth}px; max-height: ${e.imageHeight}px;`}),r=e.div({className:{loading:!0,hidden:e=>!!e.imageUrl}},[spinner(e),e.div(t.i18n`Loading image…`)]),n=e.div({className:"details"},[e.strong((e=>e.name)),e.br(),"uploaded by ",e.strong((e=>e.sender)),e=>` at ${e.time} on ${e.date}.`]),o=e.div({role:"dialog",className:"lightbox",onClick:e=>this.clickToClose(e),onKeydown:e=>this.closeOnEscKey(e)},[i,r,n,s]);return trapFocus(e,o),o}clickToClose(e){e.target===this.root()&&this.value.close()}closeOnEscKey(e){"Escape"!==e.key&&"Esc"!==e.key||this.value.close()}}function trapFocus(e,t){const s=focusables(t),i=s[0],r=s[s.length-1];e.addEventListener(t,"keydown",(e=>{"Tab"===e.key&&(e.shiftKey?document.activeElement===i&&(r.focus(),e.preventDefault()):document.activeElement===r&&(i.focus(),e.preventDefault()))}),!0),Promise.resolve().then((()=>{i.focus()}))}function focusables(e){return e.querySelectorAll("a[href], button, textarea, input, select")}class SessionStatusView extends TemplateView{render(e,t){return e.div({className:{SessionStatusView:!0,hidden:e=>!e.isShown}},[spinner(e,{hidden:e=>!e.isWaiting}),e.p((e=>e.statusLabel)),e.if((e=>e.isConnectNowShown),(e=>e.button({className:"link",onClick:()=>t.connectNow()},"Retry now"))),e.if((e=>e.isSecretStorageShown),(e=>e.a({href:t.setupKeyBackupUrl},"Go to settings"))),e.if((e=>e.canDismiss),(e=>e.div({className:"end"},e.button({className:"dismiss",onClick:()=>t.dismiss()}))))])}}class RoomGridView extends TemplateView{constructor(e,t){super(e),this._viewClassForTile=t}render(e,t){const s=[];for(let i=0;i<t.height*t.width;i+=1)s.push(e.div({onClick:()=>t.focusTile(i),onFocusin:()=>t.focusTile(i),className:{container:!0,[`tile${i}`]:!0,focused:e=>e.focusIndex===i}},e.mapView((e=>e.roomViewModelAt(i)),(e=>e?"roomBeingCreated"===e.kind?new RoomBeingCreatedView(e):"invite"===e.kind?new InviteView(e):new RoomView(e,this._viewClassForTile):new StaticView((e=>e.div({className:"room-placeholder"},[e.h2({className:"focused"},t.i18n`Select a room on the left`),e.h2({className:"unfocused"},t.i18n`Click to select this tile`)])))))));return s.push(e.div({className:e=>`focus-ring tile${e.focusIndex}`})),e.div({className:"RoomGridView middle layout3x2"},s)}}class ViewModel extends EventEmitter{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 s=this.navigation.observe(e).subscribe((s=>{t(s,e)}));this.track(s)}track(e){return this.disposables||(this.disposables=new Disposables),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;i<e.length;++i)s+=e[i],i<t.length&&(s+=t[i]);return s}emitChange(e){this._options.emitChange?this._options.emitChange(e):this.emit("change",e)}get platform(){return this._options.platform}get clock(){return this._options.platform.clock}get logger(){return this.platform.logger}get urlRouter(){return this._options.urlRouter}get features(){return this._options.features}get navigation(){return this._options.navigation}get timeFormatter(){return this._options.platform.timeFormatter}}class KeyDescription{constructor(e,t){this._id=e,this._keyDescription=t}get id(){return this._id}get passphraseParams(){var e;return null==(e=this._keyDescription)?void 0:e.passphrase}get algorithm(){var e;return null==(e=this._keyDescription)?void 0:e.algorithm}async isCompatible(e,t){if("m.secret_storage.v1.aes-hmac-sha2"===this.algorithm){const s=this._keyDescription;if(s.mac){const i=await calculateKeyMac(e.binaryKey,s.iv,t);return s.mac===i}if(s.passphrase){const t=e.description._keyDescription;return!!t.passphrase&&(s.passphrase.algorithm===t.passphrase.algorithm&&s.passphrase.iterations===t.passphrase.iterations&&s.passphrase.salt===t.passphrase.salt)}}return!1}}class Key{constructor(e,t){this._keyDescription=e,this._binaryKey=t}withDescription(e){return new Key(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 calculateKeyMac(e,t,s){const{crypto:i,encoding:r}=s,{utf8:n,base64:o}=r,{derive:a,aes:l,hmac:c}=i,d=o.decode(t),h=new Uint8Array(8),u=n.encode(""),m=await a.hkdf(e,h,u,"SHA-256",512),p=m.slice(0,32),g=m.slice(32),_=await l.encryptCTR({key:p,iv:d,data:n.encode("\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")}),y=await c.compute(g,_,"SHA-256");return o.encode(y)}const DEFAULT_ITERATIONS=5e5,DEFAULT_BITSIZE=256;async function keyFromPassphrase(e,t,s){const{passphraseParams:i}=e;if(!i)throw new Error("not a passphrase key");if("m.pbkdf2"!==i.algorithm)throw new Error(`Unsupported passphrase algorithm: ${i.algorithm}`);const{utf8:r}=s.encoding,n=await s.crypto.derive.pbkdf2(r.encode(t),i.iterations||5e5,r.encode(i.salt),"SHA-512",i.bits||256);return new Key(e,n)}const OLM_RECOVERY_KEY_PREFIX=[139,1];function keyFromRecoveryKey(e,t,s,i){const r=i.encoding.base58.decode(t.replace(/ /g,""));let n=0;for(const e of r)n^=e;if(0!==n)throw new Error("Incorrect parity");for(let e=0;e<OLM_RECOVERY_KEY_PREFIX.length;++e)if(r[e]!==OLM_RECOVERY_KEY_PREFIX[e])throw new Error("Incorrect prefix");if(r.length!==OLM_RECOVERY_KEY_PREFIX.length+s.PRIVATE_KEY_LENGTH+1)throw new Error("Incorrect length");const o=Uint8Array.from(r.slice(OLM_RECOVERY_KEY_PREFIX.length,OLM_RECOVERY_KEY_PREFIX.length+s.PRIVATE_KEY_LENGTH));return new Key(e,o)}const SSSS_KEY="e2ee:ssssKey",BACKUPVERSION_KEY="e2ee:keyBackupVersion";var KeyType=(e=>(e[e.RecoveryKey=0]="RecoveryKey",e[e.Passphrase=1]="Passphrase",e))(KeyType||{});async function readDefaultKeyDescription(e){var t;const s=await e.readTxn([e.storeNames.accountData]),i=await s.accountData.get("m.secret_storage.default_key"),r=null==(t=null==i?void 0:i.content)?void 0:t.key;if(!r)return;const n=await s.accountData.get(`m.secret_storage.key.${r}`);return n?new KeyDescription(r,n.content):void 0}async function writeKey(e,t,s){const i=await s.session.get(BACKUPVERSION_KEY);return s.session.set(BACKUPVERSION_KEY,t),s.session.set(SSSS_KEY,{id:e.id,binaryKey:e.binaryKey}),i}async function readKey(e){const t=await e.session.get(SSSS_KEY);if(!t)return;const s=await e.accountData.get(`m.secret_storage.key.${t.id}`);return s?new Key(new KeyDescription(t.id,s.content),t.binaryKey):void 0}async function removeKey(e){e.session.remove(SSSS_KEY)}async function keyFromCredential(e,t,s,i,r){const n=await readDefaultKeyDescription(s);if(!n)throw new Error("Could not find a default secret storage key in account data");return await keyFromCredentialAndDescription(e,t,n,i,r)}async function keyFromCredentialAndDescription(e,t,s,i,r){let n;if(1===e)n=await keyFromPassphrase(s,t,i);else{if(0!==e)throw new Error(`Invalid type: ${e}`);n=keyFromRecoveryKey(s,t,r,i)}return n}async function keyFromDehydratedDeviceKey(e,t,s){const i=await readDefaultKeyDescription(t);if(await(null==i?void 0:i.isCompatible(e,s)))return e.withDescription(i)}var Status=(e=>(e[e.Enabled=0]="Enabled",e[e.SetupWithPassphrase=1]="SetupWithPassphrase",e[e.SetupWithRecoveryKey=2]="SetupWithRecoveryKey",e[e.Pending=3]="Pending",e[e.NewVersionAvailable=4]="NewVersionAvailable",e))(Status||{}),BackupWriteStatus=(e=>(e[e.Writing=0]="Writing",e[e.Stopped=1]="Stopped",e[e.Done=2]="Done",e[e.Pending=3]="Pending",e))(BackupWriteStatus||{});class KeyBackupViewModel extends ViewModel{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=KeyType.RecoveryKey;const t=e=>{e&&!this._keyBackupSubscription?this._keyBackupSubscription=this.track(this._session.keyBackup.get().disposableOn("change",(()=>{this._onKeyBackupChange()}))):!e&&this._keyBackupSubscription&&(this._keyBackupSubscription=this.disposeTracked(this._keyBackupSubscription)),this._onKeyBackupChange()};this.track(this._session.keyBackup.subscribe(t)),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:void 0===e.version?3:e.needsNewKey?4:0;switch(this._setupKeyType){case KeyType.RecoveryKey:return 2;case KeyType.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 null!=(t=null==(e=this._keyBackup)?void 0:e.version)?t:""}get isMasterKeyTrusted(){var e,t;return null!=(t=null==(e=this._crossSigning)?void 0:e.isMasterKeyTrusted)&&t}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;if(!e||void 0===e.version)return 3;if(e.hasStopped)return 1;return e.operationInProgress?0:e.hasBackedUpAllKeys?2:3}get backupError(){var e,t;return null==(t=null==(e=this._keyBackup)?void 0:e.error)?void 0:t.message}get error(){var e;return null==(e=this._error)?void 0:e.message}showPhraseSetup(){this._setupKeyType=KeyType.Passphrase,this.emitChange("status")}showKeySetup(){this._setupKeyType=KeyType.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))}catch(e){console.error(e),this._error=e,this.emitChange("error")}finally{this._isBusy=!1,this.emitChange()}}enterSecurityPhrase(e,t){return this._enterCredentials(KeyType.Passphrase,e,t)}enterSecurityKey(e,t){return this._enterCredentials(KeyType.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 void 0!==(null==(e=this._keyBackup)?void 0:e.operationInProgress)}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;null==(t=null==(e=this._keyBackup)?void 0:e.operationInProgress)||t.abort()}startBackup(){this.logger.run("KeyBackupViewModel.startBackup",(e=>{var t;null==(t=this._keyBackup)||t.flush(e)}))}}class KeyBackupSettingsView extends TemplateView{render(e,t){return e.div([e.map((e=>e.status),((e,t,s)=>{switch(e){case Status.Enabled:return renderEnabled(t,s);case Status.NewVersionAvailable:return renderNewVersionAvailable(t,s);case Status.SetupWithPassphrase:return renderEnableFromPhrase(t,s);case Status.SetupWithRecoveryKey:return renderEnableFromKey(t,s);case Status.Pending:return t.p(s.i18n`Waiting to go online…`)}})),e.map((e=>e.backupWriteStatus),((e,t,s)=>{switch(e){case BackupWriteStatus.Writing:{const e=t.progress({min:"0",max:"100",value:e=>e.backupPercentage});return t.div(["Backup in progress ",e," ",e=>e.backupInProgressLabel])}case BackupWriteStatus.Stopped:{let e;return e=s.backupError?`Backup has stopped because of an error: ${s.backupError}`:"Backup has stopped",t.p([e," ",t.button({onClick:()=>s.startBackup()},"Backup now")])}case BackupWriteStatus.Done:return t.p("All keys are backed up.");default:return}})),e.if((e=>e.isMasterKeyTrusted),(e=>e.p("Cross-signing master key found and trusted."))),e.if((e=>e.canSignOwnDevice),(e=>e.div([e.button({onClick:disableTargetCallback$1((async e=>{await t.signOwnDevice()}))},"Sign own device"),e.button({onClick:disableTargetCallback$1((async()=>{t.navigateToVerification()}))},"Verify by emoji")])))])}}function renderEnabled(e,t){const s=[e.p([t.i18n`Key backup is enabled, using backup version ${t.backupVersion}. `,e.button({onClick:()=>t.disable()},t.i18n`Disable`)])];return t.dehydratedDeviceId&&s.push(e.p(t.i18n`A dehydrated device id was set up with id ${t.dehydratedDeviceId} which you can use during your next login with your secret storage key.`)),e.div(s)}function renderNewVersionAvailable(e,t){const s=[e.p([t.i18n`A new backup version has been created from another device. Disable key backup and enable it again with the new key.`,e.button({onClick:()=>t.disable()},t.i18n`Disable`)])];return e.div(s)}function renderEnableFromKey(e,t){const s=e.button({className:"link",onClick:()=>t.showPhraseSetup()},t.i18n`use a security phrase`);return e.div([e.p(t.i18n`Enter your secret storage security key below to ${t.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.`),renderError(e),renderEnableFieldRow(e,t,t.i18n`Security key`,((e,s)=>t.enterSecurityKey(e,s))),e.p([t.i18n`Alternatively, you can `,s,t.i18n` if you have one.`])])}function renderEnableFromPhrase(e,t){const s=e.button({className:"link",onClick:()=>t.showKeySetup()},t.i18n`use your security key`);return e.div([e.p(t.i18n`Enter your secret storage security phrase below to ${t.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.`),renderError(e),renderEnableFieldRow(e,t,t.i18n`Security phrase`,((e,s)=>t.enterSecurityPhrase(e,s))),e.p([t.i18n`You can also `,s,t.i18n`.`])])}function renderEnableFieldRow(e,t,s,i){let r;const n=e.input({type:"password",disabled:e=>e.isBusy,placeholder:s}),o=[e.p([n,e.button({disabled:e=>e.isBusy,onClick:()=>i(n.value,(null==r?void 0:r.checked)||!1)},t.decryptAction)])];if(t.offerDehydratedDeviceSetup){r=e.input({type:"checkbox",id:"enable-dehydrated-device"});const s=e.a({href:"https://github.com/uhoreg/matrix-doc/blob/dehydration/proposals/2697-device-dehydration.md",target:"_blank",rel:"noopener"},"more info");o.push(e.p([r,e.label({for:r.id},[t.i18n`Back up my device as well (`,s,")"])]))}return e.div({className:"row"},[e.div({className:"label"},s),e.div({className:"content"},o)])}function renderError(e){return e.if((e=>void 0!==e.error),((e,t)=>e.div([e.p({className:"error"},(e=>e.i18n`Could not enable key backup: ${e.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 FeaturesView extends TemplateView{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((t=>e.li(e.view(new FeatureView(t))))))])}}class FeatureView extends TemplateView{render(e,t){let s=`feature_${t.id}`;return e.div({className:"FeatureView"},[e.input({type:"checkbox",id:s,checked:e=>e.enabled,onChange:e=>t.enableFeature(e.target.checked)}),e.div({class:"FeatureView_container"},[e.h4(e.label({for:s},t.name)),e.p(t.description)])])}}class SettingsView extends TemplateView{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=(e,t,s,i="")=>e.div({className:`row ${i}`},[e.div({className:"label"},t),e.div({className:"content"},s)]),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:e=>e.isLoggingOut},t.i18n`Log out`))),r.push(e.if((e=>e.accountManagementUrl),(e=>{const s=new URL(t.accountManagementUrl);return e.div([e.h3("Account"),e.p([t.i18n`Your account details are managed separately at `,e.code(s.hostname),"."]),e.button({onClick:()=>window.open(t.accountManagementUrl,"_blank")},t.i18n`Manage account`)])}))),r.push(e.h3("Key backup & security"),e.view(new KeyBackupSettingsView(t.keyBackupViewModel))),r.push(e.h3("Notifications"),e.map((e=>e.pushNotifications.supported),((e,s)=>{if(null===e)return s.p(t.i18n`Loading…`);if(e){const e=e=>e.pushNotifications.enabled?e.i18n`Disable`:e.i18n`Enable`;return i(s,(e=>e.pushNotifications.enabled?e.i18n`Push notifications are enabled`:e.i18n`Push notifications are disabled`),s.button({onClick:()=>t.togglePushNotifications(),disabled:e=>e.pushNotifications.updating},e))}return s.p(t.i18n`Push notifications are not supported on this browser`)})),e.if((e=>e.pushNotifications.supported&&e.pushNotifications.enabled),(e=>e.div([e.p(["If you think push notifications are not being delivered, ",e.button({className:"link",onClick:()=>t.checkPushEnabledOnServer()},"check")," if they got disabled on the server"]),e.map((e=>e.pushNotifications.enabledOnServer),((e,t)=>!0===e?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."):!1===e?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."):void 0)),e.map((e=>e.pushNotifications.serverError),((e,t)=>{if(e)return t.p("Couldn't not check on server: "+e.message)}))])))),r.push(e.h3("Preferences"),i(e,t.i18n`Scale down images when sending`,this._imageCompressionRange(e,t)),e.if((e=>e.activeTheme),((e,t)=>i(e,t.i18n`Use the following theme`,this._themeOptions(e,t)))));const n=[];return t.canSendLogsToServer&&n.push(e.button({onClick:disableTargetCallback$1((()=>t.sendLogsToServer()))},`Submit logs to ${t.logsServer}`)),n.push(e.button({onClick:()=>t.exportLogs()},"Download logs")),r.push(e.h3("Experimental features"),e.view(new FeaturesView(t.featuresViewModel))),r.push(e.h3("Application"),i(e,t.i18n`Version`,s),i(e,t.i18n`Storage usage`,(e=>`${e.storageUsage} / ${e.storageQuota}`)),i(e,t.i18n`Debug logs`,n),e.p({className:{hidden:e=>!e.logsFeedbackMessage}},(e=>e.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 s=32*Math.ceil(t.minSentImageSizeLimit/32),i=32*(Math.floor(t.maxSentImageSizeLimit/32)+1),r=e=>t.setSentImageSizeLimit(parseInt(e.target.value,10));return[e.input({type:"range",step:32,min:s,max:i,value:e=>e.sentImageSizeLimit||i,onInput:r,onChange:r})," ",e.output((e=>e.sentImageSizeLimit?e.i18n`resize to ${e.sentImageSizeLimit}px`:e.i18n`no resizing`))]}_themeOptions(e,t){const{themeName:s,themeVariant:i}=t.activeTheme,r=[];for(const i of Object.keys(t.themeMapping))r.push(e.option({value:i,selected:i===s},i));const n=e.select({onChange:e=>{const s=e.target.value;if("id"in t.themeMapping[s])t.changeThemeOption(s);else{const e=c.checked?"dark":h.checked?"light":"default";o(e)}}},r),o=e=>{const s=n.options[n.selectedIndex].value;t.changeThemeOption(s,e)},a="dark"===i,l="light"===i,c=e.input({type:"radio",name:"radio-chooser",value:"dark",id:"dark",checked:a}),d=e.input({type:"radio",name:"radio-chooser",value:"default",id:"default",checked:!(a||l)}),h=e.input({type:"radio",name:"radio-chooser",value:"light",id:"light",checked:l}),u=e.form({className:{hidden:()=>{const e=n.options[n.selectedIndex].value;return"id"in t.themeMapping[e]}},onChange:e=>o(e.target.value)},[d,e.label({for:"default"},"Match system theme"),c,e.label({for:"dark"},"dark"),h,e.label({for:"light"},"light")]);return e.div({className:"theme-chooser"},[n,u])}}class CreateRoomView extends TemplateView{render(e,t){return e.main({className:"middle"},e.div({className:"CreateRoomView centered-column"},[e.h2("Create room"),e.form({className:"CreateRoomView_detailsForm form",onChange:e=>this.onFormChange(e),onSubmit:e=>this.onSubmit(e)},[e.div({className:"vertical-layout"},[e.button({type:"button",className:"CreateRoomView_selectAvatar",onClick:()=>t.selectAvatar()},e.mapView((e=>e.hasAvatar),(e=>e?new AvatarView(t,64):new StaticView(void 0,(e=>e.div({className:"CreateRoomView_selectAvatarPlaceholder"})))))),e.div({className:"stretch form-row text"},[e.label({for:"name"},t.i18n`Room name`),e.input({onInput:e=>t.setName(e.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:e=>t.setTopic(e.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:e=>e.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:e=>!e.isPublic}},[e.label({for:"roomAlias"},t.i18n`Room alias`),e.input({onInput:e=>t.setRoomAlias(e.target.value),type:"text",name:"roomAlias",id:"roomAlias",placeholder:t.i18n`Room alias (<alias>, or #<alias> or #<alias>:hs.tld`})]),e.div({className:"form-group"},[e.div(e.button({className:"link",type:"button",onClick:()=>t.toggleAdvancedShown()},(e=>e.isAdvancedShown?e.i18n`Hide advanced settings`:e.i18n`Show advanced settings`))),e.div({className:{"form-row check":!0,hidden:e=>!e.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:e=>!e.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("true"===e.currentTarget.isPublic.value);break;case"isFederationDisabled":this.value.setFederationDisabled(e.target.checked)}}onSubmit(e){e.preventDefault(),this.value.create()}}class RoomDetailsView extends TemplateView{render(e,t){return e.div({className:"RoomDetailsView"},[e.div({className:"RoomDetailsView_avatar"},[e.view(new AvatarView(t,52)),e.mapView((e=>e.isEncrypted),(e=>new EncryptionIconView(e)))]),e.div({className:"RoomDetailsView_name"},[e.h2((e=>e.name))]),this._createRoomAliasDisplay(t),e.div({className:"RoomDetailsView_rows"},[this._createRightPanelButtonRow(e,t.i18n`People`,{MemberCount:!0},(e=>e.memberCount),(()=>t.openPanel("members"))),this._createRightPanelRow(e,t.i18n`Encryption`,{EncryptionStatus:!0},(()=>t.isEncrypted?t.i18n`On`:t.i18n`Off`))])])}_createRoomAliasDisplay(e){return e.canonicalAlias?tag.div({className:"RoomDetailsView_id"},[e.canonicalAlias]):""}_createRightPanelRow(e,t,s,i){const r=classNames(__spreadValues({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 n=classNames(__spreadValues({RoomDetailsView_label:!0},s));return e.button({className:"RoomDetailsView_row",onClick:r},[e.div({className:n},[t]),e.div({className:"RoomDetailsView_value"},i)])}}class EncryptionIconView extends TemplateView{render(e,t){return e.div({className:"EncryptionIconView"},[e.div({className:t?"EncryptionIconView_encrypted":"EncryptionIconView_unencrypted"})])}}class Range{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<this.end}toLocalIndex(e){return e-this.start}intersects(e){return e.start<this.end&&this.start<e.end}forEachInIterator(e,t){let s=0;for(s=0;s<this.start;s+=1)e.next();for(s=0;s<this.length;s+=1){const i=e.next();if(i.done)break;t(i.value,this.start+s)}}[Symbol.iterator](){return new RangeIterator(this)}reverseIterable(){return new ReverseRangeIterator(this)}clampIndex(e,t=this.end-1){return Math.min(Math.max(this.start,e),t)}getIndexZone(e){return e<this.start?RangeZone.Before:e<this.end?RangeZone.Inside:RangeZone.After}}var RangeZone=(e=>(e[e.Before=1]="Before",e[e.Inside=2]="Inside",e[e.After=3]="After",e))(RangeZone||{});class RangeIterator{constructor(e){this.range=e,this.idx=e.start-1}next(){return this.idx<this.range.end-1?(this.idx+=1,{value:this.idx,done:!1}):{value:void 0,done:!0}}}class ReverseRangeIterator{constructor(e){this.range=e,this.idx=e.end}[Symbol.iterator](){return this}next(){return this.idx>this.range.start?(this.idx-=1,{value:this.idx,done:!1}):{value:void 0,done:!0}}}function skipOnIterator(e,t){let s=0;for(;s<t;)if(s+=1,e.next().done)return!1;return!0}function getIteratorValueAtIdx(e,t){if(skipOnIterator(e,t)){const t=e.next();if(!t.done)return t.value}}var ResultType=(e=>(e[e.Move=0]="Move",e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.RemoveAndAdd=3]="RemoveAndAdd",e[e.UpdateRange=4]="UpdateRange",e))(ResultType||{});class ListRange extends Range{constructor(e,t,s,i=t-e){super(e,t),this._totalLength=s,this._viewportItemCount=i}expand(e){if(0===this.length)return this;const t=Math.max(0,this.start-e),s=Math.min(this.totalLength,this.end+e);return new ListRange(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),n=e-r,o=0!==s?Math.ceil(s/t):0,a=Math.min(o,n);return new ListRange(r,r+a,e,o)}queryAdd(e,t,s){const i=this.viewportItemCount>this.length?this.end:this.end-1;if(e<=i){const r=this.clampIndex(e,i),n=r===e?t:getIteratorValueAtIdx(s[Symbol.iterator](),r);return this.createAddResult(r,n)}return{type:4,newRange:this.deriveRange(1,0)}}queryRemove(e,t){if(e<this.end){const s=this.clampIndex(e);return this.createRemoveResult(s,t)}return{type:4,newRange:this.deriveRange(-1,0)}}queryMove(e,t,s,i){const r=this.getIndexZone(e);if(r!==this.getIndexZone(t)){const r=this.clampIndex(t);return{type:3,removeIdx:this.clampIndex(e),addIdx:r,value:r===t?s:getIteratorValueAtIdx(i[Symbol.iterator](),r)}}if(r!==RangeZone.Before&&r!==RangeZone.After)return r===RangeZone.Inside?{type:0,fromIdx:e,toIdx:t}:void 0}createAddResult(e,t){if(this.viewportItemCount>this.length)return{type:1,addIdx:e,value:t,newRange:this.deriveRange(1,1)};return{type:3,removeIdx:this.clampIndex(Number.MAX_SAFE_INTEGER),addIdx:e,value:t,newRange:this.deriveRange(1,0)}}createRemoveResult(e,t){if(this.end<this.totalLength){const s=this.clampIndex(Number.MAX_SAFE_INTEGER);return{type:3,removeIdx:e,value:getIteratorValueAtIdx(t[Symbol.iterator](),s),addIdx:s,newRange:this.deriveRange(-1,0)}}if(0!==this.start){const s=this.deriveRange(-1,0,1),i=s.start;return{type:3,removeIdx:e,value:getIteratorValueAtIdx(t[Symbol.iterator](),i),addIdx:i,newRange:s}}return{type:2,removeIdx:e,newRange:this.deriveRange(-1,0)}}deriveRange(e,t,s=0){const i=this.start-s,r=this.totalLength+e,n=Math.min(Math.max(i,this.end-s+t),r);return new ListRange(i,n,r,this.viewportItemCount)}}class LazyListView extends ListView{constructor(e,t){var s=e,{itemHeight:i,overflowItems:r=20}=s;super(__objRest(s,["itemHeight","overflowItems"]),t),this.itemHeight=i,this.overflowItems=r}handleEvent(e){"scroll"===e.type?this.handleScroll():super.handleEvent(e)}handleScroll(){const e=this._getVisibleRange();if(0!==e.length&&!this.renderRange.contains(e)){const t=this.renderRange;this.renderRange=e.expand(this.overflowItems),this.renderUpdate(t,this.renderRange)}}async loadList(){if(await new Promise((e=>requestAnimationFrame(e))),await new Promise((e=>requestAnimationFrame(e))),!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(0===e)throw new Error("LazyListView height is 0");return ListRange.fromViewport(this._list.length,this.itemHeight,e,t)}reRenderFullRange(e){removeChildren(this._listElement);const t=document.createDocumentFragment(),s=this._list[Symbol.iterator]();this._childInstances.length=0,e.forEachInIterator(s,(e=>{const s=this._childCreator(e);this._childInstances.push(s),t.appendChild(mountView(s,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 t=s-e.start;this.removeChild(t)}t.forEachInIterator(this._list[Symbol.iterator](),((s,i)=>{if(!e.containsIndex(i)){const e=i-t.start;this.addChild(e,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=tag.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===ResultType.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!==ResultType.Remove&&e.type!==ResultType.RemoveAndAdd||this.removeChild(this.renderRange.toLocalIndex(e.removeIdx)),e.newRange&&(this.renderRange=e.newRange,this.adjustPadding(this.renderRange)),e.type!==ResultType.Add&&e.type!==ResultType.RemoveAndAdd||this.addChild(this.renderRange.toLocalIndex(e.addIdx),e.value)}}class MemberTileView extends TemplateView{render(e,t){return e.li({className:"MemberTileView"},e.a({href:t.detailsUrl},[e.view(new AvatarView(t,32)),e.div({className:"MemberTileView_name"},(e=>e.name))]))}}class MemberListView extends LazyListView{constructor(e){super({list:e.memberTileViewModels,className:"MemberListView",itemHeight:40},(e=>new MemberTileView(e)))}}class MemberDetailsView extends TemplateView{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:e=>`MemberDetailsView_shield_${e.trustShieldColor}`}),e.p({className:"MemberDetailsView_shield_description"},(e=>e.trustDescription))])),e.div({className:"MemberDetailsView"},[e.view(new AvatarView(t,128)),e.div({className:"MemberDetailsView_name"},e.h2((e=>e.name))),e.div({className:"MemberDetailsView_id"},t.userId),this._createSection(e,t.i18n`Role`,(e=>e.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){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 RightPanelView extends TemplateView{render(e){return e.div({className:"RightPanelView"},[e.ifView((e=>e.activeViewModel),(e=>new ButtonsView(e))),e.mapView((e=>e.activeViewModel),(e=>this._viewFromType(e)))])}_viewFromType(e){switch(null==e?void 0:e.type){case"room-details":return new RoomDetailsView(e);case"member-list":return new MemberListView(e);case"member-details":return new MemberDetailsView(e);default:return new LoadingView}}}class ButtonsView extends TemplateView{render(e,t){return e.div({className:"RightPanelView_buttons"},[e.button({className:{back:!0,"button-utility":!0,hide:!t.activeViewModel.shouldShowBackButton},onClick:()=>t.showPreviousPanel()}),e.button({className:"close button-utility",onClick:()=>t.closePanel()})])}}class ReactionsView extends ListView{constructor(e){super({className:"Timeline_messageReactions",tagName:"div",list:e.reactions,onItemClick:e=>e.onClick()},(e=>new ReactionView(e)))}}class ReactionView extends TemplateView{render(e,t){return e.button({className:{active:e=>e.isActive,pending:e=>e.isPending}},[t.key," ",e=>`${e.count}`])}onClick(){this.value.toggle()}}class BaseMessageView extends TemplateView{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 null==(t=null==(e=this._renderFlags)?void 0:e.interactive)||t}get _isReplyPreview(){var e;return null==(e=this._renderFlags)?void 0:e.reply}render(e,t){const s=[this.renderMessageBody(e,t)];this._interactive&&s.push(e.button({className:"Timeline_messageOptions"},"⋯"));const i=e.el(this._tagName,{className:{Timeline_message:!0,own:t.isOwn,unsent:t.isUnsent,unverified:e=>e.isUnverified,disabled:!this._interactive,continuation:e=>e.isContinuation},"data-event-id":t.eventId},s);e.mapSideEffect((e=>e.isContinuation),((e,s)=>{if(e&&!1===s)i.removeChild(i.querySelector(".Timeline_messageAvatar")),i.removeChild(i.querySelector(".Timeline_messageSender"));else if(!e&&!this._isReplyPreview){const e=tag.a({href:t.memberPanelLink,className:"Timeline_messageAvatar"},[renderStaticAvatar(t,30)]),s=tag.div({className:`Timeline_messageSender usercolor${t.avatarColorNumber}`,title:t.sender},t.displayName);i.insertBefore(e,i.firstChild),i.insertBefore(s,i.firstChild)}}));let r=null;return e.mapSideEffect((e=>e.reactions),(e=>{e&&this._interactive&&!r?(r=new ReactionsView(e),this.addSubView(r),i.appendChild(mountView(r))):!e&&r&&(i.removeChild(r.root()),r.unmount(),this.removeSubView(r),r=null)})),i}onClick(e){"Timeline_messageOptions"===e.target.className&&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 Popup(new Menu(t),s),this._menuPopup.trackInTemplateView(this),this._menuPopup.showRelativeTo(e,2)}}createMenuOptions(e){const t=[];return e.canReact&&"redacted"!==e.shape&&!e.isPending&&(t.push(new QuickReactionsMenuOption(e)),t.push(Menu.option(e.i18n`Reply`,(()=>e.startReply())))),e.canAbortSending?t.push(Menu.option(e.i18n`Cancel`,(()=>e.abortSending()))):e.canRedact&&t.push(Menu.option(e.i18n`Delete`,(()=>e.redact())).setDestructive()),t.push(Menu.option(e.i18n`Copy matrix.to permalink`,(()=>e.copyPermalink()))),t}renderMessageBody(){}}class QuickReactionsMenuOption{constructor(e){this._vm=e}toDOM(e){const t=["👍","👎","😄","🎉","😕","❤️","🚀","👀"].map((t=>e.button({onClick:()=>this._vm.react(t)},t))),s=e.button({onClick:()=>{const e=prompt("Enter your reaction (emoji)");e&&this._vm.react(e)}},"…");return e.li({className:"quick-reactions"},[...t,s])}}class ReplyPreviewView extends TemplateView{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",href:t.permaLink},"In reply to"),e.a({className:"pill",href:t.senderProfileLink},[renderStaticAvatar(t,12,void 0),t.displayName]),e.br(),e.view(i)]))}}class ReplyPreviewError extends TemplateView{render(e){return e.blockquote({className:"ReplyPreviewView"},[e.div({className:"Timeline_messageBody statusMessage"},"This reply could not be found.")])}}class TextMessageView extends BaseMessageView{renderMessageBody(e,t){const s=e.time({className:{hidden:!t.time}},t.time),i=e.div({className:{Timeline_messageBody:!0,statusMessage:e=>"message-status"===e.shape}},e.mapView((e=>e.replyTile),(e=>this._isReplyPreview?null:t.isReply&&!e?new ReplyPreviewError:e?new ReplyPreviewView(e,this._viewClassForTile):null)));return e.mapSideEffect((e=>e.body),(e=>{for(;(null==(t=i.lastChild)?void 0:t.nodeType)!==Node.COMMENT_NODE&&"ReplyPreviewView"!==t.className;)i.removeChild(i.lastChild);var t;for(const t of e.parts)i.appendChild(renderPart(t));i.appendChild(s)})),i}}function renderList(e){const t=e.items.map((e=>tag.li(renderParts(e)))),s=e.startOffset;return s?tag.ol({start:s},t):tag.ul(t)}function renderImage(e){const t={src:e.src};return e.width&&(t.width=e.width),e.height&&(t.height=e.height),e.alt&&(t.alt=e.alt),e.title&&(t.title=e.title),tag.img(t)}function renderPill(e){const t=`avatar size-12 usercolor${e.avatarColorNumber}`,s=tag.div({class:t},text(e.avatarInitials)),i=renderParts(e.children);return i.unshift(s),tag.a({class:"pill",href:e.href,rel:"noopener",target:"_blank"},i)}function renderTable(e){const t=[];if(e.head){const s=e.head.map((e=>tag.th(renderParts(e))));t.push(tag.thead(tag.tr(s)))}const s=[];for(const t of e.body){const e=t.map((e=>tag.td(renderParts(e))));s.push(tag.tr(e))}return t.push(tag.tbody(s)),tag.table(t)}const formatFunction={header:e=>tag["h"+Math.min(6,e.level)](renderParts(e.inlines)),codeblock:e=>tag.pre(tag.code(text(e.text))),table:e=>renderTable(e),code:e=>tag.code(text(e.text)),text:e=>text(e.text),link:e=>tag.a({href:e.url,className:"link",target:"_blank",rel:"noopener"},renderParts(e.inlines)),pill:renderPill,format:e=>tag[e.format](renderParts(e.children)),rule:()=>tag.hr(),list:renderList,image:renderImage,newline:()=>tag.br()};function renderPart(e){const t=formatFunction[e.type];return t?t(e):text(`[unknown part type ${e.type}]`)}function renderParts(e){return Array.from(e,renderPart)}class BaseMediaView extends BaseMessageView{renderMessageBody(e,t){let s=`padding-top: ${t.height/t.width*100}%;`;t.platform.isIE11&&(s=`height: ${t.height}px`);const i=[e.div({className:"spacer",style:s}),this.renderMedia(e,t),e.time(t.time)],r=e.div({className:{status:!0,hidden:e=>!e.status}},(e=>e.status));if(i.push(r),t.isPending){const t=e.progress({min:0,max:100,value:e=>e.uploadPercentage,className:{hidden:e=>!e.isUploading}});i.push(t)}return e.div({className:"Timeline_messageBody"},[e.div({className:"media",style:`max-width: ${t.width}px`,"data-testid":"media"},i),e.if((e=>e.error),(e=>e.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`}t.push(Menu.option(s,(()=>e.downloadMedia())))}return t}}class ImageView extends BaseMediaView{renderMedia(e,t){const s=e.img({src:e=>e.thumbnailUrl,alt:e=>e.label,title:e=>e.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 domEventAsPromise(e,t){return new Promise(((s,i)=>{let r;const n=e=>{r(),i(e.target.error)},o=()=>{r(),s()};r=()=>{e.removeEventListener(t,o),e.removeEventListener("error",n)},e.addEventListener(t,o),e.addEventListener("error",n)}))}async function copyPlaintext(e){var t;try{if(null==(t=null==navigator?void 0:navigator.clipboard)?void 0:t.writeText)return await navigator.clipboard.writeText(e),!0;{const t=document.createElement("textarea");t.value=e,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(e){console.error("copyPlaintext: Ran into an error",e)}return!1}class VideoView extends BaseMediaView{renderMedia(e){const t=e.video({src:e=>e.videoUrl||`data:${e.mimeType},`,title:e=>e.label,controls:!0,preload:"none",poster:e=>e.thumbnailUrl,onPlay:this._onPlay.bind(this),style:e=>`max-width: ${e.width}px; max-height: ${e.height}px;${e.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=domEventAsPromise(s,"loadeddata");s.load(),await i,s.play()}catch(e){}}_onError(e){const t=this.value,s=e.target,i=s.error;if(i instanceof window.MediaError&&4===i.code){if(s.src.startsWith("data:"))return;t.setViewError(new Error(`this browser does not support videos of type ${t.mimeType}.`))}else t.setViewError(i)}}class FileView extends BaseMessageView{renderMessageBody(e,t){const s=[];return t.isPending?s.push((e=>e.label)):s.push(e.button({className:"link",onClick:()=>t.download()},(e=>e.label)),e.time(t.time)),e.p({className:"Timeline_messageBody statusMessage"},s)}}class LocationView extends BaseMessageView{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 MissingAttachmentView extends BaseMessageView{renderMessageBody(e,t){return e.p({className:"Timeline_messageBody statusMessage"},t.label)}}class AnnouncementView extends TemplateView{constructor(e){super(e)}render(e,t){return e.li({className:"AnnouncementView","data-event-id":t.eventId},e.div((e=>e.announcement)))}onClick(){}}class RedactedView extends BaseMessageView{renderMessageBody(e){return e.p({className:"Timeline_messageBody statusMessage"},(e=>e.description))}createMenuOptions(e){const t=super.createMenuOptions(e);return e.isRedacting&&t.push(Menu.option(e.i18n`Cancel`,(()=>e.abortPendingRedaction()))),t}}var TileShape=(e=>(e.Message="message",e.MessageStatus="message-status",e.Announcement="announcement",e.File="file",e.Gap="gap",e.Image="image",e.Location="location",e.MissingAttachment="missing-attachment",e.Redacted="redacted",e.Video="video",e.DateHeader="date-header",e.Call="call",e))(TileShape||{});class GapView extends TemplateView{constructor(e){super(e)}render(e,t){return e.li({className:{GapView:!0,isLoading:e=>e.isLoading,isAtTop:e=>e.isAtTop}},[e.div({class:"GapView_container"},[e.if((e=>e.showSpinner),(e=>spinner(e))),e.span((e=>e.status))]),e.if((e=>!!e.errorViewModel),(e=>e.view(new ErrorView$1(t.errorViewModel,{inline:!0}))))])}onClick(){}}class CallTileView extends TemplateView{render(e,t){return e.li({className:"CallTileView AnnouncementView"},e.div([e.if((e=>e.errorViewModel),(e=>e.div({className:"CallTileView_error"},e.view(new ErrorView$1(t.errorViewModel,{inline:!0}))))),e.div([e.div({className:"CallTileView_title"},(e=>e.title)),e.div({className:"CallTileView_subtitle"},[t.typeLabel," • ",e.span({className:"CallTileView_memberCount"},(e=>e.memberCount))]),e.view(new ListView({className:"CallTileView_members",tagName:"div",list:t.memberViewModels},(e=>new AvatarView(e,24)))),e.div((e=>e.duration)),e.div([e.button({className:"CallTileView_join button-action primary",hidden:e=>!e.canJoin},"Join"),e.button({className:"CallTileView_leave button-action primary destructive",hidden:e=>!e.canLeave},"Leave")])])]))}onClick(e){e.target.classList.contains("CallTileView_join")?this.value.join():e.target.classList.contains("CallTileView_leave")&&this.value.leave()}}class DateHeaderView extends TemplateView{constructor(e){super(e)}render(e,t){return e.h2({className:"DateHeader"},e.time({dateTime:t.machineReadableDate},t.relativeDate))}onClick(){}}function viewClassForTile(e){switch(e.shape){case TileShape.Gap:return GapView;case TileShape.Announcement:return AnnouncementView;case TileShape.Message:case TileShape.MessageStatus:return TextMessageView;case TileShape.Image:return ImageView;case TileShape.Video:return VideoView;case TileShape.File:return FileView;case TileShape.Location:return LocationView;case TileShape.MissingAttachment:return MissingAttachmentView;case TileShape.Redacted:return RedactedView;case TileShape.Call:return CallTileView;case TileShape.DateHeader:return DateHeaderView;default:throw new Error(`Tiles of shape "${e.shape}" are not supported, check the tileClassForEntry function in the view model`)}}class JoinRoomView extends TemplateView{render(e,t){const s=e.input({type:"text",name:"id",id:"id",placeholder:t.i18n`Enter a room id or alias`,disabled:e=>e.joinInProgress});return e.main({className:"middle"},e.div({className:"JoinRoomView centered-column"},[e.h2("Join room"),e.form({className:"JoinRoomView_detailsForm form",onSubmit:e=>this.onSubmit(e,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:e=>e.joinInProgress},t.i18n`Join`)]),e.map((e=>e.status),((e,t)=>t.div({className:"JoinRoomView_status"},[spinner(t,{hidden:e=>!e.joinInProgress}),t.span(e)])))])]))}onSubmit(e,t){e.preventDefault(),this.value.join(t)}}class WaitingForOtherUserView extends TemplateView{render(e,t){return e.div({className:"WaitingForOtherUserView"},[e.div({className:"WaitingForOtherUserView__heading"},[spinner(e),e.h2({className:"WaitingForOtherUserView__title"},t.i18n`Waiting for any of your device to accept the verification request`)]),e.p({className:"WaitingForOtherUserView__description"},t.i18n`Accept the request from the device you wish to verify!`),e.div({className:"WaitingForOtherUserView__actions"},e.button({className:{"button-action":!0,primary:!0,destructive:!0},onclick:()=>t.cancel()},"Cancel"))])}}class VerificationCancelledView extends TemplateView{render(e,t){const s=t.isCancelledByUs?"You":"The other device";return e.div({className:"VerificationCancelledView"},[e.h2({className:"VerificationCancelledView__title"},t.i18n`${s} cancelled the verification!`),e.p({className:"VerificationCancelledView__description"},t.i18n`${this.getDescriptionFromCancellationCode(t.cancelCode,t.isCancelledByUs)}`),e.div({className:"VerificationCancelledView__actions"},[e.button({className:{"button-action":!0,primary:!0},onclick:()=>t.gotoSettings()},"Got it")])])}getDescriptionFromCancellationCode(e,t){var s;const i={[CancelReason.InvalidMessage]:"You other device sent an invalid message.",[CancelReason.KeyMismatch]:"The key could not be verified.",[CancelReason.TimedOut]:"The verification process timed out.",[CancelReason.UnexpectedMessage]:"Your other device sent an unexpected message.",[CancelReason.UnknownMethod]:"Your other device is using an unknown method for verification.",[CancelReason.UnknownTransaction]:"Your other device sent a message with an unknown transaction id.",[CancelReason.UserMismatch]:"The expected user did not match the user verified.",[CancelReason.MismatchedCommitment]:"The hash commitment does not match.",[CancelReason.MismatchedSAS]:"The emoji/decimal did not match."},r={[CancelReason.UserCancelled]:"Your other device cancelled the verification!",[CancelReason.InvalidMessage]:"Invalid message sent to the other device.",[CancelReason.KeyMismatch]:"The other device could not verify our keys",[CancelReason.TimedOut]:"The verification process timed out.",[CancelReason.UnexpectedMessage]:"Unexpected message sent to the other device.",[CancelReason.UnknownMethod]:"Your other device does not understand the method you chose",[CancelReason.UnknownTransaction]:"Your other device rejected our message.",[CancelReason.UserMismatch]:"The expected user did not match the user verified.",[CancelReason.MismatchedCommitment]:"Your other device was not able to verify the hash commitment",[CancelReason.MismatchedSAS]:"The emoji/decimal did not match."};return null!=(s=(t?i:r)[e])?s:""}}class SelectMethodView extends TemplateView{render(e){return e.div({className:"SelectMethodView"},[e.map((e=>e.hasProceeded),((e,t,s)=>e?spinner(t):t.div([t.div({className:"SelectMethodView__heading"},[t.h2({className:"SelectMethodView__title"},s.i18n`Verify device '${s.deviceName}' by comparing emojis?`)]),t.p({className:"SelectMethodView__description"},s.i18n`You are about to verify your other device by comparing emojis.`),t.div({className:"SelectMethodView__actions"},[t.button({className:{"button-action":!0,primary:!0,destructive:!0},onclick:()=>s.cancel()},"Cancel"),t.button({className:{"button-action":!0,primary:!0},onclick:()=>s.proceed()},"Proceed")])])))])}}class VerifyEmojisView extends TemplateView{render(e,t){const s=t.emojis.reduce(((t,[s,i])=>{const r=e.div({className:"EmojiContainer"},[e.div({className:"EmojiContainer__emoji"},s),e.div({className:"EmojiContainer__name"},i)]);return t.push(r),t}),[]),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((e=>e.isWaiting),((e,t,s)=>e?t.div({className:"VerifyEmojisView__waiting"},[spinner(t),t.span(s.i18n`Waiting for you to verify on your other device`)]):t.div({className:"VerifyEmojisView__actions"},[t.button({className:{"button-action":!0,primary:!0,destructive:!0},onclick:()=>s.setEmojiMatch(!1)},s.i18n`They don't match`),t.button({className:{"button-action":!0,primary:!0},onclick:()=>s.setEmojiMatch(!0)},s.i18n`They match`)])))])}}class VerificationCompleteView extends TemplateView{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.i18n`You successfully verified device ${t.otherDeviceId}`),e.div({className:"VerificationCompleteView__actions"},[e.button({className:{"button-action":!0,primary:!0},onclick:()=>t.gotoSettings()},"Got it")])])}}class DeviceVerificationView extends TemplateView{render(e){return e.div({className:{middle:!0,DeviceVerificationView:!0}},[e.mapView((e=>e.currentStageViewModel),(e=>{switch(null==e?void 0:e.kind){case"waiting-for-user":return new WaitingForOtherUserView(e);case"verification-cancelled":return new VerificationCancelledView(e);case"select-method":return new SelectMethodView(e);case"verify-emojis":return new VerifyEmojisView(e);case"verification-completed":return new VerificationCompleteView(e);default:return null}}))])}}class CallToastNotificationView extends TemplateView{render(e,t){return e.div({className:"CallToastNotificationView"},[e.div({className:"CallToastNotificationView__top"},[e.view(new AvatarView(t,24)),e.span({className:"CallToastNotificationView__name"},(e=>e.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"},(e=>e.memberCount))]),e.div({className:"CallToastNotificationView__action"},[e.button({className:"button-action primary",onClick:()=>t.join()},t.i18n`Join`)]),e.if((e=>!!e.errorViewModel),(e=>e.div({className:"CallView_error"},e.view(new ErrorView$1(t.errorViewModel)))))])}}class VerificationToastNotificationView extends TemplateView{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 toastViewModelToView(e){switch(e.kind){case"calls":return new CallToastNotificationView(e);case"verification":return new VerificationToastNotificationView(e);default:throw new Error(`Cannot find view class for notification kind ${e.kind}`)}}class ToastCollectionView extends TemplateView{render(e,t){return e.div({className:"ToastCollectionView"},[e.ifView((e=>!!e.toastViewModels),(e=>new ListView({list:t.toastViewModels,parentProvidesUpdates:!1},(e=>toastViewModelToView(e)))))])}}class SessionView extends TemplateView{render(e,t){return e.div({className:{SessionView:!0,"middle-shown":e=>!!e.activeMiddleViewModel,"right-shown":e=>!!e.rightPanelViewModel}},[e.view(new ToastCollectionView(t.toastCollectionViewModel)),e.view(new SessionStatusView(t.sessionStatusViewModel)),e.view(new LeftPanelView(t.leftPanelViewModel)),e.mapView((e=>e.activeMiddleViewModel),(()=>t.roomGridViewModel?new RoomGridView(t.roomGridViewModel,viewClassForTile):t.settingsViewModel?new SettingsView(t.settingsViewModel):t.createRoomViewModel?new CreateRoomView(t.createRoomViewModel):t.joinRoomViewModel?new JoinRoomView(t.joinRoomViewModel):t.verificationViewModel?new DeviceVerificationView(t.verificationViewModel):t.currentRoomViewModel?"invite"===t.currentRoomViewModel.kind?new InviteView(t.currentRoomViewModel):"room"===t.currentRoomViewModel.kind?new RoomView(t.currentRoomViewModel,viewClassForTile):"roomBeingCreated"===t.currentRoomViewModel.kind?new RoomBeingCreatedView(t.currentRoomViewModel):new UnknownRoomView(t.currentRoomViewModel):new StaticView((e=>e.div({className:"room-placeholder"},e.h2(t.i18n`Choose a room on the left side.`)))))),e.mapView((e=>e.lightboxViewModel),(e=>e?new LightboxView(e):null)),e.mapView((e=>e.rightPanelViewModel),(e=>e?new RightPanelView(e):null))])}}function hydrogenGithubLink(e){return e.a({target:"_blank",href:"https://github.com/vector-im/hydrogen-web"},"Hydrogen on Github")}class PasswordLoginView extends TemplateView{render(e,t){const s=e=>!!e.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((e=>e.error),(e=>e.div({className:"error"},(e=>e.error)))),e.form({onSubmit:e=>{e.preventDefault(),t.login(i.value,r.value)}},[e.if((e=>e.errorMessage),((e,t)=>e.p({className:"error"},t.i18n(t.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 AccountSetupView extends TemplateView{render(e,t){return e.div({className:"Settings"},[e.h3(t.i18n`Restore your encrypted history?`),e.ifView((e=>e.decryptDehydratedDeviceViewModel),(e=>new KeyBackupSettingsView(e.decryptDehydratedDeviceViewModel))),e.map((e=>e.deviceDecrypted),((e,s)=>e?s.p(t.i18n`That worked out, you're good to go!`):s.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"},(e=>e.deviceDecrypted?e.i18n`Continue`:e.i18n`Continue without restoring`))])])}}class SessionLoadStatusView extends TemplateView{render(e){const t=e.if((e=>e.hasError),((e,t)=>e.button({onClick:()=>t.exportLogs()},t.i18n`Export logs`))),s=e.if((e=>e.hasError),((e,t)=>e.button({onClick:()=>t.logout()},t.i18n`Log out`)));return e.div({className:"SessionLoadStatusView"},[e.p({className:"status"},[spinner(e,{hidden:e=>!e.loading}),e.p((e=>e.loadLabel)),t,s]),e.ifView((e=>e.accountSetupViewModel),(e=>new AccountSetupView(e.accountSetupViewModel)))])}}class CompleteSSOView extends TemplateView{render(e){return e.div({className:"CompleteSSOView"},[e.p({className:"CompleteSSOView_title"},"Finishing up your SSO Login"),e.if((e=>e.errorMessage),((e,t)=>e.p({className:"error"},t.i18n(t.errorMessage)))),e.mapView((e=>e.loadViewModel),(e=>e?new SessionLoadStatusView(e):null))])}}class LoginView extends TemplateView{render(e,t){const s=e=>e.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((e=>e.completeSSOLoginViewModel),(e=>e?new CompleteSSOView(e):null)),e.if((e=>e.showHomeserver),((e,t)=>e.div({className:"LoginView_sso form-row text"},[e.label({for:"homeserver"},t.i18n`Homeserver`),e.input({id:"homeserver",type:"text",placeholder:t.i18n`Your matrix homeserver`,value:t.homeserver,disabled:s,onInput:e=>t.setHomeserver(e.target.value),onChange:()=>t.queryHomeserver()}),e.p({className:{LoginView_forwardInfo:!0,hidden:e=>!e.resolvedHomeserver}},(e=>e.i18n`You will connect to ${e.resolvedHomeserver}.`)),e.if((e=>e.errorMessage),((e,t)=>e.p({className:"error"},t.i18n(t.errorMessage))))]))),e.if((e=>e.isFetchingLoginOptions),(e=>e.div({className:"LoginView_query-spinner"},[spinner(e),e.p("Fetching available login options...")]))),e.mapView((e=>e.passwordLoginViewModel),(e=>e?new PasswordLoginView(e):null)),e.if((e=>e.passwordLoginViewModel&&e.startSSOLoginViewModel),(e=>e.p({className:"LoginView_separator"},t.i18n`or`))),e.mapView((e=>e.startSSOLoginViewModel),(e=>e?new StartSSOLoginView(e):null)),e.mapView((e=>e.startOIDCLoginViewModel),(e=>e?new StartOIDCLoginView(e):null)),e.if((e=>e.startOIDCLoginViewModel&&e.startOIDCGuestLoginViewModel),(e=>e.p({className:"LoginView_separator"},t.i18n`or`))),e.mapView((e=>e.startOIDCGuestLoginViewModel),(e=>e?new StartOIDCGuestLoginView(e):null)),e.mapView((e=>e.loadViewModel),(e=>e?new SessionLoadStatusView(e):null)),e.p(hydrogenGithubLink(e))])}}class StartSSOLoginView extends TemplateView{render(e,t){return e.div({className:"StartSSOLoginView"},e.button({className:"StartSSOLoginView_button button-action secondary",type:"button",onClick:()=>t.startSSOLogin(),disabled:e=>e.isBusy},t.i18n`Log in with SSO`))}}class StartOIDCLoginView extends TemplateView{render(e,t){return e.div({className:"StartOIDCLoginView"},e.a({className:"StartOIDCLoginView_button button-action primary",type:"button",onClick:()=>t.startOIDCLogin(),disabled:e=>e.isBusy},t.i18n`Continue`))}}class StartOIDCGuestLoginView extends TemplateView{render(e,t){return e.div({className:"StartOIDCGuestLoginView"},e.a({className:"StartOIDCGuestLoginView_button button-action primary",type:"button",onClick:()=>t.startOIDCLogin(),disabled:e=>e.isBusy},t.i18n`Continue as Guest`))}}class LogoutView extends TemplateView{render(e,t){const s=new InlineTemplateView(t,(e=>e.div([e.p("Are you sure you want to log out?"),e.div({className:"button-row"},[e.a({className:"button-action",type:"submit",href:t.cancelUrl},["Cancel"]),e.button({className:"button-action primary destructive",type:"submit",onClick:()=>t.logout()},t.i18n`Log out`)])]))),i=new InlineTemplateView(t,(e=>e.p({className:"status",hidden:e=>!e.showStatus},[spinner(e,{hidden:e=>!e.busy}),e.span((e=>e.status))])));return e.div({className:"LogoutScreen"},[e.div({className:"content"},[e.mapView((e=>e.showConfirm),(e=>e?s:i))])])}}class ForcedLogoutView extends TemplateView{render(e){return e.div({className:"LogoutScreen"},[e.div({className:"content"},e.map((e=>e.showStatus),((e,t,s)=>e?t.p({className:"status"},[spinner(t,{hidden:e=>!e.showSpinner}),t.span((e=>e.status))]):t.div([t.p("Your access token is no longer valid! You can reauthenticate in the next screen."),t.div({className:"button-row"},[t.button({className:"button-action primary",type:"submit",onClick:()=>s.proceed()},s.i18n`Proceed`)])]))))])}}class SessionLoadView extends TemplateView{render(e,t){return e.div({className:"PreSessionScreen"},[e.div({className:"logo"}),e.div({className:"SessionLoadView"},[e.view(new SessionLoadStatusView(t))]),e.div({className:{"button-row":!0,hidden:e=>e.loading}},e.a({className:"button-action primary",href:t.backUrl},t.i18n`Go back`))])}}class SessionPickerItemView extends TemplateView{_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}`},(e=>e.avatarInitials)),e.div({className:"user-id"},(e=>e.label))])])}}class SessionPickerView extends TemplateView{render(e,t){const s=new ListView({list:t.sessions,parentProvidesUpdates:!1},(e=>new SessionPickerItemView(e)));return e.div({className:"PreSessionScreen"},[e.div({className:"logo"}),e.div({className:"SessionPickerView"},[e.h1(["Continue as …"]),e.view(s),e.div({className:"button-row"},[e.a({className:"button-action primary",href:t.cancelUrl},t.i18n`Sign In`)]),e.ifView((e=>e.loadViewModel),(()=>new SessionLoadStatusView(t.loadViewModel))),e.p(hydrogenGithubLink(e))])])}}class RootView extends TemplateView{render(e,t){return e.mapView((e=>e.activeSection),(e=>{switch(e){case"error":return new StaticView((e=>e.div({className:"StatusView"},[e.h1("Something went wrong"),e.p(t.errorText)])));case"session":return new SessionView(t.sessionViewModel);case"login":return new LoginView(t.loginViewModel);case"logout":return new LogoutView(t.logoutViewModel);case"forced-logout":return new ForcedLogoutView(t.forcedLogoutViewModel);case"picker":return new SessionPickerView(t.sessionPickerViewModel);case"redirecting":return new StaticView((e=>e.p("Redirecting...")));case"loading":return new SessionLoadView(t.sessionLoadViewModel);default:throw new Error(`Unknown section: ${t.activeSection}`)}}))}}class Timeout{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 AbortError),clearTimeout(this._handle),this._handle=null,this._reject=null)}dispose(){this.abort()}}class Interval{constructor(e,t){this._handle=setInterval(t,e)}dispose(){this._handle&&(clearInterval(this._handle),this._handle=null)}}class TimeMeasure{constructor(){this._start=window.performance.now()}measure(){return window.performance.now()-this._start}}class Clock{createMeasure(){return new TimeMeasure}createTimeout(e){return new Timeout(e)}createInterval(e,t){return new Interval(t,e)}now(){return Date.now()}}class ServiceWorkerHandler{constructor(){this._waitingForReply=new Map,this._messageIdCounter=0,this._navigation=null,this._registration=null,this._registrationPromise=null,this._currentController=null,this.haltRequests=!1}setNavigation(e){this._navigation=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")})()}_onMessage(e){const{data:t}=e,s=t.replyTo;if(s){const e=this._waitingForReply.get(s);e&&(this._waitingForReply.delete(s),e(t.payload))}if("hasSessionOpen"===t.type){const s=this._navigation.observe("session").get()===t.payload.sessionId;e.source.postMessage({replyTo:t.id,payload:s})}else if("hasRoomOpen"===t.type){const s=this._navigation.observe("session").get()===t.payload.sessionId,i=this._navigation.observe("room").get()===t.payload.roomId;e.source.postMessage({replyTo:t.id,payload:s&&i})}else if("closeSession"===t.type){const{sessionId:s}=t.payload;this._closeSessionIfNeeded(s).finally((()=>{e.source.postMessage({replyTo:t.id})}))}else"haltRequests"===t.type?(this.haltRequests=!0,e.source.postMessage({replyTo:t.id})):"openRoom"===t.type&&this._navigation.push("room",t.payload.roomId)}_closeSessionIfNeeded(e){var t;const s=null==(t=this._navigation)?void 0:t.path.get("session");return e&&(null==s?void 0:s.value)===e?new Promise((t=>{const s=this._navigation.pathObservable.subscribe((i=>{const r=i.get("session");r&&r.value===e||(s(),t())}));this._navigation.push("session")})):Promise.resolve()}async _proposeUpdate(){if(document.hidden)return;const e=await this._sendAndWaitForReply("version",null,this._registration.waiting);confirm(`Version ${e.version} (${e.buildHash}) is available. Reload to apply?`)&&(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":"installed"===e.target.state&&(this._proposeUpdate(),e.target.removeEventListener("statechange",this));break;case"controllerchange":this._currentController?document.location.reload():this._currentController=navigator.serviceWorker.controller}}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((e=>{this._waitingForReply.set(i,e)}));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.3.8"}get buildHash(){return null}async preventConcurrentSessionAccess(e){return this._sendAndWaitForReply("closeSession",{sessionId:e})}async getRegistration(){return this._registrationPromise&&await this._registrationPromise,this._registration}}class NotificationService{constructor(e,t){this._serviceWorkerHandler=e,this._pushConfig=t}async enablePush(e,t){var s;const i=await(null==(s=this._serviceWorkerHandler)?void 0:s.getRegistration());if(null==i?void 0:i.pushManager){const s=(await i.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this._pushConfig.applicationServerKey})).toJSON(),r=s.keys.p256dh,n={endpoint:s.endpoint,auth:s.keys.auth,events_only:!0,default_payload:t};return e.httpPusher(this._pushConfig.gatewayUrl,this._pushConfig.appId,r,n)}}async disablePush(){var e;const t=await(null==(e=this._serviceWorkerHandler)?void 0:e.getRegistration());if(null==t?void 0:t.pushManager){const e=await t.pushManager.getSubscription();e&&await e.unsubscribe()}}async isPushEnabled(){var e;const t=await(null==(e=this._serviceWorkerHandler)?void 0:e.getRegistration());if(null==t?void 0:t.pushManager){return!!await t.pushManager.getSubscription()}return!1}async supportsPush(){var e;if(!this._pushConfig)return!1;const t=await(null==(e=this._serviceWorkerHandler)?void 0:e.getRegistration());return t&&"pushManager"in t}async enableNotifications(){return"Notification"in window&&"granted"===await Notification.requestPermission()}async supportsNotifications(){return"Notification"in window}async areNotificationsEnabled(){return"Notification"in window&&"granted"===Notification.permission}async showNotification(e,t=void 0){var s;if("Notification"in window)return void new Notification(e,{body:t});const i=await(null==(s=this._serviceWorkerHandler)?void 0:s.getRegistration());null==i||i.showNotification(e,{body:t})}}class History extends BaseObservableValue$1{constructor(){super(),this._lastSessionHash=void 0}handleEvent(e){"hashchange"===e.type&&(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=null==(e=window.localStorage)?void 0:e.getItem("hydrogen_last_url_hash"),window.addEventListener("hashchange",this)}onUnsubscribeLast(){window.removeEventListener("hashchange",this)}_storeHash(e){var t;null==(t=window.localStorage)||t.setItem("hydrogen_last_url_hash",e)}getLastSessionUrl(){return this._lastSessionHash}}class OnlineStatus extends BaseObservableValue$1{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 subtleCryptoResult(e,t){return e instanceof Promise?e:new Promise(((s,i)=>{e.oncomplete=e=>s(e.target.result),e.onerror=()=>i(new Error("Crypto error on "+t))}))}class HMACCrypto{constructor(e){this._subtleCrypto=e}async verify(e,t,s,i){const r={name:"HMAC",hash:{name:hashName(i)}},n=await subtleCryptoResult(this._subtleCrypto.importKey("raw",e,r,!1,["verify"]),"importKey");return await subtleCryptoResult(this._subtleCrypto.verify(r,n,t,s),"verify")}async compute(e,t,s){const i={name:"HMAC",hash:{name:hashName(s)}},r=await subtleCryptoResult(this._subtleCrypto.importKey("raw",e,i,!1,["sign"]),"importKey"),n=await subtleCryptoResult(this._subtleCrypto.sign(i,r,t),"sign");return new Uint8Array(n)}}class DeriveCrypto{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 n=await subtleCryptoResult(this._subtleCrypto.importKey("raw",e,{name:"PBKDF2"},!1,["deriveBits"]),"importKey"),o=await subtleCryptoResult(this._subtleCrypto.deriveBits({name:"PBKDF2",salt:s,iterations:t,hash:hashName(i)},n,r),"deriveBits");return new Uint8Array(o)}async hkdf(e,t,s,i,r){if(!this._subtleCrypto.deriveBits)return this._cryptoExtras.hkdf(this._crypto,e,t,s,i,r);const n=await subtleCryptoResult(this._subtleCrypto.importKey("raw",e,{name:"HKDF"},!1,["deriveBits"]),"importKey"),o=await subtleCryptoResult(this._subtleCrypto.deriveBits({name:"HKDF",salt:t,info:s,hash:hashName(i)},n,r),"deriveBits");return new Uint8Array(o)}}class AESCrypto{constructor(e,t){this._subtleCrypto=e,this._crypto=t}async decryptCTR({key:e,jwkKey:t,iv:s,data:i,counterLength:r=64}){const n={name:"AES-CTR",counter:s,length:r};let o;try{const s=e||t,i=t?"jwk":"raw";o=await subtleCryptoResult(this._subtleCrypto.importKey(i,s,n,!1,["decrypt"]),"importKey")}catch(e){throw new Error(`Could not import key for AES-CTR decryption: ${e.message}`)}try{const e=await subtleCryptoResult(this._subtleCrypto.decrypt(n,o,i),"decrypt");return new Uint8Array(e)}catch(e){throw new Error(`Could not decrypt with AES-CTR: ${e.message}`)}}async encryptCTR({key:e,jwkKey:t,iv:s,data:i}){const r={name:"AES-CTR",counter:s,length:64};let n;const o=e||t,a=t?"jwk":"raw";try{n=await subtleCryptoResult(this._subtleCrypto.importKey(a,o,r,!1,["encrypt"]),"importKey")}catch(e){throw new Error(`Could not import key for AES-CTR encryption: ${e.message}`)}try{const e=await subtleCryptoResult(this._subtleCrypto.encrypt(r,n,i),"encrypt");return new Uint8Array(e)}catch(e){throw new Error(`Could not encrypt with AES-CTR: ${e.message}`)}}async generateKey(e,t=256){const s=await subtleCryptoResult(this._subtleCrypto.generateKey({name:"AES-CTR",length:t},!0,["encrypt","decrypt"]));return subtleCryptoResult(this._subtleCrypto.exportKey(e,s))}async generateIV(){return generateIV(this._crypto)}}function generateIV(e){const t=e.getRandomValues(new Uint8Array(8)),s=new Uint8Array(16);for(let e=0;e<t.length;e+=1)s[e]=t[e];return s}function jwkKeyToRaw(e){if("A256CTR"!==e.alg)throw new Error(`Unknown algorithm: ${e.alg}`);if(!e.key_ops.includes("decrypt"))throw new Error("decrypt missing from key_ops");if("oct"!==e.kty)throw new Error(`Invalid key type, "oct" expected: ${e.kty}`);const t=e.k.replace(/-/g,"+").replace(/_/g,"/");return base64__default.default.decode(t)}function encodeUnpaddedBase64(e){const t=base64__default.default.encode(e),s=t.indexOf("=");return-1!==s?t.substr(0,s):t}function encodeUrlBase64(e){return encodeUnpaddedBase64(e).replace(/\+/g,"-").replace(/\//g,"_")}function rawKeyToJwk(e){return{alg:"A256CTR",ext:!0,k:encodeUrlBase64(e),key_ops:["encrypt","decrypt"],kty:"oct"}}class AESLegacyCrypto{constructor(e,t){this._aesjs=e,this._crypto=t}async decryptCTR({key:e,jwkKey:t,iv:s,data:i,counterLength:r=64}){if(64!==r)throw new Error(`Unsupported counter length: ${r}`);t&&(e=jwkKeyToRaw(t));const n=this._aesjs;return new n.ModeOfOperation.ctr(new Uint8Array(e),new n.Counter(new Uint8Array(s))).decrypt(new Uint8Array(i))}async encryptCTR({key:e,jwkKey:t,iv:s,data:i}){t&&(e=jwkKeyToRaw(t));const r=this._aesjs;return new r.ModeOfOperation.ctr(new Uint8Array(e),new r.Counter(new Uint8Array(s))).encrypt(new Uint8Array(i))}async generateKey(e,t=256){let s=crypto.getRandomValues(new Uint8Array(t/8));return"jwk"===e&&(s=rawKeyToJwk(s)),s}async generateIV(){return generateIV(this._crypto)}}function hashName(e){if("SHA-256"!==e&&"SHA-512"!==e)throw new Error(`Invalid hash name: ${e}`);return e}class Crypto{constructor(e){const t=window.crypto||window.msCrypto,s=t.subtle||t.webkitSubtle;this._subtleCrypto=s,!s.deriveBits&&(null==e?void 0:e.aesjs)?this.aes=new AESLegacyCrypto(e.aesjs,t):this.aes=new AESCrypto(s,t),this.hmac=new HMACCrypto(s),this.derive=new DeriveCrypto(s,this,e)}async digest(e,t){return await subtleCryptoResult(this._subtleCrypto.digest(hashName(e),t))}digestSize(e){switch(hashName(e)){case"SHA-512":return 64;case"SHA-256":return 32;default:throw new Error(`Not implemented for ${hashName(e)}`)}}}async function estimateStorageUsage(){var e;if(null==(e=null==navigator?void 0:navigator.storage)?void 0:e.estimate){const{quota:e,usage:t}=await navigator.storage.estimate();return{quota:e,usage:t}}return{quota:null,usage:null}}class WorkerState{constructor(e){this.worker=e,this.busy=!1}attach(e){this.worker.addEventListener("message",e),this.worker.addEventListener("error",e)}detach(e){this.worker.removeEventListener("message",e),this.worker.removeEventListener("error",e)}}class Request$1{constructor(e,t){this._promise=new Promise(((e,t)=>{this._resolve=e,this._reject=t})),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 WorkerPool{constructor(e,t){this._workers=[];for(let s=0;s<t;++s){const t=new WorkerState(new Worker(e));t.attach(this),this._workers[s]=t}this._requests=new Map,this._counter=0,this._pendingFlag=!1,this._init=null}init(){const e=new Promise(((e,t)=>{this._init={resolve:e,reject:t}}));return this.sendAll({type:"ping"}).then(this._init.resolve,this._init.reject).finally((()=>{this._init=null})),e}handleEvent(e){if("message"===e.type){const t=e.data,s=this._requests.get(t.replyToId);if(s){if(s._worker.busy=!1,s._isNotDisposed){if("success"===t.type)s._resolve(t.payload);else if("error"===t.type){const e=new Error(t.message);e.stack=t.stack,s._reject(e)}s._dispose()}this._requests.delete(t.replyToId)}this._sendPending()}else"error"===e.type&&(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(){let e;this._pendingFlag=!1;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 Request$1(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((t=>{const s=this._enqueueRequest(Object.assign({},e));return this._sendWith(s,t),s.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 AbortError),e._worker&&(e._worker.busy=!1),this._requests.delete(e._message.id),this._trySendPendingInNextTick()}}const ALLOWED_BLOB_MIMETYPES={"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},DEFAULT_MIMETYPE="application/octet-stream";class BlobHandle{constructor(e,t=null){this._blob=e,this._buffer=t,this._url=null}static fromBufferUnsafe(e,t){return new BlobHandle(new Blob([e],{type:t}),e)}static fromBuffer(e,t){return t=t?t.split(";")[0].trim():"",ALLOWED_BLOB_MIMETYPES[t]||(t=DEFAULT_MIMETYPE),new BlobHandle(new Blob([e],{type:t}),e)}static fromBlobUnsafe(e){return new BlobHandle(e)}get nativeBlob(){return this._blob}async readAsBuffer(){if(this._buffer)return this._buffer;{const e=new FileReader,t=new Promise(((t,s)=>{e.addEventListener("load",(e=>t(e.target.result))),e.addEventListener("error",(e=>s(e.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||DEFAULT_MIMETYPE}dispose(){this._url&&(URL.revokeObjectURL(this._url),this._url=null)}}class ImageHandle{static async fromBlob(e){const t=await loadImgFromBlob(e),{width:s,height:i}=t;return new ImageHandle(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 loadImgFromBlob(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),n=document.createElement("canvas");n.width=i,n.height=r;const o=n.getContext("2d"),a=await this._getDomElement();o.drawImage(a,0,0,i,r);let l,c="image/jpeg"===this.blob.mimeType?"image/jpeg":"image/png";if(n.toBlob)l=await new Promise((e=>n.toBlob(e,c)));else{if(!n.msToBlob)throw new Error("canvas can't be turned into blob");c="image/png",l=n.msToBlob()}const d=BlobHandle.fromBlobUnsafe(l);return new ImageHandle(d,i,r,null)}dispose(){this.blob.dispose()}}class VideoHandle extends ImageHandle{get duration(){if("number"==typeof this._domElement.duration)return Math.round(1e3*this._domElement.duration)}static async fromBlob(e){const t=await loadVideoFromBlob(e),{videoWidth:s,videoHeight:i}=t;return new VideoHandle(e,s,i,t)}}function hasReadPixelPermission(){const e=document.createElement("canvas");e.width=1,e.height=1;const t=e.getContext("2d"),s=[Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())];t.fillStyle=`rgb(${s[0]}, ${s[1]}, ${s[2]})`,t.fillRect(0,0,1,1);const i=t.getImageData(0,0,1,1).data;return i[0]===s[0]&&i[1]===s[1]&&i[2]===s[2]}async function loadImgFromBlob(e){const t=document.createElement("img"),s=domEventAsPromise(t,"load");return t.src=e.url,await s,t}async function loadVideoFromBlob(e){const t=document.createElement("video");t.muted=!0;const s=domEventAsPromise(t,"loadedmetadata");t.src=e.url,t.load(),await s;const i=domEventAsPromise(t,"seeked");return await new Promise((e=>setTimeout(e,200))),t.currentTime=.1,await i,t}async function downloadInIframe(e,t,s,i,r){let n=e.querySelector("iframe.downloadSandbox");if(!n){let s;n=document.createElement("iframe"),n.setAttribute("sandbox","allow-scripts allow-downloads allow-downloads-without-user-activation"),n.setAttribute("src",t),n.className="hidden downloadSandbox",e.appendChild(n),await new Promise(((e,t)=>{s=()=>{n.removeEventListener("load",e),n.removeEventListener("error",t)},n.addEventListener("load",e),n.addEventListener("error",t)})),s()}if(r){const e=await s.readAsBuffer();n.contentWindow.postMessage({type:"downloadBuffer",buffer:e,mimeType:s.mimeType,filename:i},"*")}else n.contentWindow.postMessage({type:"downloadBlob",blob:s.nativeBlob,filename:i},"*")}class HTMLParseResult{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 sanitizeConfig={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 parseHTML(e){const t=DOMPurify__default.default.sanitize(e,sanitizeConfig),s=(new DOMParser).parseFromString(`<!DOCTYPE html><html><body>${t}</body></html>`,"text/html").body;return new HTMLParseResult(s)}const POLLING_INTERVAL=200,SPEAKING_THRESHOLD=-60,SPEAKING_SAMPLE_COUNT=8;class MediaDevicesWrapper{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",(e=>{console.log(`removing track ${e.track.id} (${e.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:"boolean"!=typeof e?{ideal:e.deviceId}:void 0},video:!!t&&{deviceId:"boolean"!=typeof t?{ideal:t.deviceId}:void 0,width:s?{exact:640}:{ideal:640},height:s?{exact:360}:{ideal:360}}}}getScreenshareContraints(){return{audio:!1,video:!0}}createVolumeMeasurer(e,t){return new WebAudioVolumeMeasurer(e,t)}}class WebAudioVolumeMeasurer{constructor(e,t){this.measuringVolumeActivity=!1,this.speakingThreshold=-60,this.speaking=!1,this.volumeLooper=()=>{if(!this.analyser)return;if(!this.measuringVolumeActivity)return;this.analyser.getFloatFrequencyData(this.frequencyBinCount);let e=-1/0;for(let t=0;t<this.frequencyBinCount.length;t++)this.frequencyBinCount[t]>e&&(e=this.frequencyBinCount[t]);this.speakingVolumeSamples.shift(),this.speakingVolumeSamples.push(e),this.callback();let t=!1;for(let e=0;e<this.speakingVolumeSamples.length;e++){if(this.speakingVolumeSamples[e]>this.speakingThreshold){t=!0;break}}this.speaking!==t&&(this.speaking=t,this.callback()),this.volumeLooperTimeout=setTimeout(this.volumeLooper,200)},this.stream=e,this.callback=t,this.speakingVolumeSamples=new Array(8).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(),null==(e=this.audioContext)||e.close()}}var EventType=(e=>(e.GroupCall="org.matrix.msc3401.call",e.GroupCallMember="org.matrix.msc3401.call.member",e.Invite="m.call.invite",e.Candidates="m.call.candidates",e.Answer="m.call.answer",e.Hangup="m.call.hangup",e.Reject="m.call.reject",e.SelectAnswer="m.call.select_answer",e.Negotiate="m.call.negotiate",e.SDPStreamMetadataChanged="m.call.sdp_stream_metadata_changed",e.SDPStreamMetadataChangedPrefix="org.matrix.call.sdp_stream_metadata_changed",e.Replaces="m.call.replaces",e.AssertedIdentity="m.call.asserted_identity",e.AssertedIdentityPrefix="org.matrix.call.asserted_identity",e))(EventType||{});const SDPStreamMetadataKey="org.matrix.msc3077.sdp_stream_metadata";var SDPStreamMetadataPurpose=(e=>(e.Usermedia="m.usermedia",e.Screenshare="m.screenshare",e))(SDPStreamMetadataPurpose||{}),CallErrorCode=(e=>(e.UserHangup="user_hangup",e.LocalOfferFailed="local_offer_failed",e.NoUserMedia="no_user_media",e.UnknownDevices="unknown_devices",e.SendInvite="send_invite",e.CreateAnswer="create_answer",e.SendAnswer="send_answer",e.SetRemoteDescription="set_remote_description",e.SetLocalDescription="set_local_description",e.AnsweredElsewhere="answered_elsewhere",e.IceFailed="ice_failed",e.InviteTimeout="invite_timeout",e.Replaced="replaced",e.SignallingFailed="signalling_timeout",e.UserBusy="user_busy",e.Transfered="transferred",e.NewSession="new_session",e))(CallErrorCode||{}),CallIntent=(e=>(e.Ring="m.ring",e.Prompt="m.prompt",e.Room="m.room",e))(CallIntent||{}),CallType=(e=>(e.Video="m.video",e.Voice="m.voice",e))(CallType||{});class DOMWebRTC{createPeerConnection(e,t,s){const i=new RTCPeerConnection({iceTransportPolicy:e?"relay":void 0,iceServers:t,iceCandidatePoolSize:s});return new Proxy(i,{get(e,t,s){const i=e[t];return"function"==typeof i?i.bind(e):i}})}prepareSenderForPurpose(e,t,s){s===SDPStreamMetadataPurpose.Screenshare&&this.getRidOfRTXCodecs(e,t)}getRidOfRTXCodecs(e,t){var s,i,r,n,o,a;if(!RTCRtpReceiver.getCapabilities||!RTCRtpSender.getCapabilities)return;const l=null!=(i=null==(s=RTCRtpReceiver.getCapabilities("video"))?void 0:s.codecs)?i:[],c=[...null!=(n=null==(r=RTCRtpSender.getCapabilities("video"))?void 0:r.codecs)?n:[],...l];for(const e of c)if("video/rtx"===e.mimeType){const t=c.indexOf(e);c.splice(t,1)}const d=e.getTransceivers().find((e=>e.sender===t));!d||"video"!==(null==(o=d.sender.track)?void 0:o.kind)&&"video"!==(null==(a=d.receiver.track)?void 0:a.kind)||d.setCodecPreferences(c)}}var ColorSchemePreference=(e=>(e[e.Dark=0]="Dark",e[e.Light=1]="Light",e))(ColorSchemePreference||{});function getColoredSvgString(e,t,s){let i=e.replaceAll("#ff00ff",t);if(i=i.replaceAll("#00ffff",s),e===i)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 i}class IconColorizer{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}`),n=r.hostname,o=new URL(n,new URL(this._manifestLocation,window.location.origin)),a=this._platform.request(o,{method:"GET",format:"text",cache:!0}).response();e.push(a);const l=r.searchParams;t[s]={svg:a,primary:l.get("primary"),secondary:l.get("secondary")}}return{parsedStructure:t,promises:e}}async _produceColoredIconVariables(e){let t={};for(const[s,{svg:i,primary:r,secondary:n}]of Object.entries(e)){const{body:e}=await i;if(!r)throw new Error(`Primary color variable ${r} not in list of variables!`);const o=getColoredSvgString(e,this._resolvedVariables[r],this._resolvedVariables[n]),a=`url('data:image/svg+xml;utf8,${encodeURIComponent(o)}')`;t[s]=a}return t}}const offColor=null!=(_c=pkg__namespace.offColor)?_c:pkg__namespace.default.offColor;function derive(e,t,s,i){const r=parseInt(s);switch(i&&("darker"===t?t="lighter":"lighter"===t&&(t="darker")),t){case"darker":return offColor(e).darken(r/100).hex();case"lighter":return offColor(e).lighten(r/100).hex();case"alpha":return offColor(e).rgba(r/100)}}class DerivedVariables{constructor(e,t,s){this._aliases={},this._derivedAliases=[],this._baseVariables=e,this._variablesToDerive=t,this._isDark=s}toVariables(){var e;const t={};this._detectAliases();for(const e of this._variablesToDerive){const s=this._derive(e);s&&(t[e]=s)}for(const[s,i]of Object.entries(this._aliases))t[s]=null!=(e=this._baseVariables[i])?e:t[i];for(const e of this._derivedAliases){const s=this._deriveAlias(e,t);s&&(t[e]=s)}return t}_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=e.match(/(.+)--(.+)-(.+)/);if(t){const[,s,i,r]=t,n=this._baseVariables[s];if(!n){if(this._aliases[s])return void this._derivedAliases.push(e);throw new Error(`Cannot find value for base variable "${s}"!`)}return derive(n,i,r,this._isDark)}}_deriveAlias(e,t){const s=e.match(/(.+)--(.+)-(.+)/);if(s){const[,i,r,n]=s,o=t[i];if(!o)throw new Error(`Cannot find value for alias "${i}" when trying to derive ${e}!`);return derive(o,r,n,this._isDark)}}}null!=(_d=pkg__namespace.offColor)||pkg__namespace.default.offColor;class RuntimeThemeParser{constructor(e,t){this._themeMapping={},this._preferredColorScheme=t,this._platform=e}async parse(e,t,s,i){await i.wrap("RuntimeThemeParser.parse",(async()=>{var r;const{cssLocation:n,derivedVariables:o,icons:a}=this._getSourceData(t,s,i),l=e.name;if(!l)throw new Error("Theme name not found in manifest!");let c={},d={};for(const[t,i]of Object.entries(null==(r=e.values)?void 0:r.variants))try{const r=`${e.id}-${t}`,{name:h,default:u,dark:m,variables:p}=i,g=new DerivedVariables(p,o,m).toVariables();Object.assign(p,g);const _=await new IconColorizer(this._platform,a,p,s).toVariables();Object.assign(p,g,_);const y=`${l} ${h}`;if(u){const e=m?c:d;Object.assign(e,{variantName:h,id:r,cssLocation:n,variables:p});continue}this._themeMapping[y]={cssLocation:n,id:r,variables:p}}catch(e){console.error(e);continue}if(c.id&&d.id){const e=this._preferredColorScheme===ColorSchemePreference.Dark?c:d;this._themeMapping[l]={dark:c,light:d,default:e}}else{const e=c.id?c:d;this._themeMapping[`${l} ${e.variantName}`]={id:e.id,cssLocation:e.cssLocation}}}))}_getSourceData(e,t,s){return s.wrap("getSourceData",(()=>{var s,i,r;const n=null==(s=e.source)?void 0:s["runtime-asset"];if(!n)throw new Error(`Run-time asset not found in source section for theme at ${t}`);const o=new URL(n,new URL(t,window.location.origin)).href,a=null==(i=e.source)?void 0:i["derived-variables"];if(!a)throw new Error(`Derived variables not found in source section for theme at ${t}`);const l=null==(r=e.source)?void 0:r.icon;if(!l)throw new Error(`Icon mapping not found in source section for theme at ${t}`);return{cssLocation:o,derivedVariables:a,icons:l}}))}get themeMapping(){return this._themeMapping}}class BuiltThemeParser{constructor(e){this._themeMapping={},this._preferredColorScheme=e}parse(e,t,s){s.wrap("BuiltThemeParser.parse",(()=>{var s,i,r;const n=null==(s=e.source)?void 0:s["built-assets"],o=e.name;if(!o)throw new Error(`Theme name not found in manifest at ${t}`);let a={},l={};for(let[s,c]of Object.entries(n)){try{c=new URL(c,new URL(t,window.location.origin)).href}catch{continue}const n=null==(i=s.match(/.+-(.+)/))?void 0:i[1],d=null==(r=e.values)?void 0:r.variants[n];if(!d)throw new Error(`Variant ${n} is missing in manifest at ${t}`);const{name:h,default:u,dark:m}=d,p=`${o} ${h}`;if(u){const e=m?a:l;e.variantName=h,e.id=s,e.cssLocation=c}else this._themeMapping[p]={cssLocation:c,id:s}}if(a.id&&l.id){const e=this._preferredColorScheme===ColorSchemePreference.Dark?a:l;this._themeMapping[o]={dark:a,light:l,default:e}}else{const e=a.id?a:l;this._themeMapping[`${o} ${e.variantName}`]={id:e.id,cssLocation:e.cssLocation}}}))}get themeMapping(){return this._themeMapping}}class ThemeLoader{constructor(e){this._platform=e}async init(e,t){await this._platform.logger.wrapOrRun(t,"ThemeLoader.init",(async t=>{let s=!0;const i=[],r=[],n=await Promise.all(e.map((e=>this._platform.request(e,{method:"GET",format:"json",cache:!0}).response()))),o=new RuntimeThemeParser(this._platform,this.preferredColorScheme),a=new BuiltThemeParser(this.preferredColorScheme),l=[];for(let c=0;c<n.length;++c){const d=n[c],{status:h,body:u}=d;if(h>=200&&h<=299){s=!1;try{if(u.extends){const s=n.findIndex((e=>"value"in e&&e.value.body.id===u.extends));if(-1===s)throw new Error(`Base manifest for derived theme at ${e[c]} not found!`);const{body:i}=n[s].value,r=e[s],a=o.parse(u,i,r,t);l.push(a)}else a.parse(u,e[c],t)}catch(e){console.error(e),r.push(e.message)}}else console.error(`Failed to load manifest at ${e[c]}, status: ${h}`),t.log({l:"Manifest fetch failed",location:e[c],status:h},LogLevel.Error),i.push(e[c])}if(await Promise.all(l),this._themeMapping=__spreadValues(__spreadValues({},a.themeMapping),o.themeMapping),s)throw new Error(`All configured theme manifests failed to load, the following were tried: ${i.join(", ")}`);if(0===Object.keys(this._themeMapping).length&&r.length)throw new Error(`Failed to parse theme manifests, the following errors were encountered: ${r.join(", ")}`);this._addDefaultThemeToMapping(t),t.log({l:"Preferred colorscheme",scheme:this.preferredColorScheme===ColorSchemePreference.Dark?"dark":"light"}),t.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,n,o=this._themeMapping[e];if("id"in o)r=o.cssLocation,n=o.variables;else{if(!t)throw new Error("themeVariant is undefined!");r=o[t].cssLocation,n=o[t].variables}await this._platform.replaceStylesheet(r,i),n?(null==s||s.log({l:"Derived Theme",variables:n}),this._injectCSSVariables(n)):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 ColorSchemePreference.Dark:return null==(e=this._platform.config.defaultTheme)?void 0:e.dark;case ColorSchemePreference.Light:return null==(t=this._platform.config.defaultTheme)?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&&(null==(t=r.light)?void 0:t.id)===e)return{themeName:i,themeData:r.light};if("dark"in r&&(null==(s=r.dark)?void 0:s.id)===e)return{themeName:i,themeData:r.dark}}}_addDefaultThemeToMapping(e){e.wrap("addDefaultThemeToMapping",(e=>{const t=this.getDefaultTheme();if(t){const e=this._findThemeDetailsFromId(t);if(e){this._themeMapping.Default={id:"default",cssLocation:e.themeData.cssLocation};const t=e.themeData.variables;t&&(this._themeMapping.Default.variables=t)}}e.log({l:"Default Theme",theme:t})}))}get preferredColorScheme(){return window.matchMedia("(prefers-color-scheme: dark)").matches?ColorSchemePreference.Dark:window.matchMedia("(prefers-color-scheme: light)").matches?ColorSchemePreference.Light:void 0}}var TimeScope=(e=>(e[e.Minute=6e4]="Minute",e[e.Hours=36e5]="Hours",e[e.Day=864e5]="Day",e))(TimeScope||{});function formatDuration(e){let t=0,s=0,i=0;e>=864e5&&(t=Math.floor(e/864e5),e-=864e5*t),e>=36e5&&(s=Math.floor(e/36e5),e-=36e5*s),e>=6e4&&(i=Math.floor(e/6e4),e-=6e4*i);let r="";return t&&(r=`${t}d `),(s||t)&&(r+=`${s}h `),(i||s||t)&&(r+=`${i}m `),r+=`${Math.floor(e/1e3)}s`,r}class TimeFormatter{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())/TimeScope.Day);return t>=-1&&t<=1?capitalizeFirstLetter(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 formatDuration(e)}}function capitalizeFirstLetter(e){return e.slice(0,1).toLocaleUpperCase()+e.slice(1)}function addScript(e){return new Promise((function(t,s){var i=document.createElement("script");i.setAttribute("src",e),i.onload=t,i.onerror=s,document.body.appendChild(i)}))}async function loadOlm(e){return window.msCrypto&&!window.crypto&&(window.crypto=window.msCrypto),e?(window.WebAssembly?(await addScript(e.wasmBundle),await window.Olm.init({locateFile:()=>e.wasm})):(await addScript(e.legacyBundle),await window.Olm.init()),window.Olm):null}function assetAbsPath(e){return e.startsWith("/")?e:new URL(e,document.location.href).pathname}async function loadOlmWorker(e){const t=new WorkerPool(e.worker,4);await t.init(),await t.sendAll({type:"load_olm",path:assetAbsPath(e.olm.legacyBundle)});return new OlmWorker(t)}function adaptUIOnVisualViewportResize(e){if(!window.visualViewport)return;const t=()=>{const t=e.querySelector(".SessionView");if(!t)return;const s=e.querySelector(".bottom-aligned-scroll");let i,r,n;s&&(i=s.scrollTop,r=s.offsetHeight);const o=t.offsetTop+t.offsetHeight-window.visualViewport.height;e.style.setProperty("--ios-viewport-height",window.visualViewport.height.toString()+"px"),e.style.setProperty("--ios-viewport-top",o.toString()+"px"),s&&(n=s.offsetHeight,s.scrollTop=i+r-n)};return window.visualViewport.addEventListener("resize",t),()=>{window.visualViewport.removeEventListener("resize",t)}}class Platform{constructor({container:e,assetPaths:t,config:s,configURL:i,logger:r,options:n=null,cryptoExtras:o=null}){this._container=e,this._assetPaths=t,this._config=s,this._configURL=i,this.settingsStorage=new SettingsStorage("hydrogen_setting_v1_"),this.clock=new Clock,this.encoding=new Encoding,this.random=Math.random,this.logger=null!=r?r:this._createLogger(null==n?void 0:n.development),this.history=new History,this.onlineStatus=new OnlineStatus,this.timeFormatter=new TimeFormatter,this._serviceWorkerHandler=null,t.serviceWorker&&"serviceWorker"in navigator&&(this._serviceWorkerHandler=new ServiceWorkerHandler,this._serviceWorkerHandler.registerAndStart(t.serviceWorker)),this.notificationService=void 0,this._assetPaths.olm&&(this.crypto=new Crypto(o)),this.storageFactory=new StorageFactory(this._serviceWorkerHandler),this.sessionInfoStorage=new SessionInfoStorage("hydrogen_sessions_v1"),this.estimateStorageUsage=estimateStorageUsage,"function"==typeof fetch?this.request=createFetchRequest(this.clock.createTimeout,this._serviceWorkerHandler):this.request=xhrRequest;const a=!!window.MSInputMethodContext&&!!document.documentMode;this.isIE11=a;const l=/iPad|iPhone|iPod/.test(navigator.platform)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1&&!window.MSStream;this.isIOS=l,this._disposables=new Disposables,this._olmPromise=void 0,this._workerPromise=void 0,this.mediaDevices=new MediaDevicesWrapper(navigator.mediaDevices),this.webRTC=new DOMWebRTC,this._themeLoader=new ThemeLoader(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:e,body:t}=await this.request(this._configURL,{method:"GET",format:"json",cache:!0}).response();if(404===e)throw new Error(`Could not find ${this._configURL}. Did you copy over config.sample.json?`);if(e>=400)throw new Error(`Got status ${e} while trying to fetch ${this._configURL}`);this._config=t}if(this.notificationService=new NotificationService(this._serviceWorkerHandler,this._config.push),this._themeLoader){const s=this.config.themeManifests;await(null==(t=this._themeLoader)?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 Logger({platform:this}),s=new IDBLogPersister({name:"hydrogen_logs",platform:this,serializedTransformer:e=>{var t;return(null==(t=e.e)?void 0:t.stack)&&(e.e.stack=e.e.stack.replace(/\/\?loginToken=(.+)/,"?loginToken=<snip>")),e}});return t.addReporter(s),e&&t.addReporter(new ConsoleReporter),t}get updateService(){return this._serviceWorkerHandler}loadOlm(){return this._olmPromise||(this._olmPromise=loadOlm(this._assetPaths.olm)),this._olmPromise}get config(){return this._config}async loadOlmWorker(){if(!window.WebAssembly)return this._workerPromise||(this._workerPromise=loadOlmWorker(this._assetPaths)),this._workerPromise}createAndMountRootView(e){if(this.isIE11&&(this._container.className+=" legacy"),this.isIOS){this._container.className+=" ios";const e=adaptUIOnVisualViewportResize(this._container);e&&this._disposables.track(e)}this._container.addEventListener("error",handleAvatarError,!0),this._disposables.track((()=>this._container.removeEventListener("error",handleAvatarError,!0))),window.__hydrogenViewModel=e;const t=new RootView(e);this._container.appendChild(t.mount())}setNavigation(e){var t;null==(t=this._serviceWorkerHandler)||t.setNavigation(e)}createBlob(e,t){return BlobHandle.fromBuffer(e,t)}saveFileAs(e,t){navigator.msSaveBlob?navigator.msSaveBlob(e.nativeBlob,t):downloadInIframe(this._container,this._assetPaths.downloadSandbox,e,t,this.isIOS)}async copyPlaintext(e){return await copyPlaintext(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((e=>{const s=()=>{t.removeEventListener("change",s,!0);const i=t.files[0];this._container.removeChild(t),i?e({name:i.name,blob:BlobHandle.fromBlobUnsafe(i)}):e()};t.addEventListener("change",s,!0)}));return this._container.appendChild(t),t.click(),s}openUrl(e){location.href=e}parseHTML(e){return parseHTML(e)}async loadImage(e){return ImageHandle.fromBlob(e)}async loadVideo(e){return VideoHandle.fromBlob(e)}hasReadPixelPermission(){return hasReadPixelPermission()}get devicePixelRatio(){return window.devicePixelRatio||1}get version(){return"0.3.8"}get themeLoader(){return this._themeLoader}async replaceStylesheet(e,t){const s=await this.logger.wrapOrRun(t,{l:"replaceStylesheet",location:e},(async t=>{let s;const i=document.querySelector("head");document.querySelectorAll(".theme").forEach((e=>e.remove()));const r=document.createElement("link");r.href=e,r.rel="stylesheet",r.type="text/css",r.className="theme";const n=new Promise((i=>{r.onerror=()=>{s=new Error(`Failed to load stylesheet from ${e}`),t.catch(s),i()},r.onload=()=>{i()}}));return i.appendChild(r),await n,s}));if(s)throw s}get description(){var e;return"web-"+(null!=(e=navigator.userAgent)?e:"<unknown>")}dispose(){this._disposables.dispose()}}var FeatureFlag=(e=>(e[e.Calls=1]="Calls",e[e.CrossSigning=2]="CrossSigning",e))(FeatureFlag||{});class FeatureSet{constructor(e=0){this.flags=e}withFeature(e){return new FeatureSet(this.flags|e)}withoutFeature(e){return new FeatureSet(this.flags^e)}isFeatureEnabled(e){return!!(this.flags&e)}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 FeatureSet(t)}async store(e){await e.setInt("enabled_features",this.flags)}}function createEnum(...e){const t={};for(const s of e)t[s]=s;return Object.freeze(t)}function normalizeHomeserver(e){try{return new URL(e).origin}catch(t){return new URL(`https://${e}`).origin}}async function getWellKnownResponse(e,t){const s={format:"json",timeout:3e4,method:"GET"};try{const i=`${e}/.well-known/matrix/client`;return await t(i,s).response()}catch(e){if("ConnectionError"===e.name)return null;throw e}}async function lookupHomeserver(e,t){var s,i,r;e=normalizeHomeserver(e);let n=null,o=null;const a=await getWellKnownResponse(e,t);if(a&&200===a.status){const{body:t}=a,l=null==(s=t["m.homeserver"])?void 0:s.base_url;"string"==typeof l&&(e=normalizeHomeserver(l));const c=null==(i=t["org.matrix.msc2965.authentication"])?void 0:i.issuer;"string"==typeof c&&(n=c);const d=null==(r=t["org.matrix.msc2965.authentication"])?void 0:r.account;"string"==typeof d&&(o=d)}return{homeserver:e,issuer:n,account:o}}class AbortableOperation extends EventEmitter{constructor(e){super(),this._abortable=void 0;this._progress=void 0;this.result=e((e=>(this._abortable=e,e)),(e=>{this._progress=e,this.emit("change","progress")}))}get progress(){return this._progress}abort(){var e;null==(e=this._abortable)||e.abort(),this._abortable=void 0}}function encodeQueryParams(e){return Object.entries(e||{}).filter((([,e])=>void 0!==e)).map((([e,t])=>("object"==typeof t&&(t=JSON.stringify(t)),`${encodeURIComponent(e)}=${encodeURIComponent(t)}`))).join("&")}function encodeBody(e){if(e instanceof BlobHandle){const t=e;return{mimeType:t.mimeType,body:t}}if(e instanceof Map)return{mimeType:"multipart/form-data",body:e};if("object"==typeof e){return{mimeType:"application/json",body:JSON.stringify(e)}}throw new Error("Unknown body type: "+e)}class HomeServerRequest{constructor(e,t,s,i){let r;if(null==i?void 0:i.log){const s=null==i?void 0:i.log;r=s.child({t:"network",url:t,method:e},s.level.Info)}this._log=r,this._sourceRequest=s,this._promise=s.response().then((s=>{var n,o;if(null==r||r.set("status",s.status),s.status>=200&&s.status<300||(null==(n=null==i?void 0:i.allowedStatusCodes)?void 0:n.includes(s.status)))return null==r||r.finish(),s.body;if(s.status>=500){const e=new ConnectionError("Internal Server Error");throw null==r||r.catch(e),e}if(s.status>=400&&!(null==(o=s.body)?void 0:o.errcode)){const e=new ConnectionError(`HTTP error status ${s.status} without errcode in body, assume this is a load balancer complaining the server is offline.`);throw null==r||r.catch(e),e}{const i=new HomeServerError(e,t,s.body,s.status);throw null==r||r.set("errcode",i.errcode),null==r||r.catch(i),i}}),(e=>{if("AbortError"===e.name&&this._sourceRequest){const e=new ConnectionError("Service worker aborted, either updating or hit #187.");throw null==r||r.catch(e),e}throw"ConnectionError"===e.name&&(null==r||r.set("timeout",e.isTimeout)),null==r||r.catch(e),e}))}abort(){var e;this._sourceRequest&&(null==(e=this._log)||e.set("aborted",!0),this._sourceRequest.abort(),this._sourceRequest=void 0)}response(){return this._promise}async responseCode(){return(await this._sourceRequest.response()).status}}const CS_R0_PREFIX="/_matrix/client/r0",CS_V3_PREFIX="/_matrix/client/v3",DEHYDRATION_PREFIX="/_matrix/client/unstable/org.matrix.msc2697.v2";class HomeServerApi{constructor({homeserver:e,accessToken:t,request:s,reconnector:i}){this._homeserver=e,this._accessToken=t,this._requestFn=s,this._reconnector=i}_url(e,t=CS_R0_PREFIX){return this._homeserver+t+e}_baseRequest(e,t,s,i,r,n){let o;t=`${t}?${encodeQueryParams(s)}`;const a=new Map;let l=null;if((null==r?void 0:r.accessTokenOverride)?l=r.accessTokenOverride:n&&(l=n.get()),l&&a.set("Authorization",`Bearer ${l}`),a.set("Accept","application/json"),i){const e=encodeBody(i);a.set("Content-Type",e.mimeType),o=e.body}const c=this._requestFn(t,{method:e,headers:a,body:o,timeout:null==r?void 0:r.timeout,uploadProgress:null==r?void 0:r.uploadProgress,format:"json",cache:"GET"!==e}),d=new HomeServerRequest(e,t,c,r);return this._reconnector&&d.response().catch((e=>{"ConnectionError"===e.name&&this._reconnector.onRequestFailed(this)})),d}_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,(null==i?void 0:i.prefix)||CS_R0_PREFIX),t,s,i)}_put(e,t,s,i){return this._authedRequest("PUT",this._url(e,(null==i?void 0:i.prefix)||CS_R0_PREFIX),t,s,i)}_get(e,t,s,i){return this._authedRequest("GET",this._url(e,(null==i?void 0:i.prefix)||CS_R0_PREFIX),t,s,i)}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)}event(e,t,s){return this._get(`/rooms/${encodeURIComponent(e)}/event/${encodeURIComponent(t)}`,void 0,void 0,s)}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,n={}){n.allowedStatusCodes=[401];const o={auth:i,password:t,initial_device_displayname:s,inhibit_login:r};return e&&(o.username=e),this._unauthedRequest("POST",this._url("/register",CS_V3_PREFIX),void 0,o,n)}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+=`/${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 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)}join(e,t){return this._post(`/rooms/${encodeURIComponent(e)}/join`,{},{},t)}joinIdOrAlias(e,t){return this._post(`/join/${encodeURIComponent(e)}`,{},{},t)}invite(e,t,s){return this._post(`/rooms/${encodeURIComponent(e)}/invite`,{},{user_id:t},s)}leave(e,t){return this._post(`/rooms/${encodeURIComponent(e)}/leave`,{},{},t)}forget(e,t){return this._post(`/rooms/${encodeURIComponent(e)}/forget`,{},{},t)}kick(e,t,s,i){return this._post(`/rooms/${encodeURIComponent(e)}/kick`,{},{user_id:t,reason:s},i)}ban(e,t,s,i){return this._post(`/rooms/${encodeURIComponent(e)}/ban`,{},{user_id:t,reason:s},i)}unban(e,t,s,i){return this._post(`/rooms/${encodeURIComponent(e)}/unban`,{},{user_id:t,reason:s},i)}logout(e){return this._post("/logout",{},{},e)}whoami(e){return this._get("/account/whoami",void 0,void 0,e)}getDehydratedDevice(e={}){return e.prefix=DEHYDRATION_PREFIX,this._get("/dehydrated_device",void 0,void 0,e)}createDehydratedDevice(e,t={}){return t.prefix=DEHYDRATION_PREFIX,this._put("/dehydrated_device",{},e,t)}claimDehydratedDevice(e,t={}){return t.prefix=DEHYDRATION_PREFIX,this._post("/dehydrated_device/claim",{},{device_id:e},t)}searchProfile(e,t,s){return this._post("/user_directory/search",{},{limit:null!=t?t:10,search_term:e},s)}profile(e,t){return this._get(`/profile/${encodeURIComponent(e)}`)}setProfileDisplayName(e,t,s){return this._put(`/profile/${encodeURIComponent(e)}/displayname`,{},{displayname:t},s)}setProfileAvatarUrl(e,t,s){return this._put(`/profile/${encodeURIComponent(e)}/avatar_url`,{},{avatar_url:t},s)}createRoom(e,t){return this._post("/createRoom",{},e,t)}accountData(e,t,s){return this._get(`/user/${encodeURIComponent(e)}/account_data/${encodeURIComponent(t)}`,void 0,void 0,s)}setAccountData(e,t,s,i){return this._put(`/user/${encodeURIComponent(e)}/account_data/${encodeURIComponent(t)}`,{},s,i)}roomAccountData(e,t,s,i){return this._get(`/user/${encodeURIComponent(e)}/rooms/${encodeURIComponent(t)}/account_data/${encodeURIComponent(s)}`,void 0,void 0,i)}setRoomAccountData(e,t,s,i,r){return this._put(`/user/${encodeURIComponent(e)}/rooms/${encodeURIComponent(t)}/account_data/${encodeURIComponent(s)}`,{},i,r)}getTurnServer(e){return this._get("/voip/turnServer",void 0,void 0,e)}}const WELL_KNOWN=".well-known/openid-configuration",RANDOM_CHARSET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",randomChar=()=>RANDOM_CHARSET.charAt(Math.floor(1e10*Math.random())%62),randomString=e=>Array.from({length:e},randomChar).join(""),isValidBearerToken=e=>!("object"!=typeof e||"Bearer"!==e.token_type||"string"!=typeof e.access_token||"refresh_token"in e&&"string"!=typeof e.refresh_token||"expires_in"in e&&"number"!=typeof e.expires_in);function assert(e,t){if(!e)throw new Error(`Assertion failed: ${t}`)}class OidcApi{constructor({issuer:e,request:t,encoding:s,crypto:i,urlRouter:r,clientId:n,staticClients:o={}}){this._issuer=e,this._requestFn=t,this._encoding=s,this._crypto=i,this._urlRouter=r,this._staticClients=o,n&&(this._registrationPromise=Promise.resolve({client_id:n}))}get clientMetadata(){return{client_name:"Hydrogen Web",logo_uri:this._urlRouter.absoluteUrlForAsset("icon.png"),client_uri:this._urlRouter.absoluteAppUrl(),tos_uri:"https://element.io/terms-of-service",policy_uri:"https://element.io/privacy",response_types:["code"],grant_types:["authorization_code","refresh_token"],redirect_uris:[this._urlRouter.createOIDCRedirectURL()],id_token_signed_response_alg:"RS256",token_endpoint_auth_method:"none",post_logout_redirect_uris:[this._urlRouter.createOIDCPostLogoutRedirectURL()]}}get metadataUrl(){return new URL(WELL_KNOWN,`${this._issuer}${this._issuer.endsWith("/")?"":"/"}`).toString()}get issuer(){return this._issuer}async clientId(){return(await this.registration()).client_id}registration(){return this._registrationPromise||(this._registrationPromise=(async()=>{const e=`${this.issuer}${this.issuer.endsWith("/")?"":"/"}`;if(this._staticClients[e])return this._staticClients[e];const t=new Map;t.set("Accept","application/json"),t.set("Content-Type","application/json");const s=this._requestFn(await this.registrationEndpoint(),{method:"POST",headers:t,format:"json",body:JSON.stringify(this.clientMetadata)}),i=await s.response();if(i.status>=400)throw new Error("failed to register client");return i.body})()),this._registrationPromise}metadata(){return this._metadataPromise||(this._metadataPromise=(async()=>{const e=new Map;e.set("Accept","application/json");const t=this._requestFn(this.metadataUrl,{method:"GET",headers:e,format:"json"}),s=await t.response();if(s.status>=400)throw new Error("failed to request metadata");return s.body})()),this._metadataPromise}async validate(){const e=await this.metadata();assert("string"==typeof e.authorization_endpoint,"Has an authorization endpoint"),assert("string"==typeof e.token_endpoint,"Has a token endpoint"),assert("string"==typeof e.registration_endpoint,"Has a registration endpoint"),assert(Array.isArray(e.response_types_supported)&&e.response_types_supported.includes("code"),"Supports the code response type"),assert(Array.isArray(e.response_modes_supported)&&e.response_modes_supported.includes("fragment"),"Supports the fragment response mode"),assert("string"==typeof e.authorization_endpoint||Array.isArray(e.grant_types_supported)&&e.grant_types_supported.includes("authorization_code"),"Supports the authorization_code grant type"),assert(Array.isArray(e.code_challenge_methods_supported)&&e.code_challenge_methods_supported.includes("S256"),"Supports the authorization_code grant type")}async _generateCodeChallenge(e){const t=this._encoding.utf8.encode(e),s=await this._crypto.digest("SHA-256",t);return this._encoding.base64.encode(s).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async authorizationEndpoint({state:e,redirectUri:t,scope:s,nonce:i,codeVerifier:r}){const n=await this.metadata(),o=new URL(n.authorization_endpoint);return o.searchParams.append("response_mode","fragment"),o.searchParams.append("response_type","code"),o.searchParams.append("redirect_uri",t),o.searchParams.append("client_id",await this.clientId()),o.searchParams.append("state",e),o.searchParams.append("scope",s),i&&o.searchParams.append("nonce",i),r&&(o.searchParams.append("code_challenge_method","S256"),o.searchParams.append("code_challenge",await this._generateCodeChallenge(r))),o.toString()}async tokenEndpoint(){return(await this.metadata()).token_endpoint}async registrationEndpoint(){return(await this.metadata()).registration_endpoint}async revocationEndpoint(){return(await this.metadata()).revocation_endpoint}async endSessionEndpoint({idTokenHint:e,logoutHint:t,redirectUri:s,state:i}){const r=(await this.metadata()).end_session_endpoint;if(!r)return;s||(s=this._urlRouter.createOIDCPostLogoutRedirectURL());const n=new URL(r);return n.searchParams.append("client_id",await this.clientId()),n.searchParams.append("post_logout_redirect_uri",s),e&&n.searchParams.append("id_token_hint",e),t&&n.searchParams.append("logout_hint",t),i&&n.searchParams.append("state",i),n.href}async isGuestAvailable(){var e;return null==(e=(await this.metadata()).scopes_supported)?void 0:e.includes("urn:matrix:org.matrix.msc2967.client:api:guest")}generateDeviceScope(){return`urn:matrix:org.matrix.msc2967.client:device:${randomString(10)}`}generateParams({scope:e,redirectUri:t}){return{scope:e,redirectUri:t,state:randomString(8),nonce:randomString(8),codeVerifier:randomString(64)}}async completeAuthorizationCodeGrant({codeVerifier:e,code:t,redirectUri:s}){const i=new URLSearchParams;i.append("grant_type","authorization_code"),i.append("client_id",await this.clientId()),i.append("code_verifier",e),i.append("redirect_uri",s),i.append("code",t);const r=i.toString(),n=new Map;n.set("Content-Type","application/x-www-form-urlencoded");const o=this._requestFn(await this.tokenEndpoint(),{method:"POST",headers:n,format:"json",body:r}),a=await o.response();if(a.status>=400)throw new Error("failed to exchange authorization code");const l=a.body;return assert(isValidBearerToken(l),"Got back a valid bearer token"),l}async refreshToken({refreshToken:e}){const t=new URLSearchParams;t.append("grant_type","refresh_token"),t.append("client_id",await this.clientId()),t.append("refresh_token",e);const s=t.toString(),i=new Map;i.set("Content-Type","application/x-www-form-urlencoded");const r=this._requestFn(await this.tokenEndpoint(),{method:"POST",headers:i,format:"json",body:s}),n=await r.response();if(n.status>=400)throw new Error("failed to use refresh token");const o=n.body;return assert(isValidBearerToken(o),"Got back a valid bearer token"),o}async revokeToken({token:e,type:t}){const s=await this.revocationEndpoint();if(!s)return;const i=new URLSearchParams;i.append("token_type",t),i.append("token",e),i.append("client_id",await this.clientId());const r=i.toString(),n=new Map;n.set("Content-Type","application/x-www-form-urlencoded");const o=this._requestFn(s,{method:"POST",headers:n,body:r});if((await o.response()).status>=400)throw new Error("failed to revoke token")}}class BaseObservableValue extends BaseObservable{emit(e){for(const t of this._handlers)t(e)}waitFor(e){return e(this.get())?new ResolvedWaitForHandle(Promise.resolve(this.get())):new WaitForHandle(this,e)}flatMap(e){return new FlatMapObservableValue(this,e)}map(e){return new MappedObservableValue(this,e)}}class WaitForHandle{constructor(e,t){this._promise=new Promise(((s,i)=>{this._reject=i,this._subscription=e.subscribe((e=>{t(e)&&(this._reject=null,s(e),this.dispose())}))}))}get promise(){return this._promise}dispose(){this._subscription&&(this._subscription(),this._subscription=null),this._reject&&(this._reject(new AbortError),this._reject=null)}}class ResolvedWaitForHandle{constructor(e){this.promise=e}dispose(){}}class ObservableValue extends BaseObservableValue{constructor(e){super(),this._value=e}get(){return this._value}set(e){e!==this._value&&(this._value=e,this.emit(this._value))}}class FlatMapObservableValue extends BaseObservableValue{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)return void(this.targetSubscription||(this.targetSubscription=t.subscribe((()=>this.emit(this.get())))))}this.targetSubscription&&(this.targetSubscription=this.targetSubscription())}get(){const e=this.source.get();if(!e)return;const t=this.mapper(e);return null==t?void 0:t.get()}}class MappedObservableValue extends BaseObservableValue{constructor(e,t){super(),this.source=e,this.mapper=t}onUnsubscribeLast(){super.onUnsubscribeLast(),this.sourceSubscription=this.sourceSubscription()}onSubscribeFirst(){super.onSubscribeFirst(),this.sourceSubscription=this.source.subscribe((()=>{this.emit(this.get())}))}get(){const e=this.source.get();return this.mapper(e)}}class TokenRefresher{constructor({oidcApi:e,refreshToken:t,accessToken:s,accessTokenExpiresAt:i,anticipation:r,clock:n}){this._token=new ObservableValue({accessToken:s,accessTokenExpiresAt:i,refreshToken:t}),this._accessToken=this._token.map((e=>e.accessToken)),this._anticipation=r,this._oidcApi=e,this._clock=n}async start(){this.needsRenewing&&await this.renew(),this._running=!0,this._renewingLoop()}stop(){this._running=!1,this._timeout&&this._timeout.dispose()}get needsRenewing(){return this._token.get().accessTokenExpiresAt-this._clock.now()-this._anticipation<0}async _renewingLoop(){for(;this._running;){const e=this._token.get().accessTokenExpiresAt-this._clock.now()-this._anticipation;if(e>0){this._timeout=this._clock.createTimeout(e);try{await this._timeout.elapsed()}catch{return}}await this.renew()}}async renew(){let e=this._token.get().refreshToken;const t=await this._oidcApi.refreshToken({refreshToken:e});if("number"!=typeof t.expires_in)throw new Error("Refreshed access token does not expire");t.refresh_token&&(e=t.refresh_token),this._token.set({refreshToken:e,accessToken:t.access_token,accessTokenExpiresAt:this._clock.now()+1e3*t.expires_in})}get accessToken(){return this._accessToken}get token(){return this._token}}class ExponentialRetryDelay{constructor(e){this._start=2e3,this._current=2e3;this._start=2e3,this._current=2e3,this._createTimeout=e,this._max=3e5}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 AbortError))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 ConnectionStatus=(e=>(e[e.Waiting=0]="Waiting",e[e.Reconnecting=1]="Reconnecting",e[e.Online=2]="Online",e))(ConnectionStatus||{});class Reconnector{constructor({retryDelay:e,createMeasure:t,onlineStatus:s}){this._onlineStatus=s,this._retryDelay=e,this._createTimeMeasure=t,this._state=new ObservableValue$1(2),this._isReconnecting=!1}get lastVersionsResponse(){return this._versionsResponse}get connectionStatus(){return this._state}get retryIn(){return 0===this._state.get()?this._retryDelay.nextValue-this._stateSince.measure():0}async onRequestFailed(e){if(!this._isReconnecting){this._isReconnecting=!0;const t=this._onlineStatus&&this._onlineStatus.subscribe((e=>{e&&this.tryNow()}));try{await this._reconnectLoop(e)}catch(e){console.error(e)}finally{t&&t(),this._isReconnecting=!1}}}tryNow(){this._retryDelay&&this._retryDelay.abort()}_setState(e){e!==this._state.get()&&(this._stateSince=0===e?this._createTimeMeasure():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(e){if("ConnectionError"!==e.name)throw e;this._setState(0),await this._retryDelay.waitForRetry()}}}async function decryptAttachment(e,t,s){if(void 0===s||void 0===s.key||void 0===s.iv||void 0===s.hashes||void 0===s.hashes.sha256)throw new Error("Invalid info. Missing info.key, info.iv or info.hashes.sha256 key");const{crypto:i}=e,{base64:r}=e.encoding;var n=r.decode(s.iv),o=r.encode(r.decode(s.hashes.sha256));const a=await i.digest("SHA-256",t);if(r.encode(new Uint8Array(a))!=o)throw new Error("Mismatched SHA-256 digest");var l;l="v1"==s.v||"v2"==s.v?64:128;return await i.aes.decryptCTR({jwkKey:s.key,iv:n,data:t,counterLength:l})}async function encryptAttachment(e,t){const{crypto:s}=e,{base64:i}=e.encoding,r=await s.aes.generateIV(),n=await s.aes.generateKey("jwk",256),o=await t.readAsBuffer(),a=await s.aes.encryptCTR({jwkKey:n,iv:r,data:o}),l=await s.digest("SHA-256",a);return{blob:e.createBlob(a,"application/octet-stream"),info:{v:"v2",key:n,iv:i.encodeUnpadded(r),hashes:{sha256:i.encodeUnpadded(l)}}}}class MediaRepository{constructor({homeserver:e,platform:t}){this._homeserver=e,this._platform=t}mxcUrlThumbnail(e,t,s,i){const r=this._parseMxcUrl(e);if(r){const[e,n]=r;return`${this._homeserver}/_matrix/media/r0/thumbnail/${encodeURIComponent(e)}/${encodeURIComponent(n)}`+"?"+encodeQueryParams({width:Math.round(t),height:Math.round(s),method:i})}}mxcUrl(e){const t=this._parseMxcUrl(e);if(t){const[e,s]=t;return`${this._homeserver}/_matrix/media/r0/download/${encodeURIComponent(e)}/${encodeURIComponent(s)}`}}_parseMxcUrl(e){const t="mxc://";return e.startsWith(t)?e.substr(6).split("/",2):void 0}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 decryptAttachment(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,null==(s=e.info)?void 0:s.mimetype,t)}}class Request{constructor(e,t){this.methodName=e,this.args=t,this._responsePromise=new Promise(((e,t)=>{this.responseResolve=e,this.responseReject=t}))}abort(){var e;this._requestResult?this._requestResult.abort():(this.responseReject(new AbortError),null==(e=this.responseCodeReject)||e.call(this,new AbortError))}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 t,s,i;this._requestResult=e;const r=await(null==(t=this._requestResult)?void 0:t.response());this.responseResolve(r);const n=await(null==(s=this._requestResult)?void 0:s.responseCode());null==(i=this.responseCodeResolve)||i.call(this,n)}get requestResult(){return this._requestResult}}class HomeServerApiWrapper{constructor(e){this._scheduler=e}}for(const e of Object.getOwnPropertyNames(HomeServerApi.prototype))"constructor"===e||e.startsWith("_")||(HomeServerApiWrapper.prototype[e]=function(...t){return this._scheduler._hsApiRequest(e,t)});class RequestScheduler{constructor({hsApi:e,clock:t}){this._requests=new Set,this._stopped=!1,this._wrapper=new HomeServerApiWrapper(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 Request(e,t);return this._doSend(s),s}async _doSend(e){this._requests.add(e);try{let t;for(;!this._stopped;)try{const t=this._hsApi[e.methodName].apply(this._hsApi,e.args);return void await e.setRequestResult(t)}catch(s){if(!(s instanceof HomeServerError&&"M_LIMIT_EXCEEDED"===s.errcode))return void e.responseReject(s);Number.isSafeInteger(s.retry_after_ms)?await this._clock.createTimeout(s.retry_after_ms).elapsed():(t||(t=new ExponentialRetryDelay(this._clock.createTimeout)),await t.waitForRetry())}this._stopped&&e.abort()}finally{this._requests.delete(e)}}}const INCREMENTAL_TIMEOUT=3e4,SyncStatus=createEnum("InitialSync","CatchupSync","Syncing","Stopped");function timelineIsEmpty(e){var t;try{const s=null==(t=null==e?void 0:e.timeline)?void 0:t.events;return Array.isArray(s)&&0===s.length}catch(e){return!0}}class Sync{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 ObservableValue$1(SyncStatus.Stopped),this._error=null}get status(){return this._status}get error(){return this._error}start(){if(this._status.get()!==SyncStatus.Stopped)return;this._error=null;let e=this._session.syncToken;e?this._status.set(SyncStatus.CatchupSync):this._status.set(SyncStatus.InitialSync),this._syncLoop(e)}async _syncLoop(e){for(;this._status.get()!==SyncStatus.Stopped;){let t,s,i=this._status.get()===SyncStatus.CatchupSync||this._status.get()===SyncStatus.InitialSync;await this._logger.run("sync",(async i=>{i.set("token",e),i.set("status",this._status.get());try{const r=this._status.get()===SyncStatus.Syncing?3e4:0,n=await this._syncRequest(e,r,i);e=n.syncToken,t=n.roomStates,s=n.sessionChanges,this._status.get()!==SyncStatus.Syncing&&n.hadToDeviceMessages?this._status.set(SyncStatus.CatchupSync):this._status.set(SyncStatus.Syncing)}catch(e){if("ConnectionError"===e.name&&e.isTimeout)return;this._error=e,"AbortError"!==e.name&&(i.error=e,i.logLevel=i.level.Fatal),i.set("stopping",!0),this._status.set(SyncStatus.Stopped)}this._status.get()!==SyncStatus.Stopped&&await i.wrap("afterSyncCompleted",(e=>this._runAfterSyncCompleted(s,t,e)))}),this._logger.level.Info,((e,t)=>t.durationWithoutType("network")>=2e3||t.error||i?e.minLevel(t.level.Detail):e.minLevel(t.level.Info)))}}async _runAfterSyncCompleted(e,t,s){const i=this._status.get()===SyncStatus.CatchupSync,r=(async()=>{try{await s.wrap("session",(t=>this._session.afterSyncCompleted(e,i,t)))}catch(e){}})(),n=t.map((async e=>{try{await e.room.afterSyncCompleted(e.changes,s)}catch(e){}}));await Promise.all(n.concat(r))}async _syncRequest(e,t,s){var i;let{syncFilterId:r}=this._session;if("string"!=typeof r)try{this._currentRequest=this._hsApi.createFilter(this._session.user.id,{room:{state:{lazy_load_members:!0}}},{log:s}),r=(await this._currentRequest.response()).filter_id}catch(e){s.log("Sync filters aren't available, falling back to no filter"),r="filteringNotAvailable"}const n=t+8e4;this._currentRequest=this._hsApi.sync(e,"filteringNotAvailable"===r?void 0:r,t,{timeout:n,log:s});const o=await this._currentRequest.response(),a=!e,l=new SessionSyncProcessState,c=this._parseInvites(o.rooms),{roomStates:d,archivedRoomStates:h}=await this._parseRoomsResponse(o.rooms,c,a,s);try{l.lock=await s.wrap("obtainSyncLock",(()=>this._session.obtainSyncLock(o))),await s.wrap("prepare",(e=>this._prepareSync(l,d,o,e))),await s.wrap("afterPrepareSync",(e=>Promise.all(d.map((t=>t.room.afterPrepareSync(t.preparation,e)))))),await s.wrap("write",(async e=>this._writeSync(l,c,d,h,o,r,a,e)))}finally{l.dispose()}s.wrap("after",(e=>this._afterSync(l,c,d,h,e)));const u=null==(i=o.to_device)?void 0:i.events;return{syncToken:o.next_batch,roomStates:d,sessionChanges:l.changes,hadToDeviceMessages:Array.isArray(u)&&u.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 r,n;const o=await this._openPrepareSyncTxn();e.preparation=await i.wrap("session",(t=>this._session.prepareSync(s,e.lock,o,t)));const a=null==(r=e.preparation)?void 0:r.newKeysByRoom;if(a){const{hasOwnProperty:e}=Object.prototype;for(const i of a.keys()){if(!((null==(n=s.rooms)?void 0:n.join)&&e.call(s.rooms.join,i))){let e=this._session.rooms.get(i);e&&t.push(new RoomSyncProcessState(e,!1,{},e.membership))}}}await Promise.all(t.map((async e=>{const t=null==a?void 0:a.get(e.room.id);e.preparation=await i.wrap("room",(async s=>(e.isNewRoom&&await e.room.load(null,o,s),e.room.prepareSync(e.roomResponse,e.membership,t,o,s))),i.level.Detail)}))),await o.complete()}async _writeSync(e,t,s,i,r,n,o,a){const l=await this._openSyncTxn();try{e.changes=await a.wrap("session",(t=>this._session.writeSync(r,n,e.preparation,l,t))),await Promise.all(t.map((async e=>{e.changes=await a.wrap("invite",(t=>e.invite.writeSync(e.membership,e.roomResponse,l,t)))}))),await Promise.all(s.map((async e=>{e.changes=await a.wrap("room",(t=>e.room.writeSync(e.roomResponse,o,e.preparation,l,t)))}))),await Promise.all(i.map((async e=>{var t;const s=null==(t=e.roomState)?void 0:t.summaryChanges;e.changes=await a.wrap("archivedRoom",(t=>e.archivedRoom.writeSync(s,e.roomResponse,e.membership,l,t)))})))}catch(e){throw l.abort(a),l.getCause(e)}await l.complete(a)}_afterSync(e,t,s,i,r){r.wrap("session",(t=>this._session.afterSync(e.changes,t)),r.level.Detail);for(let e of i)r.wrap("archivedRoom",(t=>{e.archivedRoom.afterSync(e.changes,t),e.archivedRoom.release()}),r.level.Detail);for(let e of s)r.wrap("room",(t=>e.room.afterSync(e.changes,t)),r.level.Detail);for(let e of t)r.wrap("invite",(t=>e.invite.afterSync(e.changes,t)),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=[],n=[];if(e){const o=["join","leave"];for(const a of o){const o=e[a];if(o)for(const[e,l]of Object.entries(o)){if(s&&timelineIsEmpty(l))continue;const o=this._session.invites.get(e);o&&t.push(new InviteSyncProcessState(o,!1,null,a));const c=this._createRoomSyncState(e,l,a,s);c&&r.push(c);const d=await this._createArchivedRoomSyncState(e,c,l,a,s,i);d&&n.push(d)}}}return{roomStates:r,archivedRoomStates:n}}_createRoomSyncState(e,t,s,i){let r=!1,n=this._session.rooms.get(e);if(!n&&("join"===s||i&&"leave"===s)&&(n=this._session.createJoinedRoom(e),r=!0),n)return new RoomSyncProcessState(n,r,t,s)}async _createArchivedRoomSyncState(e,t,s,i,r,n){let o;if((null==t?void 0:t.shouldAdd)&&!r?o=this._session.createOrGetArchivedRoomForSync(e):"leave"===i&&(o=t?this._session.createOrGetArchivedRoomForSync(e):await this._session.loadArchivedRoom(e,n)),o)return new ArchivedRoomSyncProcessState(o,t,s,i)}_parseInvites(e){const t=[];if(null==e?void 0:e.invite)for(const[s,i]of Object.entries(e.invite)){let e=this._session.invites.get(s),r=!1;e||(e=this._session.createInvite(s),r=!0),t.push(new InviteSyncProcessState(e,r,i,"invite"))}return t}stop(){this._status.get()!==SyncStatus.Stopped&&(this._status.set(SyncStatus.Stopped),this._currentRequest&&(this._currentRequest.abort(),this._currentRequest=null))}}class SessionSyncProcessState{constructor(){this.lock=null,this.preparation=null,this.changes=null}dispose(){var e;null==(e=this.lock)||e.release()}}class RoomSyncProcessState{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&&"join"===this.membership}get shouldRemove(){return!this.isNewRoom&&"join"!==this.membership}get summaryChanges(){var e;return null==(e=this.changes)?void 0:e.summaryChanges}}class ArchivedRoomSyncProcessState{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)&&"leave"===this.membership}get shouldRemove(){return"join"===this.membership}}class InviteSyncProcessState{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"invite"!==this.membership}}function applyTimelineEntries(e,t,s,i,r){return t.length&&(e=t.reduce(((e,t)=>processTimelineEvent(e,t,s,i,r)),e)),e}function applySyncResponse(e,t,s,i){t.summary&&(e=updateSummary(e,t.summary)),s!==e.membership&&((e=e.cloneIfNeeded()).membership=s),t.account_data&&(e=t.account_data.events.reduce(processRoomAccountData,e)),iterateResponseStateEvents(t,(t=>{e=processStateEvent(e,t,i)}));const r=t.unread_notifications;return r&&(e=processNotificationCounts(e,r)),e}function processNotificationCounts(e,t){const s=t.highlight_count||0;s!==e.highlightCount&&((e=e.cloneIfNeeded()).highlightCount=s);const i=t.notification_count;return i!==e.notificationCount&&((e=e.cloneIfNeeded()).notificationCount=i),e}function processRoomAccountData(e,t){var s;if("m.tag"===(null==t?void 0:t.type)){let i=null==(s=null==t?void 0:t.content)?void 0:s.tags;i&&!Array.isArray(i)&&"object"==typeof i||(i=null),(e=e.cloneIfNeeded()).tags=i}return e}function processStateEvent(e,t,s){var i,r,n,o,a;if("m.room.create"===t.type)(e=e.cloneIfNeeded()).lastMessageTimestamp=t.origin_server_ts,e.type=null!=(r=null==(i=t.content)?void 0:i.type)?r:null;else if("m.room.encryption"===t.type){const s=null==(n=t.content)?void 0:n.algorithm;e.encryption||s!==MEGOLM_ALGORITHM||((e=e.cloneIfNeeded()).encryption=t.content)}else if("m.room.name"===t.type){const s=null==(o=t.content)?void 0:o.name;s!==e.name&&((e=e.cloneIfNeeded()).name=s)}else if("m.room.avatar"===t.type){const s=null==(a=t.content)?void 0:a.url;s!==e.avatarUrl&&((e=e.cloneIfNeeded()).avatarUrl=s)}else if("m.room.canonical_alias"===t.type){const s=t.content;(e=e.cloneIfNeeded()).canonicalAlias=s.alias}else if("m.room.member"===t.type){const i=t.content;if(!0!==i.is_direct||"invite"!==i.membership||e.isDirectMessage)"leave"===i.membership&&e.isDirectMessage&&e.dmUserId===t.state_key&&((e=e.cloneIfNeeded()).isDirectMessage=!1,e.dmUserId=null);else{let i;t.sender===s?i=t.state_key:t.state_key===s&&(i=t.sender),i&&((e=e.cloneIfNeeded()).isDirectMessage=!0,e.dmUserId=i)}}return e}function processTimelineEvent(e,t,s,i,r){return"m.room.message"===t.eventType&&((!e.lastMessageTimestamp||t.timestamp>e.lastMessageTimestamp)&&((e=e.cloneIfNeeded()).lastMessageTimestamp=t.timestamp),!s&&t.sender!==r&&i&&((e=e.cloneIfNeeded()).isUnread=!0)),e}function updateSummary(e,t){const s=t["m.heroes"],i=t["m.joined_member_count"],r=t["m.invited_member_count"];return s&&Array.isArray(s)&&((e=e.cloneIfNeeded()).heroes=s),Number.isInteger(r)&&((e=e.cloneIfNeeded()).inviteCount=r),Number.isInteger(i)&&((e=e.cloneIfNeeded()).joinCount=i),e}class SummaryData{constructor(e,t){this.roomId=e?e.roomId:t,this.name=e?e.name:null,this.type=e?e.type:null,this.lastMessageTimestamp=e?e.lastMessageTimestamp:null,this.isUnread=!!e&&e.isUnread,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,this.isTrackingMembers=!!e&&e.isTrackingMembers,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,this.dmUserId=e?e.dmUserId:null,this.cloned=!!e}changedKeys(e){return Object.getOwnPropertyNames(this).filter((t=>"cloned"!==t&&this[t]!==e[t]))}cloneIfNeeded(){return this.cloned?this:new SummaryData(this)}serialize(){return Object.entries(this).reduce(((e,[t,s])=>("cloned"!==t&&null!==s&&(e[t]=s),e)),{})}applyTimelineEntries(e,t,s,i){return applyTimelineEntries(this,e,t,s,i)}applySyncResponse(e,t,s){return applySyncResponse(this,e,t,s)}get needsHeroes(){return!this.name&&!this.canonicalAlias&&this.heroes&&this.heroes.length>0}isNewJoin(e){return"join"===this.membership&&"join"!==e.membership}}class RoomSummary{constructor(e){this._data=null,this.applyChanges(new SummaryData(null,e))}get data(){return this._data}writeClearUnread(e){const t=new SummaryData(this._data);return t.isUnread=!1,t.notificationCount=0,t.highlightCount=0,e.roomSummary.set(t.serialize()),t}writeHasFetchedMembers(e,t){const s=new SummaryData(this._data);return s.hasFetchedMembers=e,t.roomSummary.set(s.serialize()),s}writeIsTrackingMembers(e,t){const s=new SummaryData(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(e){throw s.abort(),e}return await s.complete(),this.applyChanges(e),!0}applyChanges(e){this._data=e,this._data.cloned=!1}async load(e){this.applyChanges(new SummaryData(e))}}const PENDING_FRAGMENT_ID=Number.MAX_SAFE_INTEGER;class BaseEntry{constructor(e){this._fragmentIdComparer=e}compare(e){return this.fragmentId===e.fragmentId?this.entryIndex-e.entryIndex:this.fragmentId===PENDING_FRAGMENT_ID?1:e.fragmentId===PENDING_FRAGMENT_ID?-1:this._fragmentIdComparer.compare(this.fragmentId,e.fragmentId)}asEventKey(){return new EventKey(this.fragmentId,this.entryIndex)}}const REACTION_TYPE="m.reaction",ANNOTATION_RELATION_TYPE="m.annotation";function createAnnotation(e,t){return{"m.relates_to":{event_id:e,key:t,rel_type:"m.annotation"}}}function getRelationTarget(e){var t;return e.event_id||(null==(t=e["m.in_reply_to"])?void 0:t.event_id)}function setRelationTarget(e,t){void 0!==e.event_id?e.event_id=t:e["m.in_reply_to"]&&(e["m.in_reply_to"].event_id=t)}function getRelatedEventId(e){if(e.type===REDACTION_TYPE)return e.redacts;{const t=getRelation(e);if(t)return getRelationTarget(t)}return null}function getRelationFromContent(e){return null==e?void 0:e["m.relates_to"]}function getRelation(e){return getRelationFromContent(e.content)}class PendingAnnotation{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-1!==t&&(this._entries.splice(t,1),!0)}get willAnnotate(){const e=this._entries.reduce(((e,t)=>!e||t.pendingEvent.queueIndex>e.pendingEvent.queueIndex?t:e),null);return!!e&&!e.isRedaction}get isEmpty(){return 0===this._entries.length}}function htmlEscape(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function fallbackForNonTextualMessage(e){switch(e){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 fallbackPrefix(e){return"m.emote"===e?"* ":""}function _createReplyContent(e,t,s,i){return{msgtype:t,body:s,format:"org.matrix.custom.html",formatted_body:i,"m.relates_to":{"m.in_reply_to":{event_id:e}}}}function createReplyContent(e,t,s){const i=fallbackForNonTextualMessage(e.content.msgtype),r=fallbackPrefix(e.content.msgtype),n=e.sender,o=`<mx-reply><blockquote>In reply to ${r}<a href="https://matrix.to/#/${n}">${e.displayName||n}</a><br />${i||e.content.formatted_body||e.content.body&&htmlEscape(e.content.body)||""}</blockquote></mx-reply>`,a=(i||e.content.body||"").split("\n");a[0]=`> ${r}<${n}> ${a[0]}`;const l=a.join("\n> ")+"\n\n"+s,c=o+htmlEscape(s);return _createReplyContent(e.id,t,l,c)}class BaseEventEntry extends BaseEntry{constructor(e){super(e),this._pendingRedactions=null,this._pendingAnnotations=null,this._contextEntry=null,this._contextForEntries=null}get isReply(){var e;return!!(null==(e=this.relation)?void 0:e["m.in_reply_to"])}get isRedacting(){return!!this._pendingRedactions}get isRedacted(){return this.isRedacting}get isRedaction(){return this.eventType===REDACTION_TYPE}get redactionReason(){var e;return this._pendingRedactions?null==(e=this._pendingRedactions[0].content)?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===REDACTION_TYPE&&e.isRelatedToId(this.id)){if(this._pendingRedactions||(this._pendingRedactions=[]),this._pendingRedactions.push(e),1===this._pendingRedactions.length)return"isRedacted"}else{const t=e.redactingEntry||e;if(t.isRelatedToId(this.id)&&"m.annotation"===t.relation.rel_type&&this._addPendingAnnotation(e))return"pendingAnnotations"}}removeLocalRelation(e){var t;if(e.eventType===REDACTION_TYPE&&e.isRelatedToId(this.id)&&this._pendingRedactions){const t=this._pendingRedactions.length;if(this._pendingRedactions=this._pendingRedactions.filter((t=>t!==e)),0===this._pendingRedactions.length&&(this._pendingRedactions=null,0!==t))return"isRedacted"}else{const s=e.redactingEntry||e;if(s.isRelatedToId(this.id)&&"m.annotation"===(null==(t=s.relation)?void 0:t.rel_type)&&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 PendingAnnotation,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),0===this._pendingAnnotations.size&&(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 createAnnotation(this.id,e)}createReplyContent(e,t){return createReplyContent(this,e,t)}isRelatedToId(e){return e&&this.relatedEventId===e}haveAnnotation(e){var t,s,i;const r=(null==(s=null==(t=this.annotations)?void 0:t[e])?void 0:s.me)||!1,n=null==(i=this.pendingAnnotations)?void 0:i.get(e),o=(null==n?void 0:n.willAnnotate)||!1;return r&&(!n||o)||!r&&o}get relation(){return getRelationFromContent(this.content)}get pendingAnnotations(){return this._pendingAnnotations}get annotations(){return null}}class PendingEventEntry extends BaseEventEntry{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 PENDING_FRAGMENT_ID}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 null==(e=this._member)?void 0:e.userId}get displayName(){var e;return null==(e=this._member)?void 0:e.name}get avatarUrl(){var e;return null==(e=this._member)?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)||super.isRelatedToId(e)}get relatedEventId(){return this._pendingEvent.relatedEventId}get redactingEntry(){return this._redactingEntry}get contextEventId(){var e;return this.isReply?null!=(e=this._pendingEvent.relatedEventId)?e:this._pendingEvent.relatedTxnId:null}}const SendStatus=createEnum("Waiting","EncryptingAttachments","UploadingAttachments","Encrypting","Sending","Sent","Error"),unencryptedContentFields=["m.relates_to"];class PendingEvent{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=SendStatus.Waiting,this._sendRequest=null,this._attachmentsTotalBytes=0,this._attachments&&(this._attachmentsTotalBytes=Object.values(this._attachments).reduce(((e,t)=>e+t.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=getRelationFromContent(this.content);return e?getRelationTarget(e):this._data.relatedEventId}setRelatedEventId(e){const t=getRelationFromContent(this.content);t?setRelationTarget(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=SendStatus.Encrypting,this._emitUpdate("status")}get contentForEncryption(){const e=Object.assign({},this._data.content);for(const t of unencryptedContentFields)delete e[t];return e}_preserveContentFields(e){const t=this._data.content;for(const s of unencryptedContentFields)void 0!==t[s]&&(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=SendStatus.Error,this._error=e,this._emitUpdate("status")}setWaiting(){this._status=SendStatus.Waiting,this._emitUpdate("status")}get status(){return this._status}get error(){return this._error}get hasStartedSending(){return this._status===SendStatus.Sending||this._status===SendStatus.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=SendStatus.EncryptingAttachments,this._emitUpdate("status");for(const e of Object.values(this._attachments))if(await t.wrap("encrypt",(()=>(t.set("size",e.size),e.encrypt()))),this.aborted)throw new AbortError}this._status=SendStatus.UploadingAttachments,this._emitUpdate("status");const s=Object.entries(this._attachments);s.sort((([,e],[,t])=>e.size-t.size));for(const[i,r]of s)await t.wrap("upload",(t=>(t.set("size",r.size),r.upload(e,(()=>{this._emitUpdate("attachmentsSentBytes")}),t)))),r.applyToContent(i,this.content);this._data.needsUpload=!1}async abort(){var e;if(!this._aborted){if(this._aborted=!0,this._attachments)for(const e of Object.values(this._attachments))e.abort();null==(e=this._sendRequest)||e.abort(),await this._removeFromQueueCallback()}}get aborted(){return this._aborted}async send(e,t){this._status=SendStatus.Sending,this._emitUpdate("status");const s=this._data.encryptedEventType||this._data.eventType,i=this._data.encryptedContent||this._data.content;this._sendRequest=s===REDACTION_TYPE?e.redact(this.roomId,this._data.relatedEventId,this.txnId,i,{log:t}):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,t.set("id",this._data.remoteId),this._status=SendStatus.Sent,this._emitUpdate("status")}dispose(){if(this._attachments)for(const e of Object.values(this._attachments))e.dispose()}}class EventEntry extends BaseEventEntry{constructor(e,t){super(t),this._eventEntry=e,this._decryptionError=null,this._decryptionResult=null}clone(){const e=new EventEntry(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(null==(t=null==(e=this._decryptionResult)?void 0:e.event)?void 0:t.content)||this._eventEntry.event.content}get prevContent(){return getPrevContentFromStateEvent(this._eventEntry.event)}get eventType(){var e,t;return(null==(t=null==(e=this._decryptionResult)?void 0:e.event)?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"m.room.encrypted"===this._eventEntry.event.type}get isDecrypted(){var e;return!!(null==(e=this._decryptionResult)?void 0:e.event)}get isVerified(){var e;return this.isEncrypted&&(null==(e=this._decryptionResult)?void 0:e.isVerified)}get isUnverified(){var e;return this.isEncrypted&&(null==(e=this._decryptionResult)?void 0:e.isUnverified)}setDecryptionError(e){this._decryptionError=e}get decryptionError(){return this._decryptionError}get relatedEventId(){return getRelatedEventId(this.event)}get isRedacted(){return super.isRedacted||isRedacted(this._eventEntry.event)}get redactionReason(){var e,t;const s=null==(e=this._eventEntry.event.unsigned)?void 0:e.redacted_because;return s?null==(t=s.content)?void 0:t.reason:super.redactionReason}get annotations(){return this._eventEntry.annotations}get relation(){const e=this._eventEntry.event.content;return e&&getRelationFromContent(e)||getRelationFromContent(this.content)}get contextEventId(){return this.isReply?this.relatedEventId:null}}function isValidFragmentId(e){return"number"==typeof e}const _REDACT_KEEP_KEY_MAP=["event_id","type","room_id","user_id","sender","state_key","prev_state","content","unsigned","origin_server_ts"].reduce((function(e,t){return e[t]=1,e}),{}),_REDACT_KEEP_CONTENT_MAP={"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 redactEvent(e,t){for(const e of Object.keys(t))_REDACT_KEEP_KEY_MAP[e]||delete t[e];const{content:s}=t,i=_REDACT_KEEP_CONTENT_MAP[t.type];for(const e of Object.keys(s))(null==i?void 0:i[e])||delete s[e];t.unsigned=t.unsigned||{},t.unsigned.redacted_because=e}function findBackwardSiblingFragments(e,t){const s=[];for(;isValidFragmentId(e.previousId);){const i=t.get(e.previousId);if(!i)break;if(i.nextId!==e.id)throw new Error(`Previous fragment ${i.id} doesn't point back to ${e.id}`);t.delete(e.previousId),s.unshift(i),e=i}return s}function findForwardSiblingFragments(e,t){const s=[];for(;isValidFragmentId(e.nextId);){const i=t.get(e.nextId);if(!i)break;if(i.previousId!==e.id)throw new Error(`Next fragment ${i.id} doesn't point back to ${e.id}`);t.delete(e.nextId),s.push(i),e=i}return s}function createIslands(e){const t=new Map;for(let s of e)t.set(s.id,s);const s=[];for(;t.size;){const e=t.values().next().value;t.delete(e.id);const i=findBackwardSiblingFragments(e,t),r=findForwardSiblingFragments(e,t),n=i.concat(e,r);s.push(n)}return s.map((e=>new Island(e)))}class Fragment{constructor(e,t,s){this.id=e,this.previousId=t,this.nextId=s}}class Island{constructor(e){this._idToSortIndex=new Map,e.forEach(((e,t)=>{this._idToSortIndex.set(e.id,t)}))}compare(e,t){const s=this._idToSortIndex.get(e);if(void 0===s)throw new Error(`first id ${e} isn't part of this island`);const i=this._idToSortIndex.get(t);if(void 0===i)throw new Error(`second id ${t} isn't part of this island`);return s-i}get fragmentIds(){return this._idToSortIndex.keys()}}class CompareError extends Error{get name(){return"CompareError"}}class FragmentIdComparer{constructor(e){this._fragmentsById=e.reduce(((e,t)=>(e.set(t.id,t),e)),new Map),this.rebuild(e)}_getIsland(e){const t=this._idToIsland.get(e);if(void 0===t)throw new CompareError(`Unknown fragment id ${e}`);return t}compare(e,t){if(e===t)return 0;const s=this._getIsland(e);if(s!==this._getIsland(t))throw new CompareError(`${e} and ${t} are on different islands, can't tell order`);return s.compare(e,t)}rebuild(e){const t=createIslands(e);this._idToIsland=new Map;for(let e of t)for(let t of e.fragmentIds)this._idToIsland.set(t,e)}add(e){const t=new Fragment(e.id,e.previousId,e.nextId);this._fragmentsById.set(e.id,t),this.rebuild(this._fragmentsById.values())}append(e,t){const s=new Fragment(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 Fragment(e,null,t),i=this._fragmentsById.get(t);i&&(i.previousId=e),this._fragmentsById.set(e,s),this.rebuild(this._fragmentsById.values())}}class RelationWriter{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=getRelation(e.event);r&&r.rel_type&&t.timelineRelations.add(this._roomId,r.event_id,r.rel_type,e.id);const n=await t.timelineEvents.getByEventId(this._roomId,i);if(n){const i=await this._applyRelation(e,n,t,s);if(i)return i.map((e=>(t.timelineEvents.update(e),new EventEntry(e,this._fragmentIdComparer))))}}return null}async writeGapRelation(e,t,s,i){const r=new EventEntry(e,this._fragmentIdComparer),n=await this.writeRelation(r,s,i);if(t.isBackward&&!isRedacted(e.event)){const t=await s.timelineRelations.getAllForTarget(this._roomId,r.id);if(t.length)for(const r of t){const t=await s.timelineEvents.getByEventId(this._roomId,r.sourceEventId);if(t){const r=new EventEntry(t,this._fragmentIdComparer);await this._applyRelation(r,e,s,i)}}}return n}async _applyRelation(e,t,s,i){if(e.eventType===REDACTION_TYPE)return i.wrap("redact",(async i=>{const r=t.event,n=getRelation(r);if(this._applyRedaction(e.event,t,s,i)){const e=[t];if(n){const t=await this._reaggregateRelation(r,n,s,i);t&&e.push(t)}return e}return null}));{const s=getRelation(e.event);if(s&&!isRedacted(t.event)){if("m.annotation"===s.rel_type){if(i.wrap("react",(s=>this._aggregateAnnotation(e.event,t,s))))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 n=getRelation(r);return n&&n.rel_type&&s.timelineRelations.remove(this._roomId,n.event_id,n.rel_type,r.event_id),s.timelineRelations.removeAllForTarget(this._roomId,r.event_id),redactEvent(e,r),delete t.annotations,!0}_aggregateAnnotation(e,t){const s=getRelation(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 n=e.sender===this._ownUserId;return r.me=r.me||n,r.count+=1,r.firstTimestamp=Math.min(r.firstTimestamp,e.origin_server_ts),!0}async _reaggregateRelation(e,t,s,i){return"m.annotation"===t.rel_type?i.wrap("reaggregate annotations",(e=>this._reaggregateAnnotation(t.event_id,t.key,s,e))):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 n=await s.timelineRelations.getForTargetAndType(this._roomId,e,"m.annotation");return i.set("relations",n.length),delete r.annotations[t],isObjectEmpty(r.annotations)&&delete r.annotations,await Promise.all(n.map((async e=>{const n=await s.timelineEvents.getByEventId(this._roomId,e.sourceEventId);n||i.log({l:"missing annotation",id:e.sourceEventId}),getRelation(n.event).key===t&&this._aggregateAnnotation(n.event,r,i)}))),r}}function isObjectEmpty(e){for(const t in e)if(e.hasOwnProperty(t))return!1;return!0}class Direction{constructor(e){this.isForward=e}get isBackward(){return!this.isForward}asApiString(){return this.isForward?"f":"b"}reverse(){return this.isForward?Direction.Backward:Direction.Forward}static get Forward(){return _forward}static get Backward(){return _backward}}const _forward=new Direction(!0),_backward=new Direction(!1);class FragmentBoundaryEntry extends BaseEntry{constructor(e,t,s){super(s),this._fragment=e,this._isFragmentStart=t}static start(e,t){return new FragmentBoundaryEntry(e,!0,t)}static end(e,t){return new FragmentBoundaryEntry(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?KeyLimits.minStorageKey:KeyLimits.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 isValidFragmentId(this.linkedFragmentId)}get direction(){return this.started?Direction.Backward:Direction.Forward}withUpdatedFragment(e){return new FragmentBoundaryEntry(e,this._isFragmentStart,this._fragmentIdComparer)}createNeighbourEntry(e){return new FragmentBoundaryEntry(e,!this._isFragmentStart,this._fragmentIdComparer)}addLocalRelation(){}removeLocalRelation(){}}function deduplicateEvents(e){const t=new Set;return e.filter((e=>!t.has(e.event_id)&&(t.add(e.event_id),!0)))}class SyncWriter{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[t]=await e.timelineEvents.lastEvents(this._roomId,s.id,1),i=t?t.eventIndex:EventKey.defaultLiveKey.eventIndex;this._lastLiveKey=new EventKey(s.id,i)}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 s={roomId:this._roomId,id:EventKey.defaultLiveKey.fragmentId,previousId:null,nextId:null,previousToken:t,nextToken:null};return e.timelineFragments.add(s),this._fragmentIdComparer.add(s),s}}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 n={roomId:this._roomId,id:t,previousId:e,nextId:null,previousToken:s,nextToken:null};return i.timelineFragments.add(n),this._fragmentIdComparer.append(t,e),{oldFragment:r,newFragment:n}}async _ensureLiveFragment(e,t,s,i,r){if(e){if(s.limited){const n=e.fragmentId;e=e.nextFragmentKey();const{oldFragment:o,newFragment:a}=await this._replaceLiveFragment(n,e.fragmentId,s.prev_batch,i);t.push(FragmentBoundaryEntry.end(o,this._fragmentIdComparer)),t.push(FragmentBoundaryEntry.start(a,this._fragmentIdComparer)),r.log({l:"live fragment",limited:!0,id:e.fragmentId})}}else{let n=await this._createLiveFragment(i,s.prev_batch);e=new EventKey(n.id,EventKey.defaultLiveKey.eventIndex),t.push(FragmentBoundaryEntry.start(n,this._fragmentIdComparer)),r.log({l:"live fragment",first:!0,id:e.fragmentId})}return e}async _writeStateEvents(e,t,s){let i=0;for(const s of e)s.type!==EVENT_TYPE$1&&(t.roomState.set(this._roomId,s),i+=1);s.set("stateEvents",i)}async _writeTimeline(e,t,s,i,r,n){const o=[],a=[];if(null==e?void 0:e.length){i=await this._ensureLiveFragment(i,o,t,r,n),n.set("timelineEvents",e.length);let l=0;for(const t of e){const e=createEventEntry(i=i.nextKey(),this._roomId,t);let c=await s.lookupMemberAtEvent(t.sender,t,r);c&&(e.displayName=c.displayName,e.avatarUrl=c.avatarUrl);if(!await r.timelineEvents.tryInsert(e,n))continue;const d=new EventEntry(e,this._fragmentIdComparer);o.push(d);const h=await this._relationWriter.writeRelation(d,r,n);h&&a.push(...h),"string"==typeof t.state_key&&t.type!==EVENT_TYPE$1&&(l+=1,r.roomState.set(this._roomId,t))}n.set("timelineStateEventCount",l)}return{currentKey:i,entries:o,updatedEntries:a}}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 t=r.event.event_id,{events:i}=e,n=i.findIndex((e=>e.event_id===t));if(-1!==n)return s.set("overlap_event_id",t),Object.assign({},e,{limited:!1,events:i.slice(n+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 n,{timeline:o}=e;r.set("isRejoin",t),t&&(o=await this._handleRejoinOverlap(o,i,r)),Array.isArray(null==o?void 0:o.events)&&(n=deduplicateEvents(o.events));const{state:a}=e;let l;Array.isArray(null==a?void 0:a.events)&&(l=a.events);const c=this._memberWriter.prepareMemberSync(l,n,s);l&&await this._writeStateEvents(l,i,r);const{currentKey:d,entries:h,updatedEntries:u}=await this._writeTimeline(n,o,c,this._lastLiveKey,i,r);return{entries:h,updatedEntries:u,newLiveKey:d,memberChanges:await c.write(i),memberSync:c}}afterSync(e){this._lastLiveKey=e}get lastMessageKey(){return this._lastLiveKey}}class BaseLRUCache{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(-1!==e){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),-1===s?this._entries.length>this.limit&&(s=this._entries.length-1):s+=1,-1!==s&&(this.onEvictEntry(this._entries[s]),this._entries.splice(s,1))}onEvictEntry(e){}}class LRUCache extends BaseLRUCache{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,(e=>this._keyFn(e)===t))}}class MemberWriter{constructor(e){this._roomId=e,this._cache=new LRUCache(5,(e=>e.userId))}prepareMemberSync(e,t,s){return new MemberSync(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 RoomMember(i))}if(!s||!s.equals(e))return t.roomMembers.set(e.serialize()),this._cache.set(e),new MemberChange(e,null==s?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 RoomMember(i),this._cache.set(s))}return s}}class MemberSync{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===EVENT_TYPE$1){const e=RoomMember.fromMemberEvent(this._roomId,s);e&&(t||(t=new Map),t.set(e.userId,e))}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===EVENT_TYPE$1&&!(null==t?void 0:t.has(r))){const e=RoomMember.fromMemberEvent(this._roomId,i);e&&(t||(t=new Map),t.set(e.userId,e))}}return t}async lookupMemberAtEvent(e,t,s){var i;let r;return this._timelineEvents&&(r=this._findPrecedingMemberEventInTimeline(e,t),r)?r:(r=null==(i=this._newStateMembers)?void 0:i.get(e),r||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(!(null==s?void 0:s.has(i.userId))){const s=await this._memberWriter._writeMember(i,e);if(s){!this._hasFetchedMembers&&!s.previousMembership&&(s.previousMembership=i.membership),t.set(s.userId,s)}}if(s)for(const i of s.values()){const s=await this._memberWriter._writeMember(i,e);s&&t.set(s.userId,s)}return t}_findPrecedingMemberEventInTimeline(e,t){let s=-1;for(let e=this._timelineEvents.length-1;e>=0;e--){if(this._timelineEvents[e].event_id===t.event_id){s=e;break}}for(let t=s-1;t>=0;t--){const s=this._timelineEvents[t];if(s.type===EVENT_TYPE$1&&s.state_key===e){const e=RoomMember.fromMemberEvent(this._roomId,s);if(e)return e}}}}class GapWriter{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((e=>e.event_id)),n=await s.timelineEvents.getEventKeysForIds(this._roomId,r);i.set("existingEvents",n.size);const o=t.filter((e=>!n.has(e.event_id)));let a;if(i.set("nonOverlappingEvents",o.length),e.hasLinkedFragment){i.set("linkedFragmentId",e.linkedFragmentId);for(const t of n.values())if(t.fragmentId===e.linkedFragmentId){i.set("foundLinkedFragment",!0);const t=await s.timelineFragments.get(this._roomId,e.linkedFragmentId);a=e.createNeighbourEntry(t);break}}return{nonOverlappingEvents:o,neighbourFragmentEntry:a}}async _findFragmentEdgeEventKey(e,t){const{fragmentId:s,direction:i}=e,r=await this._findFragmentEdgeEvent(s,i,t);return r?new EventKey(r.fragmentId,r.eventIndex):EventKey.defaultFragmentKey(e.fragmentId)}async _findFragmentEdgeEvent(e,t,s){if(t.isBackward){const[t]=await s.timelineEvents.firstEvents(this._roomId,e,1);return t}{const[t]=await s.timelineEvents.lastEvents(this._roomId,e,1);return t}}async _storeEvents(e,t,s,i,r,n){const o=[],a=[];let l=t;for(let t=0;t<e.length;++t){const c=e[t];l=l.nextKeyForDirection(s);const d=createEventEntry(l,this._roomId,c),h=this._findMember(c.sender,i,e,t,s);h&&(d.displayName=h.displayName,d.avatarUrl=h.avatarUrl);const u=await this._relationWriter.writeGapRelation(d,s,r,n);if(u&&a.push(...u),await r.timelineEvents.tryInsert(d,n)){directionalAppend(o,new EventEntry(d,this._fragmentIdComparer),s)}}return{entries:o,updatedEntries:a}}_findMember(e,t,s,i,r){function n(t){return t.type===EVENT_TYPE$1&&t.state_key===e}const o=r.isBackward?1:-1;for(let e=i+o;e>=0&&e<s.length;e+=o){const t=s[e];if(n(t))return RoomMember.fromMemberEvent(this._roomId,t)}for(let e=i;e>=0&&e<s.length;e-=o){const t=s[e];if(n(t))return RoomMember.fromReplacingMemberEvent(this._roomId,t)}const a=null==t?void 0:t.find(n);if(a)return RoomMember.fromMemberEvent(this._roomId,a)}async _updateFragments(e,t,s,i,r,n){const{direction:o}=e,a=[];return directionalAppend(i,e,o),t?(n.set("closedGapWith",t.fragmentId),t.token=null,e.token=null,r.timelineFragments.update(t.fragment),directionalAppend(i,t,o),a.push(e.fragment),a.push(t.fragment)):e.token=s,r.timelineFragments.update(e.fragment),a}async writeFragmentFill(e,t,s,i,r){const{fragmentId:n,direction:o}=e,{chunk:a,state:l}=t;let{end:c}=t;if(!Array.isArray(a))throw new Error("Invalid chunk in response");if("string"!=typeof c&&void 0!==c)throw new Error("Invalid end token in response");const d=await i.timelineFragments.get(this._roomId,n);if(!d)throw new Error(`Unknown fragment: ${n}`);if((e=e.withUpdatedFragment(d)).token!==s)throw new Error("The pagination token has changed locally while fetching messages.");if(0===a.length)return e.edgeReached=!0,await i.timelineFragments.update(e.fragment),{entries:[e],updatedEntries:[],fragments:[]};let h=await this._findFragmentEdgeEventKey(e,i);r.set("lastKey",h.toString());const{nonOverlappingEvents:u,neighbourFragmentEntry:m}=await this._findOverlappingEvents(e,a,i,r),{entries:p,updatedEntries:g}=await this._storeEvents(u,h,o,l,i,r);return{entries:p,updatedEntries:g,fragments:await this._updateFragments(e,m,c,p,i,r)}}}class ReaderRequest{constructor(e,t){this.decryptRequest=null,this._promise=e(this,t)}complete(){return this._promise}dispose(){this.decryptRequest&&(this.decryptRequest.dispose(),this.decryptRequest=null)}}async function readRawTimelineEntriesWithTxn(e,t,s,i,r,n){let o=[];const a=n.timelineEvents,l=n.timelineFragments;for(;o.length<i&&t;){let n;if(n=s.isForward?await a.eventsAfter(e,t,i):await a.eventsBefore(e,t,i),o=directionalConcat(o,n.map((e=>new EventEntry(e,r))),s),o.length<i){const i=await l.get(e,t.fragmentId);let n=new FragmentBoundaryEntry(i,s.isBackward,r);if(directionalAppend(o,n,s),!n.token&&n.hasLinkedFragment){const i=await l.get(e,n.linkedFragmentId);r.add(i);const a=new FragmentBoundaryEntry(i,s.isForward,r);directionalAppend(o,a,s),t=a.asEventKey()}else t=null}}return o}class TimelineReader{constructor({roomId:e,storage:t,fragmentIdComparer:s}){this._roomId=e,this._storage=t,this._fragmentIdComparer=s,this._decryptEntries=null}enableEncryption(e){this._decryptEntries=e}get readTxnStores(){const e=[this._storage.storeNames.timelineEvents,this._storage.storeNames.timelineFragments];return this._decryptEntries&&e.push(this._storage.storeNames.inboundGroupSessions),e}readFrom(e,t,s,i){return new ReaderRequest((async(i,r)=>{const n=await this._storage.readTxn(this.readTxnStores);return await this._readFrom(e,t,s,i,n,r)}),i)}readFromEnd(e,t=null,s){return new ReaderRequest((async(s,i)=>{const r=t||await this._storage.readTxn(this.readTxnStores),n=await r.timelineFragments.liveFragment(this._roomId);let o;if(n){this._fragmentIdComparer.add(n);const t=FragmentBoundaryEntry.end(n,this._fragmentIdComparer),a=t.asEventKey();o=await this._readFrom(a,Direction.Backward,e,s,r,i),o.unshift(t)}else o=[];return o}),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 e=new EventEntry(r,this._fragmentIdComparer);if(this._decryptEntries){const s=this._decryptEntries([e],i,t);await s.complete()}return e}}async _readFrom(e,t,s,i,r,n){const o=await readRawTimelineEntriesWithTxn(this._roomId,e,t,s,this._fragmentIdComparer,r);if(this._decryptEntries){i.decryptRequest=this._decryptEntries(o,r,n);try{await i.decryptRequest.complete()}finally{i.decryptRequest=null}}return o}}class NonPersistedEventEntry extends EventEntry{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 User{constructor(e){this._userId=e}get id(){return this._userId}}class Timeline{constructor({roomId:e,storage:t,closeCallback:s,fragmentIdComparer:i,pendingEvents:r,clock:n,powerLevelsObservable:o,hsApi:a}){this._roomId=e,this._storage=t,this._closeCallback=s,this._fragmentIdComparer=i,this._disposables=new Disposables,this._pendingEvents=r,this._clock=n,this._remoteEntries=new SortedArray(((e,t)=>e.compare(t))),this._ownMember=null,this._timelineReader=new TimelineReader({roomId:this._roomId,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer}),this._readerRequest=null,this._allEntries=null,this._contextEntriesNotInTimeline=new Map,this._decryptEntries=null,this._hsApi=a,this.initializePowerLevels(o)}initializePowerLevels(e){e&&(this._powerLevels=e.get(),this._disposables.track(e.subscribe((e=>this._powerLevels=e))))}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);this._ownMember=r?new RoomMember(r):RoomMember.fromUserId(this._roomId,e.id,t);const n=this._disposables.track(this._timelineReader.readFromEnd(20,i,s));try{const e=await n.complete();this._loadContextEntriesWhereNeeded(e),this._setupEntries(e)}finally{this._disposables.disposeTracked(n)}}_setupEntries(e){this._remoteEntries.setManySorted(e),this._pendingEvents?this._localEntries=new AsyncMappedList(this._pendingEvents,(e=>this._mapPendingEventToEntry(e)),((e,t)=>{e.notifyUpdate(t)}),(e=>this._applyAndEmitLocalRelationChange(e,(t=>t.removeLocalRelation(e))))):this._localEntries=new ObservableArray,this._allEntries=new ConcatList(this._remoteEntries,this._localEntries)}async _mapPendingEventToEntry(e){let t;e.eventType===REDACTION_TYPE&&(t=await this._getOrLoadEntry(e.relatedTxnId,e.relatedEventId));const s=new PendingEventEntry({pendingEvent:e,member:this._ownMember,clock:this._clock,redactingEntry:t});return this._loadContextEntriesWhereNeeded([s]),this._applyAndEmitLocalRelationChange(s,(e=>e.addLocalRelation(s))),s}_applyAndEmitLocalRelationChange(e,t){var s,i;const r=e=>{const s=t(e);return s||!1};if(this._findAndUpdateEntryById(e.pendingEvent.relatedTxnId,e.relatedEventId,r),e.redactingEntry){const t=null==(s=e.redactingEntry.pendingEvent)?void 0:s.relatedTxnId;this._findAndUpdateEntryById(t,e.redactingEntry.relatedEventId,r),null==(i=e.redactingEntry.contextForEntries)||i.forEach((e=>this._emitUpdateForEntry(e,"contextEntry")))}}_findAndUpdateEntryById(e,t,s){let i=!1;e&&(i=this._localEntries.findAndUpdate((t=>t.id===e),s)),!i&&t&&this._remoteEntries.findAndUpdate((e=>e.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,"m.annotation");for(const e of i){const i=await s.timelineEvents.getByEventId(this._roomId,e.sourceEventId);if(i&&i.event.sender===this._ownMember.userId&&getRelation(i.event).key===t){const e=new EventEntry(i,this._fragmentIdComparer);return this._addLocalRelationsToNewRemoteEntries([e]),e}}return null}updateOwnMember(e){this._ownMember=e}_addLocalRelationsToNewRemoteEntries(e){var t;if(null==(t=this._localEntries)?void 0:t.hasSubscriptions)for(const t of this._localEntries){if(t.relatedEventId){const s=e.find((e=>e.id===t.relatedEventId));null==s||s.addLocalRelation(t)}if(t.redactingEntry){const s=t.redactingEntry.relatedEventId,i=e.find((e=>e.id===s));null==i||i.addLocalRelation(t)}}}static _entryUpdater(e,t){var s;return null==(s=e.contextForEntries)||s.forEach((e=>e.setContextEntry(t))),t.updateFrom(e),t}replaceEntries(e){var t;this._addLocalRelationsToNewRemoteEntries(e);for(const s of e)try{this._remoteEntries.getAndUpdate(s,Timeline._entryUpdater);const e=this._contextEntriesNotInTimeline.get(s.id);e&&(Timeline._entryUpdater(e,s),this._contextEntriesNotInTimeline.set(s.id,s)),null==(t=s.contextForEntries)||t.forEach((e=>this._emitUpdateForEntry(e,"contextEntry")))}catch(e){if("CompareError"===e.name)continue;throw e}}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 e=this._contextEntriesNotInTimeline.get(s.relatedEventId);(null==e?void 0:e.isNonPersisted)&&(null==e?void 0:e.addLocalRelation(s))&&(null==(t=e.contextForEntries)||t.forEach((e=>this._emitUpdateForEntry(e,"contextEntry"))))}}_moveEntryToRemoteEntries(e){for(const t of e){const e=this._contextEntriesNotInTimeline.get(t.id);e&&(e.contextForEntries.forEach((e=>{e.setContextEntry(t),this._emitUpdateForEntry(e,"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((e=>e.id===s));i||(i=this._findLoadedEventById(s)),i?t.setContextEntry(i):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 null!=(t=this.getByEventId(e))?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((e=>e.type===EVENT_TYPE$1&&e.user_id===s)),r={event:t.event,displayName:i.content.displayname,avatarUrl:i.content.avatar_url},n=new NonPersistedEventEntry(r,this._fragmentIdComparer);if(this._decryptEntries){const e=this._decryptEntries([n]);await e.complete()}return n}async loadAtTop(e){if(this._disposables.isDisposed)return!0;const t=this._remoteEntries.array.find((e=>!!e.eventType));if(!t)return!0;const s=this._disposables.track(this._timelineReader.readFrom(t.asEventKey(),Direction.Backward,e));try{const t=await s.complete();return this.addEntries(t),t.length<e}finally{this._disposables.disposeTracked(s)}}async _getOrLoadEntry(e,t){var s;if(e)for(const t of this._localEntries)if(t.id===e)return t;return t?null!=(s=this.getByEventId(t))?s:await this._getEventFromStorage(t):null}getByEventId(e){for(let t=0;t<this._remoteEntries.length;t+=1){const s=this._remoteEntries.get(t);if(s.id===e)return s}return null}get entries(){return this._allEntries}get remoteEntries(){return this._remoteEntries.array}dispose(){this._closeCallback&&(this._disposables.dispose(),this._closeCallback(),this._closeCallback=null)}enableEncryption(e){this._decryptEntries=e,this._timelineReader.enableEncryption(e)}get powerLevels(){return this._powerLevels}get me(){return this._ownMember}}async function loadMembers({roomId:e,storage:t,txn:s}){s||(s=await t.readTxn([t.storeNames.roomMembers]));return(await s.roomMembers.getAll(e)).map((e=>new RoomMember(e)))}async function fetchMembers({summary:e,syncToken:t,roomId:s,hsApi:i,storage:r,setChangedMembersMap:n},o){const a=new Map;n(a);const l=await i.members(s,{at:t},{log:o}).response(),c=await r.readWriteTxn([r.storeNames.roomSummary,r.storeNames.roomMembers]);let d,h;try{d=e.writeHasFetchedMembers(!0,c);const{roomMembers:t}=c,i=l.chunk;if(!Array.isArray(i))throw new Error("malformed");o.set("members",i.length),h=await Promise.all(i.map((async e=>{const i=null==e?void 0:e.state_key;if(!i)throw new Error("malformed");const r=a.get(i);if(r)return r;{const i=RoomMember.fromMemberEvent(s,e);return i&&t.set(i.serialize()),i}})))}catch(e){throw c.abort(),e}finally{n(null)}return await c.complete(),e.applyChanges(d),h}async function fetchOrLoadMembers(e,t){const{summary:s}=e;return s.data.hasFetchedMembers?loadMembers(e):t.wrapOrRun(e.log,"fetchMembers",(t=>fetchMembers(e,t)))}async function fetchOrLoadMember(e,t){const s=await loadMember(e),{summary:i}=e;return i.data.hasFetchedMembers||s?s:t.wrapOrRun(e.log,"fetchMember",(t=>fetchMember(e,t)))}async function loadMember({roomId:e,userId:t,storage:s}){const i=await s.readTxn([s.storeNames.roomMembers]),r=await i.roomMembers.get(e,t);return r?new RoomMember(r):null}async function fetchMember({roomId:e,userId:t,hsApi:s,storage:i},r){let n;try{n=await s.state(e,"m.room.member",t,{log:r}).response()}catch(e){if("HomeServerError"===e.name&&"M_NOT_FOUND"===e.errcode)return null;throw e}const o=new RoomMember({roomId:e,userId:t,membership:n.membership,avatarUrl:n.avatar_url,displayName:n.displayname}),a=await i.readWriteTxn([i.storeNames.roomMembers]);try{a.roomMembers.set(o.serialize())}catch(e){throw a.abort(),e}return await a.complete(),o}class RetainedValue{constructor(e){this._retentionCount=1,this._freeCallback=e}retain(){this._retentionCount+=1}release(){this._retentionCount-=1,0===this._retentionCount&&this._freeCallback()}}class MemberList extends RetainedValue{constructor({members:e,closeCallback:t}){super(t),this._members=new ObservableMap;for(const t of e)this._members.add(t.userId,t)}afterSync(e){for(const[t,s]of e.entries())this._members.set(t,s.member)}get members(){return this._members}}function calculateRoomName(e,t,s){const i=t.joinCount+t.inviteCount-1;if(e.length>=i){if(e.length>1){const t=e[e.length-1];return e.slice(0,e.length-1).map((e=>e.name)).join(", ")+" and "+t.name}{const t=e[0];return t?t.name:(s.log({l:"could get get other member name",length:e.length,otherMember:!!t,otherMemberMembership:null==t?void 0:t.membership}),"Unknown DM Name")}}return e.length<i?e.map((e=>e.name)).join(", ")+` and ${i} others`:null}class Heroes{constructor(e){this._roomId=e,this._members=new Map}async calculateChanges(e,t,s){const i=new Map,r=[];for(const t of this._members.keys())-1===e.indexOf(t)&&r.push(t);for(const[s,r]of t.entries())(this._members.has(s)||-1!==e.indexOf(s))&&i.set(s,r.member);for(const t of e)if(!this._members.has(t)&&!i.has(t)){const e=await s.roomMembers.get(this._roomId,t);if(e){const t=new RoomMember(e);i.set(t.userId,t)}}return{updatedHeroMembers:i.values(),removedUserIds:r}}applyChanges({updatedHeroMembers:e,removedUserIds:t},s,i){for(const e of t)this._members.delete(e);for(const s of e)t.includes(s.userId)||this._members.set(s.userId,s);const r=Array.from(this._members.values()).sort(((e,t)=>e.name.localeCompare(t.name)));this._roomName=calculateRoomName(r,s,i)}get roomName(){return this._roomName}get roomAvatarUrl(){if(1===this._members.size)for(const e of this._members.values())return e.avatarUrl;return null}get roomAvatarColorId(){if(1===this._members.size)for(const e of this._members.keys())return e;return null}}class ObservedEventMap{constructor(e){this._map=new Map,this._notifyEmpty=e}observe(e,t=null){let s=this._map.get(e);return s||(s=new ObservedEvent(this,t,e),this._map.set(e,s)),s}updateEvents(e){for(let t=0;t<e.length;t+=1){const s=e[t],i=this._map.get(s.id);null==i||i.update(s)}}_remove(e){this._map.delete(e),0===this._map.size&&this._notifyEmpty()}}class ObservedEvent extends BaseObservableValue$1{constructor(e,t,s){super(),this._eventMap=e,this._entry=t,this._id=s,Promise.resolve().then((()=>{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 ensureLogItem(e){return e||Instance.item}const EVENT_TYPE="m.room.power_levels",STATE_DEFAULT_POWER_LEVEL=50;class PowerLevels{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&&"join"===this._membership||this.canRedact}canSendType(e){return this._myLevel>=this._getEventTypeLevel(e)}get canRedact(){return this._myLevel>=this._getActionLevel("redact")}get _myLevel(){return"join"!==this._membership?Number.MIN_SAFE_INTEGER:this.getUserLevel(this._ownUserId)}getUserLevel(e){var t,s,i,r;if(this._plEvent){let r=null==(s=null==(t=this._plEvent.content)?void 0:t.users)?void 0:s[e];if("number"!=typeof r&&(r=null==(i=this._plEvent.content)?void 0:i.users_default),"number"==typeof r)return r}else if(this._createEvent&&e===(null==(r=this._createEvent.content)?void 0:r.creator))return 100;return 0}_getActionLevel(e){var t,s;const i=null==(s=null==(t=this._plEvent)?void 0:t.content)?void 0:s[e];return"number"==typeof i?i:50}_getEventTypeLevel(e){var t,s,i,r,n;const o=null==(i=null==(s=null==(t=this._plEvent)?void 0:t.content)?void 0:s.events)?void 0:i[e];if("number"==typeof o)return o;{const e=null==(n=null==(r=this._plEvent)?void 0:r.content)?void 0:n.events_default;return"number"==typeof e?e:0}}}class ObservedStateTypeMap extends ObservableMap{constructor(e){super(),this.type=e}async load(e,t){const s=await t.roomState.getAllForType(e,this.type);for(let e=0;e<s.length;++e){const{event:t}=s[e];this.add(t.state_key,t)}}handleStateEvent(e){e.type===this.type&&this.set(e.state_key,e)}setRemoveCallback(e){this.removeCallback=e}onUnsubscribeLast(){var e;null==(e=this.removeCallback)||e.call(this)}}class ObservedStateKeyValue extends BaseObservableValue$1{constructor(e,t){super(),this.type=e,this.stateKey=t}async load(e,t){var s;this.event=null==(s=await t.roomState.get(e,this.type,this.stateKey))?void 0:s.event}handleStateEvent(e){e.type===this.type&&e.state_key===this.stateKey&&(this.event=e,this.emit(this.get()))}get(){return this.event}setRemoveCallback(e){this.removeCallback=e}onUnsubscribeLast(){var e;null==(e=this.removeCallback)||e.call(this)}}const EVENT_ENCRYPTED_TYPE$1="m.room.encrypted";class BaseRoom extends EventEmitter{constructor({roomId:e,storage:t,hsApi:s,mediaRepository:i,emitCollectionChange:r,user:n,createRoomEncryption:o,getSyncToken:a,platform:l}){super(),this._roomId=e,this._storage=t,this._hsApi=s,this._mediaRepository=i,this._summary=new RoomSummary(e),this._fragmentIdComparer=new FragmentIdComparer([]),this._emitCollectionChange=r,this._timeline=null,this._openTimelinePromise=null,this._user=n,this._changedMembersDuringSync=null,this._memberList=null,this._createRoomEncryption=o,this._roomEncryption=null,this._getSyncToken=a,this._platform=l,this._observedEvents=null,this._roomStateObservers=new Set,this._powerLevels=null,this._powerLevelLoading=null,this._observedMembers=null}async observeStateType(e,t=void 0){const s=new ObservedStateTypeMap(e);return await this._addStateObserver(s,t),s}async observeStateTypeAndKey(e,t,s=void 0){const i=new ObservedStateKeyValue(e,t);return await this._addStateObserver(i,s),i}async getStateEvent(e,t=""){return(await this._storage.readTxn(["roomState"])).roomState.get(this.id,e,t)}async _addStateObserver(e,t){t||(t=await this._storage.readTxn([this._storage.storeNames.roomState])),await e.load(this.id,t),this._roomStateObservers.add(e),e.setRemoveCallback((()=>{this._roomStateObservers.delete(e)}))}async _eventIdsToEntries(e,t){const s=[];return await Promise.all(e.map((async e=>{const i=await t.timelineEvents.getByEventId(this._roomId,e);i&&s.push(new EventEntry(i,this._fragmentIdComparer))}))),s}_getAdditionalTimelineRetryEntries(e,t){let s=this._roomEncryption.filterUndecryptedEventEntriesForKeys(this._timeline.remoteEntries,t);const i=e.reduce(((e,t)=>(e.add(t.id),e)),new Set);return s=s.filter((e=>!i.has(e.id))),s}async notifyRoomKey(e,t,s){var i;if(!this._roomEncryption)return;const r=await this._storage.readTxn([this._storage.storeNames.timelineEvents,this._storage.storeNames.inboundGroupSessions]);let n=await this._eventIdsToEntries(t,r);if(this._timeline){const t=this._getAdditionalTimelineRetryEntries(n,[e]);n=n.concat(t)}if(n.length){const e=this._decryptEntries(DecryptionSource.Retry,n,r,s);await e.complete(),null==(i=this._timeline)||i.replaceEntries(n);const t=this._summary.data.applyTimelineEntries(n,!1,!1);await this._summary.writeAndApplyData(t,this._storage)&&this._emitUpdate()}}_setEncryption(e){return!(!e||this._roomEncryption)&&(this._roomEncryption=e,this._timeline&&this._timeline.enableEncryption(this._decryptEntries.bind(this,DecryptionSource.Timeline)),!0)}_decryptEntries(e,t,s,i=null){return new DecryptionRequest((async(i,r)=>{if(s||(s=await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions])),i.cancelled)return;const n=t.filter((e=>"m.room.encrypted"===e.eventType)).map((e=>e.event));if(i.preparation=await this._roomEncryption.prepareDecryptAll(n,null,e,s),i.cancelled)return;const o=await i.preparation.decrypt();if(i.preparation=null,i.cancelled)return;const a=[this._storage.storeNames.groupSessionDecryptions],l=this._isTimelineOpen;l&&a.push(this._storage.storeNames.deviceKeys);const c=await this._storage.readWriteTxn(a);let d;try{d=await o.write(c,r),l&&await d.verifyKnownSenders(c)}catch(e){throw c.abort(),e}await c.complete(),d.applyToEntries(t),this._observedEvents&&this._observedEvents.updateEvents(t),l&&d.hasUnverifiedSenders&&r.wrapDetached("fetch unknown senders keys",(async e=>{var s,i;const r=await d.fetchAndVerifyRemainingSenders(this._hsApi,e),n=[];r.applyToEntries(t,(e=>n.push(e))),null==(s=this._timeline)||s.replaceEntries(n),null==(i=this._observedEvents)||i.updateEvents(n)}))}),ensureLogItem(i))}async _getSyncRetryDecryptEntries(e,t,s){let i=(await Promise.all(e.map((async e=>{const i=await t.getEventIdsForMissingKey(e,s);if(i)return this._eventIdsToEntries(i,s)})))).reduce(((e,t)=>t?e.concat(t):e),[]);if(this._timeline){const t=this._getAdditionalTimelineRetryEntries(i,e).map((e=>e.clone()));i=i.concat(t)}return i}async load(e,t,s){s.set("id",this.id);try{if(e&&this._summary.load(e),this._summary.data.encryption){const e=this._createRoomEncryption(this,this._summary.data.encryption);this._setEncryption(e)}if(this._summary.data.needsHeroes){this._heroes=new Heroes(this._roomId);const e=await this._heroes.calculateChanges(this._summary.data.heroes,[],t);this._heroes.applyChanges(e,this._summary.data,s)}}catch(e){throw new WrappedError(`Could not load room ${this._roomId}`,e)}}async observeMember(e){this._observedMembers||(this._observedMembers=new Map);const t=this._observedMembers.get(e);if(t)return t;const s=await fetchOrLoadMember({summary:this._summary,roomId:this._roomId,userId:e,storage:this._storage,hsApi:this._hsApi},this._platform.logger);if(!s)return null;const i=new RetainedObservableValue(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 fetchOrLoadMembers({summary:this._summary,roomId:this._roomId,hsApi:this._hsApi,storage:this._storage,txn:e,syncToken:this._getSyncToken(),setChangedMembersMap:e=>this._changedMembersDuringSync=e,log:t},this._platform.logger);return this._memberList=new MemberList({members:s,closeCallback:()=>{this._memberList=null}}),this._memberList}}fillGap(e,t,s=null){return this._platform.logger.wrapOrRun(s,"fillGap",(async s=>{if(s.set("id",this.id),s.set("fragment",e.fragmentId),s.set("dir",e.direction.asApiString()),e.edgeReached)return void s.set("edgeReached",!0);const i=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:s}).response(),r=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents,this._storage.storeNames.timelineEvents,this._storage.storeNames.timelineRelations,this._storage.storeNames.timelineFragments]);let n,o;try{n=await this._writeGapFill(i.chunk,r,s);const t=new RelationWriter({roomId:this._roomId,fragmentIdComparer:this._fragmentIdComparer,ownUserId:this._user.id}),a=new GapWriter({roomId:this._roomId,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer,relationWriter:t});o=await a.writeFragmentFill(e,i,e.token,r,s)}catch(e){throw r.abort(),e}if(await r.complete(),this._roomEncryption){const e=this._decryptEntries(DecryptionSource.Timeline,o.entries,null,s);await e.complete()}for(const e of o.fragments)this._fragmentIdComparer.add(e);n&&this._applyGapFill(n),this._timeline&&(this._timeline.replaceEntries(o.updatedEntries),this._timeline.addEntries(o.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 type(){var e;return null!=(e=this._summary.data.type)?e:void 0}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"join"===this.membership}get isLeft(){return"leave"===this.membership}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 isDirectMessage(){return this._summary.data.isDirectMessage}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 PowerLevels({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 PowerLevels({createEvent:s.event,ownUserId:this._user.id,membership:this.membership});{const e=this.membership;return new PowerLevels({ownUserId:this._user.id,membership:e})}}async observePowerLevels(){this._powerLevelLoading&&await this._powerLevelLoading;let e=this._powerLevels;if(!e){this._powerLevelLoading=this._loadPowerLevels();const t=await this._powerLevelLoading;e=new RetainedObservableValue(t,(()=>{this._powerLevels=null})),this._powerLevels=e,this._powerLevelLoading=null}return e}enableKeyBackup(e){var t;null==(t=this._roomEncryption)||t.enableKeyBackup(e),this._timeline&&e&&this._platform.logger.run("enableKeyBackup",(e=>this._roomEncryption.restoreMissingSessionsFromBackup(this._timeline.remoteEntries,e)))}get _isTimelineOpen(){return!!this._timeline}_emitUpdate(){this.emit("change"),this._emitCollectionChange(this)}openTimeline(e=null){return this._openTimelinePromise||(this._openTimelinePromise=this._platform.logger.wrapOrRun(e,"open timeline",(async e=>{if(e.set("id",this.id),this._timeline)throw new Error("not dealing with load race here for now");this._timeline=new Timeline({roomId:this.id,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer,pendingEvents:this._getPendingEvents(),closeCallback:()=>{this._timeline=null,this._openTimelinePromise=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,DecryptionSource.Timeline)),await this._timeline.load(this._user,this.membership,e)}catch(e){throw this._timeline.dispose(),e}return this._timeline}))),this._openTimelinePromise}_getPendingEvents(){return null}observeEvent(e){this._observedEvents||(this._observedEvents=new ObservedEventMap((()=>{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((e=>{s.update(e)})).catch((t=>{console.warn(`could not load event ${e} from storage`,t)})),s}async _readEventById(e){const t=new TimelineReader({roomId:this._roomId,storage:this._storage,fragmentIdComparer:this._fragmentIdComparer});return await t.readById(e)}dispose(){var e,t;null==(e=this._roomEncryption)||e.dispose(),null==(t=this._timeline)||t.dispose()}}class DecryptionRequest{constructor(e,t){this._cancelled=!1,this.preparation=null,this._promise=t.wrap("decryptEntries",(t=>e(this,t)))}complete(){return this._promise}get cancelled(){return this._cancelled}dispose(){this._cancelled=!0,this.preparation&&this.preparation.dispose()}}class SendQueue{constructor({roomId:e,storage:t,hsApi:s,pendingEvents:i}){i=i||[],this._roomId=e,this._storage=t,this._hsApi=s,this._pendingEvents=new SortedArray(((e,t)=>e.queueIndex-t.queueIndex)),this._pendingEvents.setManyUnsorted(i.map((e=>this._createPendingEvent(e)))),this._isSending=!1,this._offline=!1,this._roomEncryption=null,this._currentQueueIndex=0}_createPendingEvent(e,t=null){const s=new PendingEvent({data:e,remove:()=>this._removeEvent(s),emitUpdate:e=>this._pendingEvents.update(s,e),attachments:t});return s}enableEncryption(e){this._roomEncryption=e}_sendLoop(e){this._isSending=!0,this._sendLoopLogItem=e.runDetached("send queue flush",(async e=>{try{for(const t of this._pendingEvents)await e.wrap("send event",(async e=>{e.set("queueIndex",t.queueIndex);try{this._currentQueueIndex=t.queueIndex,await this._sendEvent(t,e)}catch(s){if(s instanceof ConnectionError)this._offline=!0,e.set("offline",!0),t.setWaiting();else{e.catch(s);"HomeServerError"===s.name&&(400===s.statusCode||403===s.statusCode||404===s.statusCode)?(e.set("remove",!0),await t.abort()):t.setError(s)}}finally{this._currentQueueIndex=0}}))}finally{this._isSending=!1,this._sendLoopLogItem=null}}))}async _sendEvent(e,t){if(e.needsUpload&&(await t.wrap("upload attachments",(t=>e.uploadAttachments(this._hsApi,t))),await this._tryUpdateEvent(e)),e.needsEncryption){e.setEncrypting();const s=e.contentForEncryption,{type:i,content:r}=await t.wrap("encrypt",(t=>this._roomEncryption.encrypt(e.eventType,s,this._hsApi,t)));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(e){throw s.abort(),e}await s.complete()}}async _resolveRemoteIdInPendingRelations(e,t,s){const i=this._pendingEvents.array.filter((s=>s.relatedTxnId===e&&s.relatedEventId!==t));for(const e of i)e.setRelatedEventId(t),await this._tryUpdateEventWithTxn(e,s);return i}async removeRemoteEchos(e,t,s){const i=[];for(const r of e){const e=r.unsigned&&r.unsigned.transaction_id;let n;if(n=e?this._pendingEvents.array.findIndex((t=>t.txnId===e)):this._pendingEvents.array.findIndex((e=>e.remoteId===r.event_id)),-1!==n){const o=this._pendingEvents.get(n),a=r.event_id;s.log({l:"removeRemoteEcho",queueIndex:o.queueIndex,remoteId:a,txnId:e}),t.pendingEvents.remove(o.roomId,o.queueIndex),i.push(o),await this._resolveRemoteIdInPendingRelations(e,a,t)}}return i}async _removeEvent(e){if(-1!==this._pendingEvents.array.indexOf(e)){const t=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);try{t.pendingEvents.remove(e.roomId,e.queueIndex)}catch(e){t.abort()}await t.complete();const s=this._pendingEvents.array.indexOf(e);-1!==s&&this._pendingEvents.remove(s)}e.dispose()}emitRemovals(e){for(const t of e){const e=this._pendingEvents.array.indexOf(t);-1!==e&&this._pendingEvents.remove(e),t.dispose()}}resumeSending(e){this._offline=!1,this._pendingEvents.length&&e.wrap("resumeSending",(e=>{e.set("id",this._roomId),e.set("pendingEvents",this._pendingEvents.length),this._isSending||this._sendLoop(e),this._sendLoopLogItem&&e.refDetached(this._sendLoopLogItem)}))}async enqueueEvent(e,t,s,i){const r=getRelationFromContent(t);let n=null;if(r){const t=getRelationTarget(r);if(isTxnId(t)&&(n=t,setRelationTarget(r,null)),"m.annotation"===r.rel_type){if(this._pendingEvents.array.some((t=>{const s=getRelationFromContent(t.content);return t.eventType===e&&s&&s.key===r.key&&(t.relatedTxnId===n||s.event_id===r.event_id)})))return void i.set("already_annotating",!0)}}await this._enqueueEvent(e,t,s,n,null,i)}async _enqueueEvent(e,t,s,i,r,n){const o=await this._createAndStoreEvent(e,t,i,r,s);this._pendingEvents.set(o),n.set("queueIndex",o.queueIndex),n.set("pendingEvents",this._pendingEvents.length),this._isSending||this._offline||this._sendLoop(n),this._sendLoopLogItem&&n.refDetached(this._sendLoopLogItem)}async enqueueRedaction(e,t,s){if(this._pendingEvents.array.some((t=>t.eventType===REDACTION_TYPE&&(t.relatedTxnId===e||t.relatedEventId===e))))return void s.set("already_redacting",!0);let i,r;if(isTxnId(e)){i=e;const t=e,n=this._pendingEvents.array.find((e=>e.txnId===t));if(n&&!n.remoteId&&n.status!==SendStatus.Sending)return s.set("remove",i),void await n.abort();if(!n)return;r=n.remoteId}else{r=e;const t=this._pendingEvents.array.find((e=>e.remoteId===r));t&&(i=t.txnId)}s.set("relatedTxnId",i),s.set("relatedEventId",r),await this._enqueueEvent(REDACTION_TYPE,{reason:t},null,i,r,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(e){throw t.abort(),e}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 n=await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);let o;try{const a=n.pendingEvents,l=await a.getMaxQueueIndex(this._roomId)||0,c=Math.max(l,this._currentQueueIndex)+1,d=e!==REDACTION_TYPE&&"m.reaction"!==e&&!!this._roomEncryption;o=this._createPendingEvent({roomId:this._roomId,queueIndex:c,eventType:e,content:t,relatedTxnId:s,relatedEventId:i,txnId:makeTxnId(),needsEncryption:d,needsUpload:!!r},r),a.add(o.data)}catch(e){throw n.abort(),e}return await n.complete(),o}dispose(){for(const e of this._pendingEvents)e.dispose()}}class AttachmentUpload{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;null==(e=this._uploadRequest)||e.abort()}get localPreview(){return this._unencryptedBlob}async encrypt(){if(this._encryptionInfo)throw new Error("already encrypted");const{info:e,blob:t}=await encryptAttachment(this._platform,this._transferredBlob);this._transferredBlob=t,this._encryptionInfo=e}async upload(e,t,s){this._uploadRequest=e.uploadAttachment(this._transferredBlob,this._filename,{uploadProgress:e=>{this._sentBytes=e,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"));setPath(`${s}info.size`,t,this._transferredBlob.size),setPath(`${s}info.mimetype`,t,this._unencryptedBlob.mimeType),this._encryptionInfo?setPath(`${s}file`,t,Object.assign(this._encryptionInfo,{mimetype:this._unencryptedBlob.mimeType,url:this._mxcUrl})):setPath(`${s}url`,t,this._mxcUrl)}dispose(){this._unencryptedBlob.dispose(),this._transferredBlob.dispose()}}function setPath(e,t,s){const i=e.split(".");let r=t;for(let e=0;e<i.length-1;e+=1){const t=i[e];r[t]||(r[t]={}),r=r[t]}r[i[i.length-1]]=s}const EVENT_ENCRYPTED_TYPE="m.room.encrypted";class Room extends BaseRoom{constructor(e){super(e),this._roomStateHandler=e.roomStateHandler;const{pendingEvents:t}=e,s=new RelationWriter({roomId:this.id,fragmentIdComparer:this._fragmentIdComparer,ownUserId:this._user.id});this._syncWriter=new SyncWriter({roomId:this.id,fragmentIdComparer:this._fragmentIdComparer,relationWriter:s,memberWriter:new MemberWriter(this.id)}),this._sendQueue=new SendQueue({roomId:this.id,storage:this._storage,hsApi:this._hsApi,pendingEvents:t})}_setEncryption(e){return!!super._setEncryption(e)&&(this._sendQueue.enableEncryption(this._roomEncryption),!0)}async prepareSync(e,t,s,i,r){var n;r.set("id",this.id),s&&r.set("newKeys",s.length);let o,a,l=this._summary.data.applySyncResponse(e,t,this._user.id),c=this._roomEncryption;if(!c&&l.encryption&&(r.set("enableEncryption",!0),c=this._createRoomEncryption(this,l.encryption)),c){let t=(null==(n=null==e?void 0:e.timeline)?void 0:n.events)||[];s&&(o=await this._getSyncRetryDecryptEntries(s,c,i),o.length&&(r.set("retry",o.length),t=t.concat(o.map((e=>e.event))))),t=t.filter((e=>"m.room.encrypted"===(null==e?void 0:e.type))),t.length&&(a=await c.prepareDecryptAll(t,s,DecryptionSource.Sync,i))}return{roomEncryption:c,summaryChanges:l,decryptPreparation:a,decryptChanges:null,retryEntries:o}}async afterPrepareSync(e,t){e.decryptPreparation&&await t.wrap("decrypt",(async t=>{t.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:n},o,a){var l;a.set("id",this.id);const c=s.isNewJoin(this._summary.data);c&&(o.roomState.removeAllForRoom(this.id),o.roomMembers.removeAllForRoom(this.id));const{entries:d,updatedEntries:h,newLiveKey:u,memberChanges:m,memberSync:p}=await a.wrap("syncWriter",(t=>this._syncWriter.writeSync(e,c,s.hasFetchedMembers,o,t)),a.level.Detail);let g,_;i&&(g=await a.wrap("decryptChanges",(e=>i.write(o,e))),a.set("decryptionResults",g.results.size),a.set("decryptionErrors",g.errors.size),this._isTimelineOpen&&await g.verifyKnownSenders(o),g.applyToEntries(d),(null==n?void 0:n.length)&&(g.applyToEntries(n),h.push(...n))),a.set("newEntries",d.length),a.set("updatedEntries",h.length),r&&(_=await r.writeSync(e,m,o,a),a.set("shouldFlushKeyShares",_.shouldFlush));const y=d.concat(h);let v,w;"join"!==(s=s.applyTimelineEntries(y,t,!this._isTimelineOpen,this._user.id)).membership?o.roomSummary.remove(this.id):s=this._summary.writeData(s,o),s&&a.set("summaryChanges",s.changedKeys(this._summary.data)),(null==s?void 0:s.needsHeroes)&&(this._heroes||(this._heroes=new Heroes(this._roomId)),v=await this._heroes.calculateChanges(s.heroes,m,o)),Array.isArray(null==(l=e.timeline)?void 0:l.events)&&(w=await this._sendQueue.removeRemoteEchos(e.timeline.events,o,a));const f=this._getPowerLevelsEvent(e);return await this._runRoomStateHandlers(e,p,o,a),{roomResponse:e,summaryChanges:s,roomEncryption:r,newEntries:d,updatedEntries:h,newLiveKey:u,removedPendingEvents:w,memberChanges:m,heroChanges:v,powerLevelsEvent:f,encryptionChanges:_,decryption:g}}afterSync(e,t){const{summaryChanges:s,newEntries:i,updatedEntries:r,newLiveKey:n,removedPendingEvents:o,memberChanges:a,powerLevelsEvent:l,heroChanges:c,roomEncryption:d,roomResponse:h,encryptionChanges:u}=e;if(t.set("id",this.id),this._syncWriter.afterSync(n),this._setEncryption(d),this._roomEncryption&&this._roomEncryption.afterSync(u),a.size){if(this._changedMembersDuringSync)for(const[e,t]of a.entries())this._changedMembersDuringSync.set(e,t.member);if(this._memberList&&this._memberList.afterSync(a),this._roomStateHandler.updateRoomMembers(this,a),this._observedMembers&&this._updateObservedMembers(a),this._timeline)for(const[e,t]of a.entries())if(e===this._user.id){this._timeline.updateOwnMember(t.member);break}}let m=!1;if(s&&(this._summary.applyChanges(s),this._summary.data.needsHeroes||(this._heroes=null),m=!0),this._heroes&&c){const e=this.name;this._heroes.applyChanges(c,this._summary.data,t),e!==this.name&&(m=!0)}l&&this._updatePowerLevels(l),m&&this._emitUpdate(),this._timeline&&(this._timeline.replaceEntries(r),this._timeline.addEntries(i)),this._observedEvents&&(this._observedEvents.updateEvents(r),this._observedEvents.updateEvents(i)),o&&this._sendQueue.emitRemovals(o),this._emitSyncRoomState(h)}_updateObservedMembers(e){for(const[t,s]of e){const e=this._observedMembers.get(t);e&&e.set(s.member)}}_getPowerLevelsEvent(e){let t;return iterateResponseStateEvents(e,(e=>{""===e.state_key&&e.type===EVENT_TYPE&&(t=e)})),t}_updatePowerLevels(e){if(this._powerLevels){const t=new PowerLevels({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 n=null==e?void 0:e.shouldFlush,o=this._isTimelineOpen&&(null==t?void 0:t.hasUnverifiedSenders);(n||o)&&await r.wrap({l:"room",id:this.id},(async e=>{const r=[];if(n&&r.push(this._roomEncryption.flushPendingRoomKeyShares(this._hsApi,null,e)),o){const n=e.wrap("verify senders",(async e=>{var r,n;const o=await t.fetchAndVerifyRemainingSenders(this._hsApi,e),a=[],l=e=>a.push(e);o.applyToEntries(s,l),o.applyToEntries(i,l),e.set("verifiedEntries",a.length),null==(r=this._timeline)||r.replaceEntries(a),null==(n=this._observedEvents)||n.updateEvents(a)}));r.push(n)}await Promise.all(r)}))}start(e,t){if(this._roomEncryption){const s=null==e?void 0:e.get("share_room_key");s&&t.wrapDetached("flush room keys",(e=>(e.set("id",this.id),this._roomEncryption.flushPendingRoomKeyShares(this._hsApi,s,e))))}this._sendQueue.resumeSending(t)}async load(e,t,s){try{await super.load(e,t,s),await this._syncWriter.load(t,s)}catch(e){throw new WrappedError(`Could not load room ${this._roomId}`,e)}}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",(i=>(i.set("id",this.id),this._sendQueue.enqueueEvent(e,t,s,i))))}sendRedaction(e,t,s=null){return this._platform.logger.wrapOrRun(s,"redact",(s=>(s.set("id",this.id),this._sendQueue.enqueueRedaction(e,t,s))))}async ensureMessageKeyIsShared(e=null){if(this._roomEncryption)return this._platform.logger.wrapOrRun(e,"ensureMessageKeyIsShared",(e=>(e.set("id",this.id),this._roomEncryption.ensureMessageKeyIsShared(this._hsApi,e))))}get avatarColorId(){var e;return(null==(e=this._heroes)?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 e;const t=this._syncWriter.lastMessageKey;if(t){const s=await this._storage.readTxn([this._storage.storeNames.timelineEvents]),i=await s.timelineEvents.get(this._roomId,t);return null==(e=null==i?void 0:i.event)?void 0:e.event_id}}async clearUnread(e=null){if(this.isUnread||this.notificationCount)return await this._platform.logger.wrapOrRun(e,"clearUnread",(async e=>{e.set("id",this.id);const t=await this._storage.readWriteTxn([this._storage.storeNames.roomSummary]);let s;try{s=this._summary.writeClearUnread(t)}catch(e){throw t.abort(),e}await t.complete(),this._summary.applyChanges(s),this._emitUpdate();try{const e=await this._getLastEventId();e&&await this._hsApi.receipt(this._roomId,"m.read",e)}catch(e){if("ConnectionError"!==e.name)throw e}}))}leave(e=null){return this._platform.logger.wrapOrRun(e,"leave room",(async e=>{e.set("id",this.id),await this._hsApi.leave(this.id,{log:e}).response()}))}_getPendingEvents(){return this._sendQueue.pendingEvents}_runRoomStateHandlers(e,t,s,i){const r=[];return iterateResponseStateEvents(e,(e=>{r.push(this._roomStateHandler.handleRoomState(this,e,t,s,i))})),Promise.all(r)}_emitSyncRoomState(e){iterateResponseStateEvents(e,(e=>{for(const t of this._roomStateObservers)t.handleStateEvent(e)}))}writeIsTrackingMembers(e,t){return this._summary.writeIsTrackingMembers(e,t)}applyIsTrackingMembersChanges(e){this._summary.applyChanges(e)}createAttachment(e,t){return new AttachmentUpload({blob:e,filename:t,platform:this._platform})}dispose(){super.dispose(),this._sendQueue.dispose()}}class ArchivedRoom extends BaseRoom{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,0===this._retentionCount&&this._releaseCallback()}async _getKickAuthor(e,t){const s=await t.roomMembers.get(this.id,e);return s?new RoomMember(s):RoomMember.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),"leave"===s){const s=findKickDetails(t,this._user.id);if(s||e){const t=s||this._kickDetails;let r;s&&(r=await this._getKickAuthor(s.sender,i));const n=e||this._summary.data;return i.archivedRoomSummary.set({summary:n.serialize(),kickDetails:t}),{kickDetails:t,kickedBy:r,summaryData:n}}}else"join"===s&&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"leave"===(null==(e=this._kickDetails)?void 0:e.membership)}get isBanned(){var e;return"ban"===(null==(e=this._kickDetails)?void 0:e.membership)}get kickedBy(){return this._kickedBy}get kickReason(){var e;return null==(e=this._kickDetails)?void 0:e.reason}isArchived(){return!0}forget(e=null){return this._platform.logger.wrapOrRun(e,"forget room",(async e=>{e.set("id",this.id),await this._hsApi.forget(this.id,{log:e}).response();const t=this._storage.storeNames,s=await this._storage.readWriteTxn([t.roomState,t.archivedRoomSummary,t.roomMembers,t.timelineEvents,t.timelineFragments,t.timelineRelations,t.pendingEvents,t.inboundGroupSessions,t.groupSessionDecryptions,t.operations]);s.roomState.removeAllForRoom(this.id),s.archivedRoomSummary.remove(this.id),s.roomMembers.removeAllForRoom(this.id),s.timelineEvents.removeAllForRoom(this.id),s.timelineFragments.removeAllForRoom(this.id),s.timelineRelations.removeAllForRoom(this.id),s.pendingEvents.removeAllForRoom(this.id),s.inboundGroupSessions.removeAllForRoom(this.id),s.groupSessionDecryptions.removeAllForRoom(this.id),await s.operations.removeAllForScope(this.id),await s.complete(),this._retentionCount=0,this._releaseCallback(),this._forgetCallback(this.id)}))}join(e=null){return this._platform.logger.wrapOrRun(e,"rejoin archived room",(async e=>{await this._hsApi.join(this.id,{log:e}).response()}))}}function findKickDetails(e,t){var s,i;let r;if(iterateResponseStateEvents(e,(e=>{e.type===EVENT_TYPE$1&&e.state_key===t&&e.sender!==e.state_key&&(r=e)})),r)return{membership:null==(s=r.content)?void 0:s.membership,reason:null==(i=r.content)?void 0:i.reason,sender:r.sender}}async function loadProfiles(e,t,s){const i=await Promise.all(e.map((async e=>{const i=await t.profile(e,{log:s}).response();return new Profile(e,i.displayname,i.avatar_url)})));return i.sort(((e,t)=>e.name.localeCompare(t.name))),i}class Profile{constructor(e,t,s){this.userId=e,this.displayName=t,this.avatarUrl=s}get name(){return this.displayName||this.userId}}class UserIdProfile{constructor(e){this.userId=e}get displayName(){}get name(){return this.userId}get avatarUrl(){}}function defaultE2EEStatusForType(e){switch(e){case RoomVisibility.DirectMessage:case RoomVisibility.Private:return!0;case RoomVisibility.Public:return!1}}function presetForType(e){switch(e){case RoomVisibility.DirectMessage:return"trusted_private_chat";case RoomVisibility.Private:return"private_chat";case RoomVisibility.Public:return"public_chat"}}class RoomBeingCreated extends EventEmitter{constructor(e,t,s,i,r,n){var o;if(super(),this.id=e,this.options=t,this.updateCallback=s,this.mediaRepository=i,this.platform=r,this.profiles=[],this._isCancelled=!1,this.isEncrypted=void 0===t.isEncrypted?defaultE2EEStatusForType(t.visibility):t.isEncrypted,t.name)this._calculatedName=t.name;else{const e={joinCount:1,inviteCount:(null==(o=t.invites)?void 0:o.length)||0},s=(t.invites||[]).map((e=>new UserIdProfile(e)));this._calculatedName=calculateRoomName(s,e,n)}}async create(e,t){try{let s;if(this.options.avatar){const{avatar:i}=this.options;if(s={info:i.info},"blob"in i){const r=new AttachmentUpload({filename:i.name,blob:i.blob,platform:this.platform});await r.upload(e,(()=>{}),t),r.applyToContent("url",s)}else s.url=i.url}const i={is_direct:this.options.visibility===RoomVisibility.DirectMessage,preset:presetForType(this.options.visibility),initial_state:[]};if(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),void 0!==this.options.type){let e;this.options.type===RoomType.World&&(e="org.matrix.msc3815.world"),this.options.type===RoomType.Profile&&(e="org.matrix.msc3815.profile"),i.creation_content={type:e}}!0===this.options.isFederationDisabled&&(void 0===i.creation_content&&(i.creation_content={}),i.creation_content["m.federate"]=!1),this.isEncrypted&&i.initial_state.push(createRoomEncryptionEvent()),s&&i.initial_state.push({type:"m.room.avatar",state_key:"",content:s}),this.options.powerLevelContentOverride&&(i.power_level_content_override=this.options.powerLevelContentOverride),this.options.initialState&&i.initial_state.push(...this.options.initialState);const r=await e.createRoom(i,{log:t}).response();this._roomId=r.room_id}catch(e){this._error=e}this.emitChange()}async loadProfiles(e,t){try{if(!this.options.name&&this.options.invites){this.profiles=await loadProfiles(this.options.invites,e,t);const s={joinCount:1,inviteCount:this.options.invites.length};this._calculatedName=calculateRoomName(this.profiles,s,t),this.emitChange()}}catch(e){}}emitChange(e){this.updateCallback(this,e),this.emit("change")}get avatarColorId(){var e,t,s;return null!=(s=null!=(t=null==(e=this.options.invites)?void 0:e[0])?t:this._roomId)?s:this.id}get avatarUrl(){var e,t;return null==(t=null==(e=this.profiles)?void 0:e[0])?void 0:t.avatarUrl}get avatarBlobUrl(){const e=this.options.avatar;if(e&&"blob"in e)return e.blob.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&&"blob"in this.options.avatar&&this.options.avatar.blob.dispose()}async adjustDirectMessageMapIfNeeded(e,t,s,i){if(!this.options.invites||this.options.visibility!==RoomVisibility.DirectMessage)return;const r=this.options.invites[0],n="m.direct";await i.wrap("set "+n,(async i=>{try{const o=await t.readWriteTxn([t.storeNames.accountData]);let a;try{a=await o.accountData.get(n),a||(a={type:n,content:{}});const e=a.content;let t=e[r];t||(e[r]=t=[]),t.push(this._roomId),o.accountData.set(a),await o.complete()}catch(e){throw o.abort(),e}await s.setAccountData(e.id,n,a.content,{log:i}).response()}catch(e){i.catch(e)}}))}}class Invite extends EventEmitter{constructor({roomId:e,user:t,hsApi:s,mediaRepository:i,emitCollectionRemove:r,emitCollectionUpdate:n,platform:o}){super(),this._roomId=e,this._user=t,this._hsApi=s,this._emitCollectionRemove=r,this._emitCollectionUpdate=n,this._mediaRepository=i,this._platform=o,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 type(){var e;return null!=(e=this._inviteData.type)?e:void 0}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"public"===this._inviteData.joinRule}get canonicalAlias(){return this._inviteData.canonicalAlias}async accept(e=null){await this._platform.logger.wrapOrRun(e,"acceptInvite",(async e=>{var t;this._accepting=!0,this._emitChange("accepting"),await this._hsApi.joinIdOrAlias(null!=(t=this.canonicalAlias)?t:this._roomId,{log:e}).response()}))}async reject(e=null){await this._platform.logger.wrapOrRun(e,"rejectInvite",(async e=>{this._rejecting=!0,this._emitChange("rejecting"),await this._hsApi.leave(this._roomId,{log:e}).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 RoomMember(e.inviter):null}async writeSync(e,t,s,i){var r;if("invite"===e){i.set("id",this.id),i.set("add",!0);const e=null==(r=t.invite_state)?void 0:r.events;if(!Array.isArray(e))return null;const n=this._createSummaryData(e);let o;n.name||n.canonicalAlias||(o=await this._createHeroes(e,i));const a=this._getMyInvite(e);if(!a)return null;const l=this._getInviter(a,e),c=this._createData(e,a,l,n,o);return s.invites.set(c),{inviteData:c,inviter:l}}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,"join"===e.membership?this._accepted=!0:this._rejected=!0,this.emit("change")):(this._inviteData=e.inviteData,this._inviter=e.inviter))}_createData(e,t,s,i,r){const n=r?r.roomName:i.name,o=r?r.roomAvatarUrl:i.avatarUrl,a=(null==r?void 0:r.roomAvatarColorId)||this.id;return{roomId:this.id,isEncrypted:!!i.encryption,isDirectMessage:i.isDirectMessage,type:i.type,name:n,avatarUrl:o,avatarColorId:a,canonicalAlias:i.canonicalAlias,timestamp:this._platform.clock.now(),joinRule:this._getJoinRule(e),inviter:null==s?void 0:s.serialize()}}_createSummaryData(e){return e.reduce(((e,t)=>processStateEvent(e,t,this._user.id)),new SummaryData(null,this.id))}async _createHeroes(e,t){const s=e.filter((e=>e.type===EVENT_TYPE$1)),i=s.filter((e=>e.state_key!==this._user.id)),r=i.reduce(((e,t)=>{const s=RoomMember.fromMemberEvent(this.id,t);return e.set(s.userId,new MemberChange(s,null)),e}),new Map),n=i.map((e=>e.state_key)),o=new Heroes(this.id),a=await o.calculateChanges(n,r,null),l=new SummaryData(null,this.id);return l.joinCount=s.reduce(((e,t)=>{var s;return e+("join"===(null==(s=t.content)?void 0:s.membership)?1:0)}),0),l.inviteCount=s.reduce(((e,t)=>{var s;return e+("invite"===(null==(s=t.content)?void 0:s.membership)?1:0)}),0),o.applyChanges(a,l,t),o}_getMyInvite(e){return e.find((e=>e.type===EVENT_TYPE$1&&e.state_key===this._user.id))}_getInviter(e,t){const s=t.find((t=>t.type===EVENT_TYPE$1&&t.state_key===e.sender));if(s)return RoomMember.fromMemberEvent(this.id,s)}_getJoinRule(e){var t;const s=e.find((e=>"m.room.join_rules"===e.type));return s?null==(t=s.content)?void 0:t.join_rule:null}}class Pusher{constructor(e){this._description=e}static httpPusher(e,t,s,i){return new Pusher({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&&JSON.stringify(this._description.data)===JSON.stringify(e._description.data))}}class DeviceMessageHandler extends EventEmitter{constructor({storage:e,callHandler:t}){super(),this._storage=e,this._olmDecryption=null,this._megolmDecryption=null,this._callHandler=t,this._senderDeviceCache=new LRUCache(10,(e=>e.curve25519Key))}enableEncryption({olmDecryption:e,megolmDecryption:t}){this._olmDecryption=e,this._megolmDecryption=t}obtainSyncLock(e){var t;return null==(t=this._olmDecryption)?void 0:t.obtainDecryptionLock(e)}async prepareSync(e,t,s,i){i.set("messageTypes",countBy(e,(e=>e.type)));const r=e.filter((e=>"m.room.encrypted"===e.type));if(this._emitUnencryptedEvents(e),!this._olmDecryption)return void i.log("can't decrypt, encryption not enabled",i.level.Warn);const n=r.filter((e=>{var t;return(null==(t=e.content)?void 0:t.algorithm)===OLM_ALGORITHM}));if(n.length){const e=await this._olmDecryption.decryptAll(n,t,s);i.set("decryptedTypes",countBy(e.results,(e=>{var t;return null==(t=e.event)?void 0:t.type})));for(const t of e.errors)i.child("decrypt_error").catch(t);const r=this._megolmDecryption.roomKeysFromDeviceMessages(e.results,i);return new SyncPreparation(e,r)}}async writeSync(e,t){e.olmDecryptChanges.write(t);return{hasNewRoomKeys:(await Promise.all(e.newRoomKeys.map((e=>this._megolmDecryption.writeRoomKey(e,t))))).some((e=>!!e)),decryptionResults:e.olmDecryptChanges.results}}async afterSyncCompleted(e,t,s,i){if(this._emitEncryptedEvents(e),this._callHandler){const r=e.filter((e=>{var t;return this._callHandler.handlesDeviceMessageEventType(null==(t=e.event)?void 0:t.type)}));r.length&&await i.wrap("process call signalling messages",(async e=>{for(const i of r){const r=await t.deviceForId(i.event.sender,i.event.content.device_id,s,e);i.setDevice(r),i.isVerified?this._callHandler.handleDeviceMessage(i.event,i.userId,i.deviceId,e):e.log({l:"could not verify olm fingerprint key matches, ignoring",ed25519Key:i.device.ed25519Key,claimedEd25519Key:i.claimedEd25519Key,deviceId:r.deviceId,userId:r.userId})}}))}}_emitUnencryptedEvents(e){const t=e.filter((e=>"m.room.encrypted"!==e.type));for(const e of t)this.emit("message",{unencrypted:e})}_emitEncryptedEvents(e){}}class SyncPreparation{constructor(e,t){this.olmDecryptChanges=e,this.newRoomKeys=t,this.newKeysByRoom=groupBy(t,(e=>e.roomId))}}const ACCOUNT_SESSION_KEY="e2ee:olmAccount",DEVICE_KEY_FLAG_SESSION_KEY="e2ee:areDeviceKeysUploaded",SERVER_OTK_COUNT_SESSION_KEY="e2ee:serverOTKCount";async function initiallyStoreAccount(e,t,s,i,r){const n=e.pickle(t),o=await r.readWriteTxn([r.storeNames.session]);try{o.session.add("e2ee:olmAccount",n),o.session.add(DEVICE_KEY_FLAG_SESSION_KEY,s),o.session.add("e2ee:serverOTKCount",i)}catch(e){throw o.abort(),e}await o.complete()}class Account{static async load({olm:e,pickleKey:t,hsApi:s,userId:i,deviceId:r,olmWorker:n,txn:o}){const a=await o.session.get("e2ee:olmAccount");if(a){const l=new e.Account,c=await o.session.get(DEVICE_KEY_FLAG_SESSION_KEY);l.unpickle(t,a);const d=await o.session.get("e2ee:serverOTKCount");return new Account({pickleKey:t,hsApi:s,account:l,userId:i,deviceId:r,areDeviceKeysUploaded:c,serverOTKCount:d,olm:e,olmWorker:n})}}static async adoptDehydratedDevice({olm:e,dehydratedDevice:t,pickleKey:s,hsApi:i,userId:r,olmWorker:n,storage:o}){const a=t.adoptUnpickledOlmAccount(),l=JSON.parse(a.one_time_keys()),c=Object.entries(l.curve25519).length,d=!0;return await initiallyStoreAccount(a,s,d,c,o),new Account({pickleKey:s,hsApi:i,account:a,userId:r,deviceId:t.deviceId,areDeviceKeysUploaded:d,serverOTKCount:c,olm:e,olmWorker:n})}static async create({olm:e,pickleKey:t,hsApi:s,userId:i,deviceId:r,olmWorker:n,storage:o}){const a=new e.Account;n?await n.createAccountAndOTKs(a,a.max_number_of_one_time_keys()):(a.create(),a.generate_one_time_keys(a.max_number_of_one_time_keys()));const l=!1;return o&&await initiallyStoreAccount(a,t,l,0,o),new Account({pickleKey:t,hsApi:s,account:a,userId:i,deviceId:r,areDeviceKeysUploaded:l,serverOTKCount:0,olm:e,olmWorker:n})}constructor({pickleKey:e,hsApi:t,account:s,userId:i,deviceId:r,areDeviceKeysUploaded:n,serverOTKCount:o,olm:a,olmWorker:l}){this._olm=a,this._pickleKey=e,this._hsApi=t,this._account=s,this._userId=i,this._deviceId=r,this._areDeviceKeysUploaded=n,this._serverOTKCount=o,this._olmWorker=l,this._identityKeys=JSON.parse(this._account.identity_keys())}get identityKeys(){return this._identityKeys}setDeviceId(e){this._deviceId=e}async uploadKeys(e,t,s){var i;const r=JSON.parse(this._account.one_time_keys()),n=Object.entries(r.curve25519);if(n.length||!this._areDeviceKeysUploaded){const r={};if(!this._areDeviceKeysUploaded){s.set("identity",!0);const e=JSON.parse(this._account.identity_keys());r.device_keys=this._deviceKeysPayload(e)}n.length&&(s.set("otks",!0),r.one_time_keys=this._oneTimeKeysPayload(n));const o=t?this._deviceId:void 0,a=await this._hsApi.uploadKeys(o,r,{log:s}).response();this._serverOTKCount=null==(i=null==a?void 0:a.one_time_key_counts)?void 0:i.signed_curve25519,s.set("serverOTKCount",this._serverOTKCount),await this._updateSessionStorage(e,(e=>{n.length&&(this._account.mark_keys_as_published(),null==e||e.set("e2ee:olmAccount",this._account.pickle(this._pickleKey)),null==e||e.set("e2ee:serverOTKCount",this._serverOTKCount)),this._areDeviceKeysUploaded||(this._areDeviceKeysUploaded=!0,null==e||e.set(DEVICE_KEY_FLAG_SESSION_KEY,this._areDeviceKeysUploaded))}))}}async generateOTKsIfNeeded(e,t){const s=this._account.max_number_of_one_time_keys(),i=Math.floor(s/2);if(this._serverOTKCount<i){const r=JSON.parse(this._account.one_time_keys()),n=Object.entries(r.curve25519).length,o=i-n-this._serverOTKCount;return o>0&&await t.wrap("generate otks",(t=>{t.set("max",s),t.set("server",this._serverOTKCount),t.set("unpublished",n),t.set("new",o),t.set("limit",i),this._account.generate_one_time_keys(o),this._updateSessionStorage(e,(e=>{e.set("e2ee:olmAccount",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(e){throw s.free(),e}}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(e){throw s.free(),e}}writeRemoveOneTimeKey(e,t){this._account.remove_one_time_keys(e),t.session.set("e2ee:olmAccount",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("e2ee:serverOTKCount",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:[OLM_ALGORITHM,MEGOLM_ALGORITHM],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 e={key:i};this.signObject(e),t[`signed_curve25519:${s}`]=e}return t}async _updateSessionStorage(e,t){if(e){const s=await e.readWriteTxn([e.storeNames.session]);try{await t(s.session)}catch(e){throw s.abort(),e}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(anotherjson__default.default.stringify(e)),e.signatures=t,void 0!==s&&(e.unsigned=s)}pickleWithKey(e){return this._account.pickle(e)}dispose(){this._account.free(),this._account=void 0}}const DEHYDRATION_LIBOLM_PICKLE_ALGORITHM="org.matrix.msc2697.v1.olm.libolm_pickle";async function getDehydratedDevice(e,t,s,i){try{const r=await e.getDehydratedDevice({log:i}).response();if(r.device_data.algorithm===DEHYDRATION_LIBOLM_PICKLE_ALGORITHM)return new EncryptedDehydratedDevice(r,t,s)}catch(e){return void("HomeServerError"!==e.name&&(i.error=e))}}async function uploadAccountAsDehydratedDevice(e,t,s,i,r){var n;const o=(await t.createDehydratedDevice({device_data:{algorithm:DEHYDRATION_LIBOLM_PICKLE_ALGORITHM,account:e.pickleWithKey(s.binaryKey.slice()),passphrase:(null==(n=s.description)?void 0:n.passphraseParams)||{}},initial_device_display_name:i}).response()).device_id;return e.setDeviceId(o),await e.uploadKeys(void 0,!0,r),o}class EncryptedDehydratedDevice{constructor(e,t,s){this._dehydratedDevice=e,this._olm=t,this._platform=s}async decrypt(e,t){const s=new KeyDescription("dehydrated_device",this._dehydratedDevice.device_data.passphrase),i=await keyFromCredentialAndDescription(e,t,s,this._platform,this._olm),r=new this._olm.Account;try{const e=this._dehydratedDevice.device_data.account;return r.unpickle(i.binaryKey.slice(),e),new DehydratedDevice(this._dehydratedDevice,r,i)}catch(e){if(r.free(),"OLM.BAD_ACCOUNT_KEY"===e.message)return;throw e}}get deviceId(){return this._dehydratedDevice.device_id}}class DehydratedDevice{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(e){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;null==(e=this._account)||e.free(),this._account=void 0}}class Lock{tryTake(){return!this._promise&&(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 MultiLock{constructor(e){this.locks=e}release(){for(const e of this.locks)e.release()}}function createSessionEntry(e,t,s,i){return{session:e.pickle(i),sessionId:e.session_id(),senderKey:t,lastUsed:s}}class Session$1{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 n=createSessionEntry(t,e,r,i);return new Session$1(n,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 DecryptionResult{constructor(e,t,s,i){this.event=e,this.senderCurve25519Key=t,this.claimedEd25519Key=s,this.encryptedEvent=i}setDevice(e){this.device=e}get isVerified(){if(this.device){return getDeviceEd25519Key(this.device)===this.claimedEd25519Key}return!1}get isUnverified(){return!this.device||!this.isVerified}get userId(){var e;return null==(e=this.device)?void 0:e.user_id}get deviceId(){var e;return null==(e=this.device)?void 0:e.device_id}get isVerificationUnknown(){return!this.device}}var OlmPayloadType=(e=>(e[e.PreKey=0]="PreKey",e[e.Normal=1]="Normal",e))(OlmPayloadType||{});const SESSION_LIMIT_PER_SENDER_KEY=4;function sortSessions(e){e.sort(((e,t)=>t.data.lastUsed-e.data.lastUsed))}class Decryption$1{constructor(e,t,s,i,r,n){this.account=e,this.pickleKey=t,this.now=s,this.ownUserId=i,this.olm=r,this.senderKeyLock=n}async obtainDecryptionLock(e){var t;const s=new Set;for(const i of e){const e=null==(t=i.content)?void 0:t.sender_key;e&&s.add(e)}const i=await Promise.all(Array.from(s).map((e=>this.senderKeyLock.takeLock(e))));return new MultiLock(i)}async decryptAll(e,t,s){try{const i=groupBy(e,(e=>{var t;return null==(t=e.content)?void 0:t.sender_key})),r=this.now(),n=await Promise.all(Array.from(i.entries()).map((([e,t])=>this._decryptAllForSenderKey(e,t,r,s)))),o=n.reduce(((e,t)=>e.concat(t.results)),[]),a=n.reduce(((e,t)=>e.concat(t.errors)),[]),l=n.map((e=>e.senderKeyDecryption));return new DecryptionChanges$2(l,o,a,this.account,t)}catch(e){throw t.release(),e}}async _decryptAllForSenderKey(e,t,s,i){const r=await this._getSessions(e,i),n=new SenderKeyDecryption(e,r,s),o=[],a=[];for(const e of t)try{const t=this._decryptForSenderKey(n,e,s);o.push(t)}catch(e){a.push(e)}return{results:o,errors:a,senderKeyDecryption:n}}_decryptForSenderKey(e,t,s){const i=e.senderKey,r=this._getMessageAndValidateEvent(t);let n;try{n=e.decrypt(r)}catch(e){throw new DecryptionError$1("OLM_BAD_ENCRYPTED_MESSAGE",t,{senderKey:i,error:e.message})}if("string"!=typeof n&&r.type===OlmPayloadType.PreKey){let o;try{o=this._createSessionAndDecrypt(i,r,s)}catch(e){throw new DecryptionError$1(`Could not create inbound olm session: ${e.message}`,t,{senderKey:i,error:e})}e.addNewSession(o.session),n=o.plaintext}if("string"==typeof n){let e;try{e=JSON.parse(n)}catch(e){throw new DecryptionError$1("PLAINTEXT_NOT_JSON",t,{plaintext:n,error:e})}return this._validatePayload(e,t),new DecryptionResult(e,i,e.keys.ed25519)}throw new DecryptionError$1("OLM_NO_MATCHING_SESSION",t,{knownSessionIds:e.sessions.map((e=>e.id))})}_createSessionAndDecrypt(e,t,s){let i;const r=this.account.createInboundOlmSession(e,t.body);try{i=r.decrypt(t.type,t.body);const n=Session$1.create(e,r,this.olm,this.pickleKey,s);return n.unload(r),{session:n,plaintext:i}}catch(e){throw r.free(),e}}_getMessageAndValidateEvent(e){var t;const s=null==(t=e.content)?void 0:t.ciphertext;if(!s)throw new DecryptionError$1("OLM_MISSING_CIPHERTEXT",e);const i=null==s?void 0:s[this.account.identityKeys.curve25519];if(!i)throw new DecryptionError$1("OLM_NOT_INCLUDED_IN_RECIPIENTS",e);return i}async _getSessions(e,t){const s=(await t.olmSessions.getAll(e)).map((e=>new Session$1(e,this.pickleKey,this.olm)));return sortSessions(s),s}_validatePayload(e,t){var s,i,r;if(e.sender!==t.sender)throw new DecryptionError$1("OLM_FORWARDED_MESSAGE",t,{sentBy:t.sender,encryptedBy:e.sender});if(e.recipient!==this.ownUserId)throw new DecryptionError$1("OLM_BAD_RECIPIENT",t,{recipient:e.recipient});if((null==(s=e.recipient_keys)?void 0:s.ed25519)!==this.account.identityKeys.ed25519)throw new DecryptionError$1("OLM_BAD_RECIPIENT_KEY",t,{key:null==(i=e.recipient_keys)?void 0:i.ed25519});if(!e.type)throw new DecryptionError$1("missing type on payload",t,{payload:e});if("string"!=typeof(null==(r=e.keys)?void 0:r.ed25519))throw new DecryptionError$1("Missing or invalid claimed ed25519 key on payload",t,{payload:e})}}class SenderKeyDecryption{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("string"==typeof s)return sortSessions(this.sessions),s}}getModifiedSessions(){return this.sessions.filter((e=>e.isModified))}get hasNewSessions(){return this.sessions.some((e=>e.isNew))}decryptWithSession(e,t){if(void 0===t.type||void 0===t.body)throw new Error("Invalid message without type or body");const s=e.load();try{if(t.type===OlmPayloadType.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(s){if(t.type===OlmPayloadType.PreKey)throw new Error(`Error decrypting prekey message with existing session id ${e.id}: ${s.message}`);return}}finally{e.unload(s)}}}class DecryptionChanges$2{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 t=s.load();try{this.account.writeRemoveOneTimeKey(t,e)}finally{s.unload(t)}}if(t.sessions.length>4){const{senderKey:s,sessions:i}=t;for(let t=i.length-1;t>=4;t-=1){const r=i[t];e.olmSessions.remove(s,r.id)}}}}finally{this.lock.release()}}}function findFirstSessionId(e){return e.reduce(((e,t)=>!e||t<e?t:e),null)}const OTK_ALGORITHM="signed_curve25519",MAX_BATCH_SIZE=20;class Encryption$1{constructor(e,t,s,i,r,n,o,a){this.account=e,this.pickleKey=t,this.olm=s,this.storage=i,this.now=r,this.ownUserId=n,this.olmUtil=o,this.senderKeyLock=a,this._batchLocks=new Array(20);for(let e=0;e<20;e+=1)this._batchLocks[e]=new Lock}async _takeBatchLock(e){const t=this._batchLocks.filter((e=>!e.isTaken)).slice(0,e);if(t.length<e){const s=this._batchLocks.filter((e=>e.isTaken)).slice(0,e-t.length);t.push(...s)}return await Promise.all(t.map((e=>e.take()))),new MultiLock(t)}async encrypt(e,t,s,i,r){let n=[];for(let o=0;o<s.length;o+=20){const a=s.slice(o,o+20),l=await this._takeBatchLock(a.length);try{const s=await this._encryptForMaxDevices(e,t,a,i,r);n=n.concat(s)}finally{l.release()}}return n}async _encryptForMaxDevices(e,t,s,i,r){const n=await Promise.all(s.map((e=>this.senderKeyLock.takeLock(getDeviceCurve25519Key(e)))));try{const{devicesWithoutSession:n,existingEncryptionTargets:o}=await this._findExistingSessions(s),a=this.now();let l=[];try{if(n.length){const e=await r.wrap("create sessions",(e=>this._createNewSessions(n,i,a,e)));l=l.concat(e)}await this._loadSessions(o),l=l.concat(o);const s={l:"encrypt",targets:l.length},c=r.wrap(s,(()=>l.map((s=>{const i=this._encryptForDevice(e,t,s);return new EncryptedMessage(i,s.device)}))));return await this._storeSessions(l,a),c}finally{for(const e of l)e.dispose()}}finally{for(const e of n)e.release()}}async _findExistingSessions(e){const t=await this.storage.readTxn([this.storage.storeNames.olmSessions]),s=await Promise.all(e.map((async e=>await t.olmSessions.getSessionIds(getDeviceCurve25519Key(e)))));return{devicesWithoutSession:e.filter(((e,t)=>{const i=s[t];return!(null==i?void 0:i.length)})),existingEncryptionTargets:e.map(((e,t)=>{const i=s[t];if((null==i?void 0:i.length)>0){const t=findFirstSessionId(i);return EncryptionTarget.fromSessionId(e,t)}})).filter((e=>!!e))}}_encryptForDevice(e,t,s){const{session:i,device:r}=s,n=JSON.stringify(this._buildPlainTextMessageForDevice(e,t,r)),o=i.encrypt(n);return{algorithm:OLM_ALGORITHM,sender_key:this.account.identityKeys.curve25519,ciphertext:{[getDeviceCurve25519Key(r)]:o}}}_buildPlainTextMessageForDevice(e,t,s){return{keys:{ed25519:this.account.identityKeys.ed25519},recipient_keys:{ed25519:getDeviceEd25519Key(s)},recipient:s.user_id,sender:this.ownUserId,content:t,type:e}}async _createNewSessions(e,t,s,i){const r=await i.wrap("claim",(s=>this._claimOneTimeKeys(t,e,s)));try{for(const e of r){const{device:t,oneTimeKey:s}=e;e.session=await this.account.createOutboundOlmSession(getDeviceCurve25519Key(t),s)}await this._storeSessions(r,s)}catch(e){for(const e of r)e.dispose();throw e}return r}async _claimOneTimeKeys(e,t,s){const i=groupByWithCreator(t,(e=>e.user_id),(()=>new Map),((e,t)=>e.set(t.device_id,t))),r=Array.from(i.entries()).reduce(((e,[t,s])=>(e[t]=Array.from(s.values()).reduce(((e,t)=>(e[t.device_id]=OTK_ALGORITHM,e)),{}),e)),{}),n=await e.claimKeys({timeout:1e4,one_time_keys:r},{log:s}).response();Object.keys(n.failures).length&&s.log({l:"failures",servers:Object.keys(n.failures)},s.level.Warn);const o=null==n?void 0:n.one_time_keys;return this._verifyAndCreateOTKTargets(o,i,s)}_verifyAndCreateOTKTargets(e,t,s){var i;const r=[];for(const[n,o]of Object.entries(e))for(const[e,a]of Object.entries(o)){const[o,l]=Object.entries(a)[0],[c]=o.split(":");if(c===OTK_ALGORITHM){const o=null==(i=t.get(n))?void 0:i.get(e);if(o){if(verifyEd25519Signature(this.olmUtil,n,e,getDeviceEd25519Key(o),l,s)===SignatureVerification.Valid){const e=EncryptionTarget.fromOTK(o,l.key);r.push(e)}}}}return r}async _loadSessions(e){const t=await this.storage.readTxn([this.storage.storeNames.olmSessions]);let s=!1;try{await Promise.all(e.map((async e=>{const i=await t.olmSessions.get(getDeviceCurve25519Key(e.device),e.sessionId);if(i&&!s){const t=new this.olm.Session;t.unpickle(this.pickleKey,i.session),e.session=t}})))}catch(t){s=!0;for(const t of e)t.dispose();throw t}}async _storeSessions(e,t){const s=await this.storage.readWriteTxn([this.storage.storeNames.olmSessions]);try{for(const i of e){const e=createSessionEntry(i.session,getDeviceCurve25519Key(i.device),t,this.pickleKey);s.olmSessions.set(e)}}catch(e){throw s.abort(),e}await s.complete()}}class EncryptionTarget{constructor(e,t,s){this.device=e,this.oneTimeKey=t,this.sessionId=s,this.session=null}static fromOTK(e,t){return new EncryptionTarget(e,t,null)}static fromSessionId(e,t){return new EncryptionTarget(e,null,t)}dispose(){this.session&&this.session.free()}}class EncryptedMessage{constructor(e,t){this.content=e,this.device=t}}class DecryptionChanges$1{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(e){this._errors.set(t.eventId,e)}}))),{results:this._results,errors:this._errors}}async _handleReplayAttack(e,t,s){const{messageIndex:i,sessionId:r,eventId:n,timestamp:o}=t,a=await s.groupSessionDecryptions.get(e,r,i);if(a&&a.eventId!==n){const e=a.timestamp<o?n:a.eventId;throw this._results.delete(n),new DecryptionError$1("MEGOLM_REPLAYED_INDEX",event,{messageIndex:i,badEventId:e,otherEventId:a.eventId})}a||s.groupSessionDecryptions.set(e,r,i,{eventId:n,timestamp:o})}}function mergeMap(e,t){if(e)for(const[s,i]of e.entries())t.set(s,i)}class DecryptionPreparation$1{constructor(e,t,s){this._roomId=e,this._sessionDecryptions=t,this._initialErrors=s}async decrypt(){try{const e=this._initialErrors,t=new Map,s=[];return await Promise.all(this._sessionDecryptions.map((async i=>{const r=await i.decryptAll();mergeMap(r.errors,e),mergeMap(r.results,t),s.push(...r.replayEntries)}))),new DecryptionChanges$1(this._roomId,t,e,s)}finally{this.dispose()}}dispose(){for(const e of this._sessionDecryptions)e.dispose()}}class ReplayDetectionEntry{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 SessionDecryption{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 s=r.content.ciphertext;let n;if(this.olmWorker){const e=this.olmWorker.megolmDecrypt(i,s);this.decryptionRequests.push(e),n=await e.response()}else n=i.decrypt(s);const{plaintext:o}=n;let a;try{a=JSON.parse(o)}catch(e){throw new DecryptionError$1("PLAINTEXT_NOT_JSON",r,{plaintext:o,err:e})}if(a.room_id!==this.key.roomId)throw new DecryptionError$1("MEGOLM_WRONG_ROOM",r,{encryptedRoomId:a.room_id,eventRoomId:this.key.roomId});e.push(new ReplayDetectionEntry(this.key.sessionId,n.message_index,r));const l=new DecryptionResult(a,this.key.senderKey,this.key.claimedEd25519Key,r);t.set(r.event_id,l)}catch(e){if("AbortError"===e.name)return;s||(s=new Map),s.set(r.event_id,e)}})),{results:t,errors:s,replayEntries:e}}dispose(){if(this.decryptionRequests)for(const e of this.decryptionRequests)e.abort()}}function getSenderKey(e){var t;return null==(t=e.content)?void 0:t.sender_key}function getSessionId(e){var t;return null==(t=e.content)?void 0:t.session_id}function getCiphertext(e){var t;return null==(t=e.content)?void 0:t.ciphertext}function validateEvent(e){return"string"==typeof getSenderKey(e)&&"string"==typeof getSessionId(e)&&"string"==typeof getCiphertext(e)}class SessionKeyGroup{constructor(){this.events=[]}get senderKey(){return getSenderKey(this.events[0])}get sessionId(){return getSessionId(this.events[0])}}function groupEventsBySession(e){return groupByWithCreator(e,(e=>`${getSenderKey(e)}|${getSessionId(e)}`),(()=>new SessionKeyGroup),((e,t)=>e.events.push(t)))}class RoomKey{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 isBetterThan(e,t){return e.first_known_index()<t.first_known_index()}class IncomingRoomKey extends RoomKey{checkBetterThanKeyInStorage(e,t){return this._checkBetterThanKeyInStorage(e,void 0,t)}async write(e,t){let s;if(void 0===this.isBetter&&await this._checkBetterThanKeyInStorage(e,((e,t)=>{s=e.pickle(t)}),t),!1===this.isBetter)return!1;s||(s=await e.useKey(this,((e,t)=>e.pickle(t))));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(void 0!==this.isBetter)return this.isBetter;let i=e.getCachedKey(this.roomId,this.senderKey,this.sessionId);if(!i){const e=await keyFromStorage(this.roomId,this.senderKey,this.sessionId,s);e&&(e.hasSession?i=e:e.eventIds&&(this._eventIds=e.eventIds))}if(i){const s=i;await e.useKey(this,(async i=>{await e.useKey(s,((e,r)=>{this.isBetter=isBetterThan(i,e),s.isBetter=!this.isBetter,this.isBetter&&t&&t(i,r)}))}))}else this.isBetter=!0;return this.isBetter}get backupStatus(){return BackupStatus.NotBackedUp}}class DeviceMessageRoomKey extends IncomingRoomKey{constructor(e){super(),this._decryptionResult=e}get roomId(){var e;return null==(e=this._decryptionResult.event.content)?void 0:e.room_id}get senderKey(){return this._decryptionResult.senderCurve25519Key}get sessionId(){var e;return null==(e=this._decryptionResult.event.content)?void 0:e.session_id}get claimedEd25519Key(){return this._decryptionResult.claimedEd25519Key}get serializationKey(){var e;return null==(e=this._decryptionResult.event.content)?void 0:e.session_key}get serializationType(){return"create"}get keySource(){return KeySource.DeviceMessage}loadInto(e){e.create(this.serializationKey)}}class OutboundRoomKey extends IncomingRoomKey{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 KeySource.Outbound}loadInto(e){e.create(this.serializationKey)}}class BackupRoomKey extends IncomingRoomKey{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 null==(e=this._backupInfo.sender_claimed_keys)?void 0:e.ed25519}get serializationKey(){return this._backupInfo.session_key}get serializationType(){return"import_session"}get keySource(){return KeySource.Backup}loadInto(e){e.import_session(this.serializationKey)}get backupStatus(){return BackupStatus.BackedUp}}class StoredRoomKey extends RoomKey{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 keyFromDeviceMessage(e){var t;const s=null==(t=e.event.content)?void 0:t.session_key,i=new DeviceMessageRoomKey(e);if("string"==typeof i.roomId&&"string"==typeof i.sessionId&&"string"==typeof i.senderKey&&"string"==typeof s)return i}function keyFromBackup(e,t,s){var i;const r=s.session_key,n=s.sender_key,o=null==(i=s.sender_claimed_keys)?void 0:i.ed25519;if("string"==typeof e&&"string"==typeof t&&"string"==typeof n&&"string"==typeof r&&"string"==typeof o)return new BackupRoomKey(e,t,s)}async function keyFromStorage(e,t,s,i){const r=await i.inboundGroupSessions.get(e,t,s);if(r)return new StoredRoomKey(r)}class Decryption{constructor(e,t){this.keyLoader=e,this.olmWorker=t}async addMissingKeyEventIds(e,t,s,i,r){let n=await r.inboundGroupSessions.get(e,t,s);if(!(null==n?void 0:n.session)){if(n){const e=new Set(n.eventIds);for(const t of i)e.add(t);n.eventIds=Array.from(e)}else n={roomId:e,senderKey:t,sessionId:s,eventIds:i};r.inboundGroupSessions.set(n)}}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"string"==typeof(null==r?void 0:r.session)}async prepareDecryptAll(e,t,s,i){const r=new Map,n=[];for(const e of t)validateEvent(e)?n.push(e):r.set(e.event_id,new DecryptionError$1("MEGOLM_INVALID_EVENT",e));const o=groupEventsBySession(n),a=[];return await Promise.all(Array.from(o.values()).map((async t=>{const n=await this.getRoomKey(e,t.senderKey,t.sessionId,s,i);if(n)a.push(new SessionDecryption(n,t.events,this.olmWorker,this.keyLoader));else for(const e of t.events)r.set(e.event_id,new DecryptionError$1("MEGOLM_NO_SESSION",e))}))),new DecryptionPreparation$1(e,a,r)}async getRoomKey(e,t,s,i,r){if(i){const n=i.find((i=>i.isForSession(e,t,s)));if(n&&await n.checkBetterThanKeyInStorage(this.keyLoader,r))return n}const n=this.keyLoader.getCachedKey(e,t,s);if(n)return n;const o=await keyFromStorage(e,t,s,r);return o&&o.serializationKey?o:void 0}writeRoomKey(e,t){return e.write(this.keyLoader,t)}roomKeysFromDeviceMessages(e,t){var s,i;const r=[];for(const n of e)"m.room_key"===(null==(s=n.event)?void 0:s.type)&&(null==(i=n.event.content)?void 0:i.algorithm)===MEGOLM_ALGORITHM&&t.wrap("room_key",(e=>{const t=keyFromDeviceMessage(n);t?(e.set("roomId",t.roomId),e.set("id",t.sessionId),r.push(t)):(e.logLevel=e.level.Warn,e.set("invalid",!0))}),t.level.Detail);return r}roomKeyFromBackup(e,t,s){return keyFromBackup(e,t,s)}dispose(){this.keyLoader.dispose()}}class KeyLoader extends BaseLRUCache{constructor(e,t,s){super(s),this.pickleKey=t,this.olm=e}getCachedKey(e,t,s){const i=this.findCachedKeyIndex(e,t,s);if(-1!==i)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=>0!==e.refCount))}dispose(){for(let e=0;e<this._entries.length;e+=1)this._entries[e].dispose();this._entries.splice(0,this._entries.length)}async allocateOperation(e){let t;for(;-1===(t=this.findIndexForAllocation(e));)await this.operationBecomesUnused();if(t<this.size){const s=this._getByIndexAndMoveUp(t);return s.isForKey(e)?(s.refCount+=1,s):(s.refCount=1,s.key=e,e.loadInto(s.session,this.pickleKey),s)}{const t=new this.olm.InboundGroupSession;e.loadInto(t,this.pickleKey);const s=new KeyOperation(e,t);return this._set(s),s}}releaseOperation(e){e.refCount-=1,e.refCount<=0&&this.resolveUnusedOperation&&(this.resolveUnusedOperation(),this.operationBecomesUnusedPromise=this.resolveUnusedOperation=void 0)}operationBecomesUnused(){return this.operationBecomesUnusedPromise||(this.operationBecomesUnusedPromise=new Promise((e=>{this.resolveUnusedOperation=e}))),this.operationBecomesUnusedPromise}findIndexForAllocation(e){let t=this.findIndexSameKey(e);return-1===t&&(this.size<this.limit?t=this.size:(t=this.findIndexSameSessionUnused(e),-1===t&&(t=this.findIndexOldestUnused()))),t}findCachedKeyIndex(e,t,s){return this._entries.reduce(((i,r,n,o)=>{const a=-1===i?void 0:o[i];return!0!==r.isBest||!r.isForSameSession(e,t,s)||a&&!r.isBetter(a)?i:n}),-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 n=-1===t?void 0:r[t];return 0!==s.refCount||!s.isForSameSession(e.roomId,e.senderKey,e.sessionId)||n&&s.isBetter(n)?t:i}),-1)}findIndexOldestUnused(){for(let e=this._entries.length-1;e>=0;e-=1){if(0===this._entries[e].refCount)return e}return-1}}class KeyOperation{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 isBetterThan(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 Algorithm="m.megolm_backup.v1.curve25519-aes-sha2";class BackupEncryption{constructor(e,t){this.encryption=e,this.decryption=t}static fromAuthData(e,t,s){const i=e.public_key,r=new s.PkDecryption,n=new s.PkEncryption;try{const e=r.init_with_private_key(t);if(e!==i)throw new Error(`Bad backup key, public key does not match. Calculated ${e} but expected ${i}`);n.set_recipient_key(e)}catch(e){throw r.free(),n.free(),e}return new BackupEncryption(n,r)}decryptRoomKey(e){const t=this.decryption.decrypt(e.ephemeral,e.mac,e.ciphertext);return JSON.parse(t)}encryptRoomKey(e,t){const s={algorithm:MEGOLM_ALGORITHM,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;null==(e=this.decryption)||e.free(),this.decryption=void 0,null==(t=this.encryption)||t.free(),this.encryption=void 0}}const KEYS_PER_REQUEST=200;class BackupConfig{constructor(e,t){this.info=e,this.crypto=t}}class KeyBackup extends EventEmitter{constructor(e,t,s,i,r,n=1e4){super(),this.hsApi=e,this.olm=t,this.keyLoader=s,this.storage=i,this.platform=r,this.maxDelay=n,this._stopped=!1,this._needsNewKey=!1,this._hasBackedUpAllKeys=!1,this.backupConfigDeferred=new Deferred,this.backupConfigDeferred=new Deferred}get hasStopped(){return this._stopped}get error(){return this._error}get version(){var e,t;return null==(t=null==(e=this.backupConfigDeferred.value)?void 0:e.info)?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 n=i.crypto.decryptRoomKey(r.session_data);if((null==n?void 0:n.algorithm)===MEGOLM_ALGORITHM)return keyFromBackup(e,t,n);(null==n?void 0:n.algorithm)&&s.set("unknown algorithm",n.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 e=>{if(this.privateKey&&!this.backupInfoRequest){let t;try{this.backupInfoRequest=this.hsApi.roomKeysVersion(void 0,{log:e}),t=await this.backupInfoRequest.response()}catch(t){if("AbortError"===t.name)return void e.set("aborted",!0);throw t}finally{this.backupInfoRequest=void 0}if(t.algorithm===Algorithm){const e=BackupEncryption.fromAuthData(t.auth_data,this.privateKey,this.olm);this.backupConfigDeferred.resolve(new BackupConfig(t,e)),this.emit("change")}else this.backupConfigDeferred.resolve(void 0),e.log({l:"Unknown backup algorithm",algorithm:t.algorithm});this.privateKey=void 0}this.flush(e)}))}flush(e){this._operationInProgress||e.wrapDetached("flush key backup",(async e=>{if(this._needsNewKey)return void e.set("needsNewKey",this._needsNewKey);this._stopped=!1,this._error=void 0,this._hasBackedUpAllKeys=!1;const t=this._runFlushOperation(e);this._operationInProgress=t,this.emit("change");try{await t.result,this._hasBackedUpAllKeys=!0}catch(t){this._stopped=!0,"HomeServerError"!==t.name||"M_WRONG_ROOM_KEYS_VERSION"!==t.errcode&&"M_NOT_FOUND"!==t.errcode?("AbortError"!==t.name||"StorageError"===t.name&&"AbortError"===t.errcode)&&(this._error=t):(e.set("wrong_version",!0),this._needsNewKey=!0),e.catch(t)}this._operationInProgress=void 0,this.emit("change")}))}_runFlushOperation(e){return new AbortableOperation((async(t,s)=>{const i=await this.backupConfigDeferred.promise;if(!i)return;let r=0,n=0;for(;;){const o=this.platform.random()*this.maxDelay,a=this.platform.clock.createTimeout(o);t(a),await a.elapsed();const l=await this.storage.readTxn([StoreNames.inboundGroupSessions]);t(l),r=n+await l.inboundGroupSessions.countNonBackedUpSessions(),s(new Progress(r,n));const c=(await l.inboundGroupSessions.getFirstNonBackedUpSessions(200)).map((e=>new StoredRoomKey(e)));if(0===c.length)return void e.set("total",r);const d=await this.encodeKeysForBackup(c,i.crypto),h=this.hsApi.uploadRoomKeysToBackup(i.info.version,d,{log:e});t(h),await h.response(),await this.markKeysAsBackedUp(c,t),n+=c.length,s(new Progress(r,n))}}))}async encodeKeysForBackup(e,t){const s={rooms:{}},i=s.rooms;for(const s of e){let e=i[s.roomId];e||(e=i[s.roomId]={sessions:{}}),e.sessions[s.sessionId]=await this.encodeRoomKey(s,t)}return s}async markKeysAsBackedUp(e,t){const s=await this.storage.readWriteTxn([StoreNames.inboundGroupSessions]);t(s);try{await Promise.all(e.map((e=>s.inboundGroupSessions.markAsBackedUp(e.roomId,e.senderKey,e.sessionId))))}catch(e){throw s.abort(),e}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;null==(e=this.backupInfoRequest)||e.abort(),null==(s=null==(t=this.backupConfigDeferred.value)?void 0:t.crypto)||s.dispose()}}class Progress{constructor(e,t){this.total=e,this.finished=t}}class Encryption{constructor({pickleKey:e,olm:t,account:s,keyLoader:i,storage:r,now:n,ownDeviceId:o}){this._pickleKey=e,this._olm=t,this._account=s,this._keyLoader=i,this._storage=r,this._now=n,this._ownDeviceId=o}discardOutboundSession(e,t){t.outboundGroupSessions.remove(e)}async createRoomKeyMessage(e,t){let s=await t.outboundGroupSessions.get(e);if(s){const t=new this._olm.OutboundGroupSession;try{return t.unpickle(this._pickleKey,s.session),this._createRoomKeyMessage(t,e)}finally{t.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 n=await i.outboundGroupSessions.get(e);r=await this._readOrCreateSession(s,n,e,t,i),r&&this._writeSession(this._now(),s,e,i)}catch(e){throw i.abort(),e}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 i=this._createRoomKeyMessage(e,s),n=new OutboundRoomKey(s,e,this._account.identityKeys);return await n.write(this._keyLoader,r),i}}_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 n=await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions,this._storage.storeNames.outboundGroupSessions]);let o,a;try{let l=await n.outboundGroupSessions.get(e);o=await this._readOrCreateSession(r,l,e,i,n),a=this._encryptContent(e,r,t,s);const c=o?this._now():l.createdAt;this._writeSession(c,r,e,n)}catch(e){throw n.abort(),e}return await n.complete(),new EncryptionResult(a,o)}finally{r&&r.free()}}_needsToRotate(e,t,s){let i=6048e5;Number.isSafeInteger(null==s?void 0:s.rotation_period_ms)&&(i=null==s?void 0:s.rotation_period_ms);let r=100;return Number.isSafeInteger(null==s?void 0:s.rotation_period_msgs)&&(r=null==s?void 0:s.rotation_period_msgs),this._now()>t+i||(e.message_index()>=r||void 0)}_encryptContent(e,t,s,i){const r=JSON.stringify({room_id:e,type:s,content:i}),n=t.encrypt(r);return{algorithm:MEGOLM_ALGORITHM,sender_key:this._account.identityKeys.curve25519,ciphertext:n,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:MEGOLM_ALGORITHM,chain_index:e.message_index()}}}class EncryptionResult{constructor(e,t){this.content=e,this.roomKeyMessage=t}}const ENCRYPTED_TYPE="m.room.encrypted",ROOM_HISTORY_VISIBILITY_TYPE="m.room.history_visibility",MIN_PRESHARE_INTERVAL=6e4;class RoomEncryption{constructor({room:e,deviceTracker:t,olmEncryption:s,megolmEncryption:i,megolmDecryption:r,encryptionParams:n,storage:o,keyBackup:a,notifyMissingMegolmSession:l,clock:c}){this._room=e,this._deviceTracker=t,this._olmEncryption=s,this._megolmEncryption=i,this._megolmDecryption=r,this._encryptionParams=n,this._senderDeviceCache=new Map,this._storage=o,this._keyBackup=a,this._notifyMissingMegolmSession=l,this._clock=c,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=groupEventsBySession(e.filter((e=>e.isEncrypted&&!e.isDecrypted&&e.event)).map((e=>e.event))),i=Array.from(s.values()),r=await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]),n=await Promise.all(i.map((async e=>this._megolmDecryption.hasSession(this._room.id,e.senderKey,e.sessionId,r)))),o=i.filter(((e,t)=>!n[t]));if(o.length)for(var a=o.length-1;a>=0;a--){const e=o[a];await t.wrap("session",(t=>this._requestMissingSessionFromBackup(e.senderKey,e.sessionId,t)))}}notifyTimelineClosed(){this._senderDeviceCache=new Map}async writeSync(e,t,s,i){let r=await this._loadHistoryVisibilityIfNeeded(this._historyVisibility,s);const n=[],o=[];if(await iterateResponseStateEvents(e,(e=>{var t;if(""===e.state_key&&"m.room.history_visibility"===e.type){const a=null==(t=null==e?void 0:e.content)?void 0:t.history_visibility;if(a!==r)return i.wrap({l:"history_visibility changed",from:r,to:a},(async e=>{r=a;const t=await this._deviceTracker.writeHistoryVisibility(this._room,r,s,e);n.push(...t.added),o.push(...t.removed)}))}})),t.size){const e=await this._deviceTracker.writeMemberChanges(this._room,t,r,s);n.push(...e.added),o.push(...e.removed)}o.length&&(i.log({l:"discardOutboundSession",leftUsers:o}),this._megolmEncryption.discardOutboundSession(this._room.id,s));let a=!1;return n.length&&(a=await this._addShareRoomKeyOperationForMembers(n,s,i)),{shouldFlush:a,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 e=await t.roomState.get(this._room.id,"m.room.history_visibility","");if(e)return null==(i=null==(s=e.event)?void 0:s.content)?void 0:i.history_visibility}return e}async prepareDecryptAll(e,t,s,i){var r,n,o;const a=new Map,l=[];for(const t of e)t.redacted_because||(null==(r=t.unsigned)?void 0:r.redacted_because)||((null==(n=t.content)?void 0:n.algorithm)!==MEGOLM_ALGORITHM&&a.set(t.event_id,new Error("Unsupported algorithm: "+(null==(o=t.content)?void 0:o.algorithm))),l.push(t));const c=await this._megolmDecryption.prepareDecryptAll(this._room.id,l,t,i);return new DecryptionPreparation(c,a,s,this,e)}async _processDecryptionResults(e,t,s,i,r,n){const o=e.filter((e=>{const t=s.get(e.event_id);return"MEGOLM_NO_SESSION"===(null==t?void 0:t.code)}));if(!o.length)return;const a=groupEventsBySession(o);i===DecryptionSource.Sync&&await Promise.all(Array.from(a.values()).map((async e=>{const t=e.events.map((e=>e.event_id));return this._megolmDecryption.addMissingKeyEventIds(this._room.id,e.senderKey,e.sessionId,t,r)}))),this._keyBackup&&n.wrapDetached("check key backup",(async e=>{if(e.set("source",i),e.set("events",o.length),e.set("sessions",a.size),i===DecryptionSource.Sync){if(await this._clock.createTimeout(1e4).elapsed(),this._disposed)return;const e=await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);await Promise.all(Array.from(a).map((async([t,s])=>{await this._megolmDecryption.hasSession(this._room.id,s.senderKey,s.sessionId,e)&&a.delete(t)})))}await Promise.all(Array.from(a.values()).map((t=>e.wrap("session",(e=>this._requestMissingSessionFromBackup(t.senderKey,t.sessionId,e))))))}))}async _verifyDecryptionResults(e,t){await Promise.all(e.map((async e=>{let s=this._senderDeviceCache.get(e.senderCurve25519Key);s||(s=await this._deviceTracker.getDeviceByCurve25519Key(e.senderCurve25519Key,t),this._senderDeviceCache.set(e.senderCurve25519Key,s)),s&&e.setDevice(s)})))}async _fetchKeyAndVerifyDecryptionResults(e,t,s){const i=e.filter((e=>e.isVerificationUnknown));return i.length?s.wrap("fetch unverified senders",(async e=>{const s=Array.from(i.reduce(((e,t)=>e.add(t.encryptedEvent.sender)),new Set));e.set("senders",s),await this._deviceTracker.devicesForUsers(s,t,e);const r=await this._storage.readTxn([this._storage.storeNames.deviceKeys]);await this._verifyDecryptionResults(i,r);const n=i.filter((e=>!e.isVerificationUnknown)).reduce(((e,t)=>(e.set(t.encryptedEvent.event_id,t),e)),new Map);return new BatchDecryptionResult(n,new Map,this)})):new BatchDecryptionResult(new Map,new Map,this)}async _requestMissingSessionFromBackup(e,t,s){if(!this._keyBackup)return s.set("enabled",!1),void this._notifyMissingMegolmSession();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)return s.set("wrong_sender_key",i.senderKey),void(s.logLevel=s.level.Warn);let t,r=!1;const n=await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]);try{r=await this._megolmDecryption.writeRoomKey(i,n),s.set("isBetter",r),r&&(t=i.eventIds)}catch(e){throw n.abort(),e}await n.complete(),r&&await s.wrap("retryDecryption",(e=>this._room.notifyRoomKey(i,t||[],e)))}}catch(e){"HomeServerError"!==e.name||"M_NOT_FOUND"!==e.errcode?s.set("not_found",!0):(s.error=e,s.logLevel=s.level.Error)}}getEventIdsForMissingKey(e,t){return this._megolmDecryption.getEventIdsForMissingKey(this._room.id,e.senderKey,e.sessionId,t)}async ensureMessageKeyIsShared(e,t){var s;if(!((null==(s=this._lastKeyPreShareTime)?void 0:s.measure())<6e4)){this._lastKeyPreShareTime=this._clock.createMeasure();try{this._keySharePromise=(async()=>{var s;const i=await this._megolmEncryption.ensureOutboundSession(this._room.id,this._encryptionParams);i&&(null==(s=this._keyBackup)||s.flush(t),await t.wrap("share key",(t=>this._shareNewRoomKey(i,e,t))))})(),await this._keySharePromise}finally{this._keySharePromise=null}}}async encrypt(e,t,s,i){var r;this._keySharePromise&&(i.set("waitForRunningKeyShare",!0),await this._keySharePromise);const n=await i.wrap("megolm encrypt",(()=>this._megolmEncryption.encrypt(this._room.id,e,t,this._encryptionParams)));return n.roomKeyMessage&&(null==(r=this._keyBackup)||r.flush(i),await i.wrap("share key",(e=>this._shareNewRoomKey(n.roomKeyMessage,s,e)))),{type:ENCRYPTED_TYPE,content:n.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(((e,t)=>e.add(t.user_id)),new Set));let n,o=await this._storage.readWriteTxn([this._storage.storeNames.operations]);try{n=this._writeRoomKeyShareOperation(e,r,o)}catch(e){throw o.abort(),e}await this._processShareRoomKeyOperation(n,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)}async flushPendingRoomKeyShares(e,t,s){if(!this._isFlushingRoomKeyShares){this._isFlushingRoomKeyShares=!0;try{if(!t){const e=await this._storage.readTxn([this._storage.storeNames.operations]);t=await e.operations.getAllByTypeAndScope("share_room_key",this._room.id)}for(const i of t)"share_room_key"===i.type&&await s.wrap("operation",(t=>this._processShareRoomKeyOperation(i,e,t)))}finally{this._isFlushingRoomKeyShares=!1}}}_writeRoomKeyShareOperation(e,t,s){const i={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(i),i}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",(s=>this._olmEncryption.encrypt("m.room_key",e.roomKeyMessage,i,t,s))),n=i.filter((e=>!r.some((t=>t.device===e))));await s.wrap("send",(e=>this._sendMessagesToDevices(ENCRYPTED_TYPE,r,t,e))),n.length&&await s.wrap("missingDevices",(async s=>{s.set("devices",n.map((e=>e.device_id)));const i=e.userIds.filter((e=>n.some((t=>t.user_id===e))));s.set("unsentUserIds",i),e.userIds=i,await this._updateOperationsStore((t=>t.update(e)));const r=this._megolmEncryption.createWithheldMessage(e.roomKeyMessage,"m.no_olm","OTKs exhausted");await this._sendSharedMessageToDevices("org.matrix.room_key.withheld",r,n,t,s)})),await this._updateOperationsStore((t=>t.remove(e.id)))}async _updateOperationsStore(e){const t=await this._storage.readWriteTxn([this._storage.storeNames.operations]);try{e(t.operations)}catch(e){throw t.abort(),e}await t.complete()}async _sendSharedMessageToDevices(e,t,s,i,r){const n=groupBy(s,(e=>e.user_id)),o={messages:Array.from(n.entries()).reduce(((e,[s,i])=>(e[s]=i.reduce(((e,s)=>(e[s.device_id]=t,e)),{}),e)),{})},a=makeTxnId();await i.sendToDevice(e,o,a,{log:r}).response()}async _sendMessagesToDevices(e,t,s,i){i.set("messages",t.length);const r=formatToDeviceMessagesPayload(t),n=makeTxnId();await s.sendToDevice(e,r,n,{log:i}).response()}filterUndecryptedEventEntriesForKeys(e,t){return e.filter((e=>{var s,i;if(e.isEncrypted&&!e.isDecrypted){const{event:r}=e;if(r){const e=null==(s=r.content)?void 0:s.sender_key,n=null==(i=r.content)?void 0:i.session_id;return t.some((t=>e===t.senderKey&&n===t.sessionId))}}return!1}))}dispose(){this._disposed=!0}}class DecryptionPreparation{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 DecryptionChanges(await this._megolmDecryptionPreparation.decrypt(),this._extraErrors,this._source,this._roomEncryption,this._events)}dispose(){this._megolmDecryptionPreparation.dispose()}}class DecryptionChanges{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 mergeMap(this._extraErrors,i),await this._roomEncryption._processDecryptionResults(this._events,s,i,this._source,e,t),new BatchDecryptionResult(s,i,this._roomEncryption)}}class BatchDecryptionResult{constructor(e,t,s){this.results=e,this.errors=t,this._roomEncryption=s}applyToEntries(e,t=void 0){for(const s of e){const e=this.results.get(s.id);if(e)s.setDecryptionResult(e),null==t||t(s);else{const e=this.errors.get(s.id);e&&(s.setDecryptionError(e),null==t||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 LockMap{constructor(){this._map=new Map}async takeLock(e){let t=this._map.get(e);return t?await t.take():(t=new Lock,t.tryTake(),this._map.set(e,t)),t.released().then((()=>{Promise.resolve().then((()=>{t.isTaken||this._map.delete(e)}))})),t}}class DecryptionError extends Error{constructor(e,t){super(e),this.reason=t}}class SecretStorage{constructor({key:e,platform:t,storage:s}){this._key=e,this._platform=t,this._storage=s}async hasValidKeyForAnyAccountData(){const e=await this._storage.readTxn([this._storage.storeNames.accountData]),t=await e.accountData.getAll();for(const e of t)try{await this._decryptAccountData(e);return!0}catch(e){if(e instanceof DecryptionError&&0!==e.reason)throw e;continue}return!1}async readSecret(e){const t=await this._storage.readTxn([this._storage.storeNames.accountData]),s=await t.accountData.get(e);if(s)return await this._decryptAccountData(s)}async _decryptAccountData(e){var t,s;const i=null==(s=null==(t=null==e?void 0:e.content)?void 0:t.encrypted)?void 0:s[this._key.id];if(!i)throw new DecryptionError(`Secret ${e.type} is not encrypted for key ${this._key.id}`,0);if("m.secret_storage.v1.aes-hmac-sha2"===this._key.algorithm)return await this._decryptAESSecret(e.type,i);throw new DecryptionError(`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),n=r.slice(0,32),o=r.slice(32),a=s.decode(t.ciphertext);if(!await this._platform.crypto.hmac.verify(o,s.decode(t.mac),a,"SHA-256"))throw new DecryptionError("Bad MAC",1);const l=await this._platform.crypto.aes.decryptCTR({key:n,iv:s.decode(t.iv),data:a});return i.decode(l)}}function recursivelyAssign(e,t,s=!1){for(const[i,r]of Object.entries(t))e[i]instanceof Object&&r?recursivelyAssign(e[i],r):null==r&&s||(e[i]=r);return e}
/*! *****************************************************************************
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 TrackKind=(e=>(e.Video="video",e.Audio="audio",e))(TrackKind||{});function getStreamAudioTrack(e){return null==e?void 0:e.getAudioTracks()[0]}function getStreamVideoTrack(e){return null==e?void 0:e.getVideoTracks()[0]}function mute(e,t,s){return s.wrap("mute",(s=>{s.set("cameraMuted",t.camera),s.set("microphoneMuted",t.microphone);const i=getStreamAudioTrack(e.userMedia);if(i){const e=!t.microphone;s.set("microphone enabled",e),i.enabled=e}const r=getStreamVideoTrack(e.userMedia);if(r){const e=!t.camera;s.set("camera enabled",e),r.enabled=e}}))}class MuteSettings{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=!!getStreamAudioTrack(e),this.hasCameraTrack=!!getStreamVideoTrack(e)}get microphone(){return!this.hasMicrophoneTrack||this.isMicrophoneMuted}get camera(){return!this.hasCameraTrack||this.isCameraMuted}toggleCamera(){return new MuteSettings(this.microphone,!this.camera,this.hasMicrophoneTrack,this.hasCameraTrack)}toggleMicrophone(){return new MuteSettings(!this.microphone,this.camera,this.hasMicrophoneTrack,this.hasCameraTrack)}equals(e){return this.microphone===e.microphone&&this.camera===e.camera}}const CALL_LOG_TYPE="call",CALL_MEMBER_VALIDITY_PERIOD_MS=36e5;var IncomingMessageAction=(e=>(e[e.InviteGlare=0]="InviteGlare",e[e.Handle=1]="Handle",e[e.Ignore=2]="Ignore",e))(IncomingMessageAction||{});class RemoteMedia{constructor(e,t){this.userMedia=e,this.screenShare=t}}class PeerCall{constructor(e,t,s){this.callId=e,this.options=t,this.logItem=s,this._state=CallState.Fledgling,this.candidateSendQueue=[],this.remoteCandidateBuffer=new Map,this.disposables=new Disposables,this.statePromiseMap=new Map,this._remoteTrackToStreamId=new Map,this._remoteStreams=new Map,this.makingOffer=!1,this.ignoreOffer=!1,this.sentEndOfCandidates=!1,this._remoteMuteSettings=new MuteSettings,this.onIceConnectionStateChange=async(e,t)=>{var s,i;if(this._state===CallState.Ended)return;let r=!1;if("connected"==e)null==(s=this.iceDisconnectedTimeout)||s.abort(),this.iceDisconnectedTimeout=void 0,this.setState(CallState.Connected,t);else if("failed"==e)r=!0,null==(i=this.iceDisconnectedTimeout)||i.abort(),this.iceDisconnectedTimeout=void 0,await this._hangup(CallErrorCode.IceFailed,t);else if("disconnected"==e){r=!0,this.iceDisconnectedTimeout=this.options.createTimeout(3e4);try{await this.iceDisconnectedTimeout.elapsed(),await this._hangup(CallErrorCode.IceFailed,t)}catch(e){if(!(e instanceof AbortError))throw e}}if(r){const e=await this.peerConnection.getStats(),s={};e.forEach(((e,t)=>{s[t]=e})),t.set("peerConnectionStats",s)}},s.log({l:"create PeerCall",id:e}),this._remoteMedia=new RemoteMedia,this.peerConnection=t.webRTC.createPeerConnection(this.options.forceTURN,[this.options.turnServer.get()],0),this.disposables.track(this.options.turnServer.subscribe((e=>{this.logItem.log({l:"updating turn server",turnServer:e}),this.peerConnection.setConfiguration({iceServers:[e]})})));const i=(e,t,s)=>{const i=e=>{this.options.errorBoundary.try((()=>t(e)))};this.peerConnection.addEventListener(e,i);this.disposables.track((()=>{this.peerConnection.removeEventListener(e,i)}))};i("iceconnectionstatechange",(async()=>{const e=this.peerConnection.iceConnectionState;await s.wrap({l:"onIceConnectionStateChange",status:e},(async t=>{await this.onIceConnectionStateChange(e,t)}))})),i("icecandidate",(async e=>{await s.wrap("onLocalIceCandidate",(async t=>{e.candidate&&await this.handleLocalIceCandidate(e.candidate,t)}))})),i("icegatheringstatechange",(async()=>{const e=this.peerConnection.iceGatheringState;await s.wrap({l:"onIceGatheringStateChange",status:e},(async t=>{await this.handleIceGatheringState(e,t)}))})),i("track",(e=>{s.wrap("onRemoteTrack",(t=>{this.onRemoteTrack(e.track,e.streams,t)}))})),i("datachannel",(e=>{s.wrap("onRemoteDataChannel",(t=>{this._dataChannel=e.channel,this.options.emitUpdate(this,void 0,t)}))})),i("negotiationneeded",(()=>{var e,t;const i=this.peerConnection.signalingState,r=()=>s.wrap({l:"onNegotiationNeeded",signalingState:i},(e=>this.handleNegotiation(e)));this.responsePromiseChain=null!=(t=null==(e=this.responsePromiseChain)?void 0:e.then(r))?t:r(),this.responsePromiseChain.catch((e=>this.options.errorBoundary.reportError(e)))}))}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 s=>{var i;this._state===CallState.Fledgling&&(s.set("signalingState",this.peerConnection.signalingState),this.direction=CallDirection.Outbound,this.setState(CallState.CreateOffer,s),this.localMuteSettings=t,await this.updateLocalMedia(e,s),(null==(i=this.localMedia)?void 0:i.dataChannelOptions)&&(this._dataChannel=this.peerConnection.createDataChannel("channel",this.localMedia.dataChannelOptions)),await this.waitForState([CallState.InviteSent,CallState.CreateAnswer]))}))}answer(e,t,s){return s.wrap("answer",(async s=>{if(this._state!==CallState.Ringing)return;let i;this.setState(CallState.CreateAnswer,s),this.localMuteSettings=t,await this.updateLocalMedia(e,s);try{i=await this.peerConnection.createAnswer()}catch(e){return void await s.wrap("Failed to create answer",(t=>{t.catch(e),this.terminate(CallParty.Local,CallErrorCode.CreateAnswer,t)}))}try{await this.peerConnection.setLocalDescription(i),this.setState(CallState.Connecting,s)}catch(e){return void await s.wrap("Error setting local description!",(t=>{t.catch(e),this.terminate(CallParty.Local,CallErrorCode.SetLocalDescription,t)}))}try{await this.delay(200)}catch(e){return}await this.sendAnswer(s)}))}setMedia(e,t){return t.wrap("setMedia",(async t=>{t.set("userMedia_audio",!!getStreamAudioTrack(e.userMedia)),t.set("userMedia_video",!!getStreamVideoTrack(e.userMedia)),t.set("screenShare_video",!!getStreamVideoTrack(e.screenShare)),t.set("datachannel",!!e.dataChannelOptions),await this.updateLocalMedia(e,t);const s={call_id:this.callId,version:1,[SDPStreamMetadataKey]:this.getSDPMetadata()};await this.sendSignallingMessage({type:EventType.SDPStreamMetadataChangedPrefix,content:s},t)}))}setMuted(e,t){return t.wrap("setMuted",(async t=>{if(this.localMuteSettings=e,t.set("cameraMuted",e.camera),t.set("microphoneMuted",e.microphone),this.localMedia){mute(this.localMedia,e,t);const s={call_id:this.callId,version:1,[SDPStreamMetadataKey]:this.getSDPMetadata()};await this.sendSignallingMessage({type:EventType.SDPStreamMetadataChangedPrefix,content:s},t)}}))}hangup(e,t){return t.wrap("hangup",(t=>this._hangup(e,t)))}async _hangup(e,t){this._state!==CallState.Ended&&this._state!==CallState.Ending&&(this.setState(CallState.Ending,t),await this.sendHangupWithCallId(this.callId,e,t),this.terminate(CallParty.Local,e,t))}getMessageAction(e){const t=this.callId===e.content.call_id;return e.type!==EventType.Invite||t?t?1:2:0}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 s=>{var r;if(i=s,1===this.getMessageAction(e))switch(e.type){case EventType.Invite:await this.handleFirstInvite(e.content,t,s);break;case EventType.Answer:await this.handleAnswer(e.content,t,s);break;case EventType.Negotiate:await this.onNegotiateReceived(e.content,s);break;case EventType.Candidates:await this.handleRemoteIceCandidates(e.content,t,s);break;case EventType.SDPStreamMetadataChanged:case EventType.SDPStreamMetadataChangedPrefix:this.updateRemoteSDPStreamMetadata(e.content[SDPStreamMetadataKey],s);break;case EventType.Hangup:s.set("reason",e.content.reason),this.terminate(CallParty.Remote,null!=(r=e.content.reason)?r:CallErrorCode.UserHangup,s);break;default:s.log(`Unknown event type for call: ${e.type}`)}else s.set("wrongCallId",!0)})),i}sendHangupWithCallId(e,t,s){const i={call_id:e,version:1};return t&&(i.reason=t),this.sendSignallingMessage({type:EventType.Hangup,content:i},s)}async handleNegotiation(e){this.makingOffer=!0;try{try{await this.peerConnection.setLocalDescription()}catch(t){return e.log("Error setting local description!").catch(t),void this.terminate(CallParty.Local,CallErrorCode.SetLocalDescription,e)}if("gathering"===this.peerConnection.iceGatheringState)try{await this.delay(200)}catch(e){return}if(this._state===CallState.Ended)return;const t=this.peerConnection.localDescription;if(e.set("includedCandidates",this.candidateSendQueue.length),this.candidateSendQueue=[],this._state===CallState.CreateOffer){const s={call_id:this.callId,offer:t,[SDPStreamMetadataKey]:this.getSDPMetadata(),version:1,lifetime:CALL_TIMEOUT_MS};await this.sendSignallingMessage({type:EventType.Invite,content:s},e),this.setState(CallState.InviteSent,e)}else if(this._state===CallState.Connected||this._state===CallState.Connecting){const s={call_id:this.callId,description:t,[SDPStreamMetadataKey]:this.getSDPMetadata(),version:1,lifetime:CALL_TIMEOUT_MS};await this.sendSignallingMessage({type:EventType.Negotiate,content:s},e)}}finally{this.makingOffer=!1}if(this.sendCandidateQueue(e),this._state===CallState.InviteSent){const t=this.logItem.child("invite timeout");e.refDetached(t),await t.run((async e=>{try{await this.delay(CALL_TIMEOUT_MS)}catch(e){return}this._state===CallState.InviteSent&&await this._hangup(CallErrorCode.InviteTimeout,e)}))}}handleInviteGlare(e,t,s){if(e.type!==EventType.Invite)return{shouldReplace:!1};const{content:i}=e,r=i.call_id,n=this.callId>r;let o;return s.wrap("handling call glare",(async e=>{o=e,n?(e.log("Glare detected: answering incoming call "+r+" and canceling outgoing call "),this._state!==CallState.Fledgling&&this._state!==CallState.CreateOffer&&await this.sendHangupWithCallId(this.callId,CallErrorCode.Replaced,e),this.close(CallErrorCode.Replaced,e),this.dispose()):(e.log("Glare detected: rejecting incoming call "+r+" and keeping outgoing call "),await this.sendHangupWithCallId(r,CallErrorCode.Replaced,e))})),{shouldReplace:n,log:o}}handleHangupReceived(e,t){this.terminate(CallParty.Remote,e.reason||CallErrorCode.UserHangup,t)}async handleFirstInvite(e,t,s){this._state===CallState.Fledgling&&void 0===this.opponentPartyId&&await this.handleInvite(e,t,s)}async handleInvite(e,t,s){var i;this.opponentPartyId=t,this.direction=CallDirection.Inbound;const r=e[SDPStreamMetadataKey];r?this.updateRemoteSDPStreamMetadata(r,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(e){return void await s.wrap("Call failed to set remote description",(async t=>(t.catch(e),this.terminate(CallParty.Local,CallErrorCode.SetRemoteDescription,t))))}if(0!==this.peerConnection.getReceivers().length){this.setState(CallState.Ringing,s);try{await this.delay(null!=(i=e.lifetime)?i:CALL_TIMEOUT_MS)}catch(e){return}this._state===CallState.Ringing&&(s.log("Invite has expired. Hanging up."),this.hangupParty=CallParty.Remote,this.setState(CallState.Ended,s),"closed"!=this.peerConnection.signalingState&&this.peerConnection.close())}else await s.wrap("Call no remote stream or no tracks after setting remote description!",(async e=>this.terminate(CallParty.Local,CallErrorCode.SetRemoteDescription,e)))}async handleAnswer(e,t,s){if(this._state===CallState.Ended)return void s.log("Ignoring answer because call has ended");if(void 0!==this.opponentPartyId)return void s.log(`Ignoring answer: we already have an answer/reject from ${this.opponentPartyId}`);this.opponentPartyId=t,await this.addBufferedIceCandidates(s),this.setState(CallState.Connecting,s);const i=e[SDPStreamMetadataKey];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(e){return void await s.wrap("Failed to set remote description",(t=>{t.catch(e),this.terminate(CallParty.Local,CallErrorCode.SetRemoteDescription,t)}))}}async handleIceGatheringState(e,t){if("complete"===e&&!this.sentEndOfCandidates){const e={candidate:""};await this.queueCandidate(e,t),this.sentEndOfCandidates=!0}}async handleLocalIceCandidate(e,t){t.set("sdpMid",e.sdpMid),t.set("candidate",e.candidate),this._state!==CallState.Ended&&(""===e.candidate&&this.sentEndOfCandidates||(await this.queueCandidate(e,t),""===e.candidate&&(this.sentEndOfCandidates=!0)))}async handleRemoteIceCandidates(e,t,s){if(this.state===CallState.Ended)return void s.log("Ignoring remote ICE candidate because call has ended");const i=e.candidates;if(!i)return void s.log("Ignoring candidates event with no candidates!");const r=0===e.version?null:t||null;if(void 0===this.opponentPartyId){s.log(`Buffering ${i.length} candidates until we pick an opponent`);const e=this.remoteCandidateBuffer.get(r)||[];return e.push(...i),void this.remoteCandidateBuffer.set(r,e)}this.opponentPartyId===t?await this.addIceCandidates(i,s):s.log(`Ignoring candidates from party ID ${t}: we have chosen party ID ${this.opponentPartyId}`)}async onNegotiateReceived(e,t){const s=e.description;if(!s||!s.sdp||!s.type)return void t.log("Ignoring invalid m.call.negotiate event");const i=this.direction===CallDirection.Inbound,r="offer"===s.type&&(this.makingOffer||"stable"!==this.peerConnection.signalingState);if(this.ignoreOffer=!i&&r,this.ignoreOffer)return void t.log("Ignoring colliding negotiate event because we're impolite");const n=e[SDPStreamMetadataKey];n?this.updateRemoteSDPStreamMetadata(n,t):t.log("Received negotiation event without SDPStreamMetadata!");try{if(await this.peerConnection.setRemoteDescription(s),"offer"===s.type){await this.peerConnection.setLocalDescription();const e={call_id:this.callId,description:this.peerConnection.localDescription,[SDPStreamMetadataKey]:this.getSDPMetadata(),version:1,lifetime:CALL_TIMEOUT_MS};await this.sendSignallingMessage({type:EventType.Negotiate,content:e},t)}}catch(e){t.log("Failed to complete negotiation").catch(e)}}async sendAnswer(e){const t=this.peerConnection.localDescription,s={call_id:this.callId,version:1,answer:{sdp:t.sdp,type:t.type},[SDPStreamMetadataKey]:this.getSDPMetadata()};e.log(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in answer`),this.candidateSendQueue=[];try{await this.sendSignallingMessage({type:EventType.Answer,content:s},e)}catch(t){throw this.terminate(CallParty.Local,CallErrorCode.SendAnswer,e),t}this.sendCandidateQueue(e)}async queueCandidate(e,t){var s;if(this.candidateSendQueue.push(e),this._state===CallState.Ringing)return;this.flushCandidatesLog=null!=(s=this.flushCandidatesLog)?s:this.logItem.child("flush candidate queue"),t.refDetached(this.flushCandidatesLog);const{flushCandidatesLog:i}=this;try{await this.delay(this.direction===CallDirection.Inbound?500:2e3)}catch(e){return}this.sendCandidateQueue(i),this.flushCandidatesLog=void 0}async sendCandidateQueue(e){if(0===this.candidateSendQueue.length||this._state===CallState.Ended)return;const t=this.candidateSendQueue;return this.candidateSendQueue=[],e.wrap({l:"send candidates",size:t.length},(async e=>{try{await this.sendSignallingMessage({type:EventType.Candidates,content:{call_id:this.callId,version:1,candidates:t}},e),await this.sendCandidateQueue(e)}catch(t){e.catch(t),this.terminate(CallParty.Local,CallErrorCode.SignallingFailed,e)}}))}updateRemoteSDPStreamMetadata(e,t){this.remoteSDPStreamMetadata=recursivelyAssign(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 e;e=null!==s.sdpMid&&void 0!==s.sdpMid||null!==s.sdpMLineIndex&&void 0!==s.sdpMLineIndex?t.log(`Adding remote ICE ${s.sdpMid} candidate: ${s.candidate}`):t.log("Got remote end-of-ICE candidates");try{await this.peerConnection.addIceCandidate(s)}catch(t){this.ignoreOffer||e.catch(t)}}}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((e=>{let t=this.statePromiseMap.get(e);if(!t){let s;const i=new Promise((e=>{s=e}));t={resolve:s,promise:i},this.statePromiseMap.set(e,t)}return t.promise})))}terminate(e,t,s){this._state!==CallState.Ended&&(this.hangupParty=e,this._hangupReason=t,this.setState(CallState.Ended,s),this.localMedia=void 0,this.peerConnection&&"closed"!==this.peerConnection.signalingState&&this.peerConnection.close())}getSDPMetadata(){var e,t,s,i,r,n;const o={};if(null==(e=this.localMedia)?void 0:e.userMedia){o[this.localMedia.userMedia.id]={purpose:SDPStreamMetadataPurpose.Usermedia,audio_muted:null!=(s=null==(t=this.localMuteSettings)?void 0:t.microphone)&&s,video_muted:null!=(r=null==(i=this.localMuteSettings)?void 0:i.camera)&&r}}if(null==(n=this.localMedia)?void 0:n.screenShare){o[this.localMedia.screenShare.id]={purpose:SDPStreamMetadataPurpose.Screenshare}}return o}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(null==(s=t.sender.track)?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((e=>e.id))),0===t.length)return void s.log({l:`ignoring ${e.kind} streamless track`,id:e.id});const i=t[0];if(this._remoteTrackToStreamId.set(e.id,i.id),!this._remoteStreams.has(i.id)){const e=e=>{this.logItem.wrap({l:"removetrack",id:e.track.id},(s=>{const r=this._remoteTrackToStreamId.get(e.track.id);if(r){this._remoteTrackToStreamId.delete(e.track.id);const n=this._remoteStreams.get(r);n&&0===n.stream.getTracks().length&&(this.disposables.disposeTracked(t),this._remoteStreams.delete(i.id),this.updateRemoteMedia(s))}}))};i.addEventListener("removetrack",e);const t=()=>{i.removeEventListener("removetrack",e)};this.disposables.track(t),this._remoteStreams.set(i.id,{disposeListener:t,stream:i})}this.updateRemoteMedia(s)}updateRemoteMedia(e){e.wrap("reevaluating remote media",(e=>{var t,s;if(this._remoteMedia.userMedia=void 0,this._remoteMedia.screenShare=void 0,this.remoteSDPStreamMetadata)for(const i of this._remoteStreams.values()){const{stream:r}=i,n=this.remoteSDPStreamMetadata[r.id];if(n)if(n.purpose===SDPStreamMetadataPurpose.Usermedia){this._remoteMedia.userMedia=r;const i=this.findReceiverForStream(TrackKind.Audio,r.id);i&&(i.track.enabled=!n.audio_muted);const o=this.findReceiverForStream(TrackKind.Video,r.id);o&&(o.track.enabled=!n.video_muted),this._remoteMuteSettings=new MuteSettings(null!=(t=n.audio_muted)&&t,null!=(s=n.video_muted)&&s,!!(null==i?void 0:i.track),!!(null==o?void 0:o.track)),e.log({l:"setting userMedia",micMuted:this._remoteMuteSettings.microphone,cameraMuted:this._remoteMuteSettings.camera})}else n.purpose===SDPStreamMetadataPurpose.Screenshare&&(this._remoteMedia.screenShare=r,e.log("setting screenShare"));else e.log({l:"no metadata yet for stream, ignoring for now",id:r.id})}this.options.emitUpdate(this,void 0,e)}))}updateLocalMedia(e,t){return t.wrap("updateLocalMedia",(async t=>{var s,i;const r=this.peerConnection.getSenders(),n=async(e,s,i)=>{const n=async(n,o)=>{const a=r.find((e=>e.track===n)),l=null!=e?e:s;if(l!==s&&(n&&(l.removeTrack(n),n.stop()),o&&l.addTrack(o)),o&&a)try{return void await t.wrap(`attempting to replace ${i} ${o.kind} track`,(e=>a.replaceTrack(o)))}catch(e){}a&&t.wrap(`removing ${i} ${a.track.kind} track`,(e=>{this.peerConnection.removeTrack(a)})),o&&t.wrap(`adding ${i} ${o.kind} track`,(e=>{const t=this.peerConnection.addTrack(o,l);this.options.webRTC.prepareSenderForPurpose(this.peerConnection,t,i)}))};(e||s)&&(await n(getStreamAudioTrack(e),getStreamAudioTrack(s)),await n(getStreamVideoTrack(e),getStreamVideoTrack(s)))};await n(null==(s=this.localMedia)?void 0:s.userMedia,null==e?void 0:e.userMedia,SDPStreamMetadataPurpose.Usermedia),await n(null==(i=this.localMedia)?void 0:i.screenShare,null==e?void 0:e.screenShare,SDPStreamMetadataPurpose.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 t=>this.options.sendSignallingMessage(e,t)))}dispose(){var e;this.disposables.dispose(),null==(e=this.iceDisconnectedTimeout)||e.abort(),this.peerConnection.close(),this.options.emitUpdate=(e,t,s)=>{s.log("emitting update from PeerCall after disposal",this.logItem.level.Error)}}close(e,t){void 0===e&&(e=CallErrorCode.UserHangup),this.terminate(CallParty.Local,e,t)}}var CallParty=(e=>(e.Local="local",e.Remote="remote",e))(CallParty||{}),CallState=(e=>(e.Fledgling="fledgling",e.CreateOffer="create_offer",e.InviteSent="invite_sent",e.CreateAnswer="create_answer",e.Connecting="connecting",e.Connected="connected",e.Ringing="ringing",e.Ending="ending",e.Ended="ended",e))(CallState||{}),CallDirection=(e=>(e.Inbound="inbound",e.Outbound="outbound",e))(CallDirection||{});const CALL_TIMEOUT_MS=6e4;function handlesEventType(e){return e===EventType.Invite||e===EventType.Candidates||e===EventType.Answer||e===EventType.Hangup||e===EventType.SDPStreamMetadataChanged||e===EventType.SDPStreamMetadataChangedPrefix||e===EventType.Negotiate}class ErrorBoundary{constructor(e){this.errorCallback=e}try(e,t){try{let s=e();return s instanceof Promise&&(s=s.catch((e=>(this._error=e,this.reportError(e),t)))),s}catch(e){return this._error=e,this.reportError(e),t}}reportError(e){try{this.errorCallback(e)}catch(e){console.error("error in ErrorBoundary callback",e)}}get error(){return this._error}}const errorCodesWithoutRetry=[CallErrorCode.UserHangup,CallErrorCode.AnsweredElsewhere,CallErrorCode.Replaced,CallErrorCode.UserBusy,CallErrorCode.Transfered,CallErrorCode.NewSession];class MemberConnection{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(0===this.queuedSignallingMessages.length)return!1;const e=this.queuedSignallingMessages[0].content.seq;return void 0!==this.lastIgnoredSeqNr&&e===this.lastIgnoredSeqNr+1||(void 0===this.lastProcessedSeqNr?0===e:e<=this.lastProcessedSeqNr+1)}dispose(){var e;null==(e=this.peerCall)||e.dispose(),this.localMedia.dispose(),this.logItem.finish()}}class Member{constructor(e,t,s,i,r,n){this.member=e,this.callDeviceMembership=t,this._deviceIndex=s,this._eventTimestamp=i,this.options=r,this.errorBoundary=new ErrorBoundary((e=>{this.emitMemberUpdate(this,"error"),this.connection&&this.connection.logItem.log("error at boundary").catch(e)})),this.emitUpdateFromPeerCall=async(e,t,s)=>{const i=this.connection;if(e.state===CallState.Ringing)i.logItem.wrap("ringing, answer peercall",(t=>(s.refDetached(t),e.answer(i.localMedia,i.localMuteSettings,t))));else if(e.state===CallState.Ended){const t=e.hangupReason;if(e.dispose(),i.peerCall=void 0,t&&!errorCodesWithoutRetry.includes(t)){i.retryCount+=1;const{retryCount:e}=i;await i.logItem.wrap({l:"retry connection",retryCount:e},(async t=>{if(s.refDetached(t),e<=3)await this.callIfNeeded(t);else{const e=await this.disconnect(!1);e&&t.refDetached(e)}}))}}this.emitMemberUpdate(this,t)},this.sendSignallingMessage=async(e,t)=>{const s=e;let i;s.content.seq=this.connection.outboundSeqCounter++,s.content.conf_id=this.options.confId,s.content.device_id=this.options.ownDeviceId,s.content.party_id=this.options.ownDeviceId,s.content.sender_session_id=this.options.sessionId,s.content.dest_session_id=this.sessionId;let r=e.type;const n=await this.options.encryptDeviceMessage(this.member.userId,this.deviceId,s,t);n?(i=formatToDeviceMessagesPayload(n),r="m.room.encrypted"):i=formatToDeviceMessagesPayload([{content:s.content,device:this}]),t.set("payload",s.content);const o=this.options.hsApi.sendToDevice(r,i,makeTxnId(),{log:t});await o.response()},this.emitMemberUpdate=this.options.emitUpdate,this._renewExpireTimeout(n)}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 t;null==(t=this.expireTimeout)||t.dispose(),this.expireTimeout=void 0;const s=memberExpiresAt(this.callDeviceMembership);if("number"!=typeof s)return;const i=Math.max(0,s-this.options.clock.now());null==e||e.set("expiresIn",i),this.expireTimeout=this.options.clock.createTimeout(i+10),this.expireTimeout.elapsed().then((()=>{this.emitMemberUpdate(this,"isExpired")}),(e=>{}))}get logItem(){var e;return null==(e=this.connection)?void 0:e.logItem}get remoteMedia(){var e,t;return null==(t=null==(e=this.connection)?void 0:e.peerCall)?void 0:t.remoteMedia}get isExpired(){return!this.isConnected&&isMemberExpired(this.callDeviceMembership,this.options.clock.now())}get remoteMuteSettings(){var e,t;return null==(t=null==(e=this.connection)?void 0:e.peerCall)?void 0:t.remoteMuteSettings}get isConnected(){var e,t;return(null==(t=null==(e=this.connection)?void 0:e.peerCall)?void 0:t.state)===CallState.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 null==(t=null==(e=this.connection)?void 0:e.peerCall)?void 0:t.dataChannel}get deviceIndex(){return this._deviceIndex}get eventTimestamp(){return this._eventTimestamp}connect(e,t,s,i){return this.errorBoundary.try((async()=>{if(this.connection)return;const r=new MemberConnection(e.clone(),t,s,i);let n;return this.connection=r,await r.logItem.wrap("connect",(async e=>{n=e,await this.callIfNeeded(e)})),n}))}callIfNeeded(e){return e.wrap("callIfNeeded",(async e=>{let t;if(t=this.member.userId===this.options.ownUserId?this.deviceId>this.options.ownDeviceId:this.member.userId>this.options.ownUserId,t){const t=this.connection;t.peerCall=this._createPeerCall(makeId("c")),await t.peerCall.call(t.localMedia,t.localMuteSettings,e)}else e.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(CallErrorCode.UserHangup,i)})),t.dispose(),this.connection=void 0,s}))}updateCallInfo(e,t,s,i){this.errorBoundary.try((()=>{this.callDeviceMembership=e,this._deviceIndex=t,this._eventTimestamp=s,this._renewExpireTimeout(i),this.connection&&this.connection.logItem.refDetached(i)}))}updateRoomMember(e){this.member=e,this.emitMemberUpdate(this)}handleDeviceMessage(e,t){this.errorBoundary.try((()=>{var s;t.wrap({l:"Member.handleDeviceMessage",type:e.type,seq:null==(s=e.content)?void 0:s.seq},(s=>{const{connection:i}=this;if(i){const t=e.content.dest_session_id;if(t!==this.options.sessionId){const r=i.logItem.log({l:"ignoring to_device event with wrong session_id",destSessionId:t,type:e.type});return void s.refDetached(r)}if(i.peerCall){if(i.peerCall.getMessageAction(e)===IncomingMessageAction.InviteGlare){const{shouldReplace:t,log:s}=i.peerCall.handleInviteGlare(e,this.deviceId,i.logItem);s&&s.refDetached(s),t&&(i.peerCall.dispose(),i.peerCall=void 0)}}e.type!==EventType.Invite||i.peerCall||(i.peerCall=this._createPeerCall(e.content.call_id));const r=sortedIndex(i.queuedSignallingMessages,e,((e,t)=>e.content.seq-t.content.seq));i.queuedSignallingMessages.splice(r,0,e);let n=!1;i.peerCall&&(n=this.dequeueSignallingMessages(i,i.peerCall,e,s)),n||s.refDetached(i.logItem.log({l:"queued message",type:e.type,seq:e.content.seq,idx:r}))}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 n=e.queuedSignallingMessages.shift(),o=n===s;r=r||o,i.wrap(o?"process message":"dequeue message",(s=>{var i;const r=null==(i=n.content)?void 0:i.seq;s.set("seq",r),s.set("type",n.type);if(t.getMessageAction(n)===IncomingMessageAction.Handle){const i=t.handleIncomingSignallingMessage(n,this.deviceId,e.logItem);s.refDetached(i),e.lastProcessedSeqNr=r}else s.set("ignored",!0),e.lastIgnoredSeqNr=r}))}return r}async setMedia(e,t){return this.errorBoundary.try((async()=>{var s;const{connection:i}=this;i&&(i.localMedia=e.replaceClone(i.localMedia,t),await(null==(s=i.peerCall)?void 0:s.setMedia(i.localMedia,i.logItem)))}))}async setMuted(e){return this.errorBoundary.try((async()=>{var t;const{connection:s}=this;s&&(s.localMuteSettings=e,await(null==(t=s.peerCall)?void 0:t.setMuted(e,s.logItem)))}))}_createPeerCall(e){const t=this.connection;return new PeerCall(e,Object.assign({},this.options,{errorBoundary:this.errorBoundary,emitUpdate:this.emitUpdateFromPeerCall,sendSignallingMessage:this.sendSignallingMessage,turnServer:t.turnServer}),t.logItem)}dispose(){var e,t;null==(e=this.connection)||e.dispose(),this.connection=void 0,null==(t=this.expireTimeout)||t.dispose(),this.expireTimeout=void 0,this.emitMemberUpdate=()=>{}}}function memberExpiresAt(e){const t=e.expires_ts;if(Number.isSafeInteger(t))return t}function isMemberExpired(e,t,s=0){const i=memberExpiresAt(e);return"number"!=typeof i||i+s<=t}function getMemberKey(e,t){return JSON.stringify(e)+","+JSON.stringify(t)}function memberKeyIsForUser(e,t){return e.startsWith(JSON.stringify(t)+",")}function getDeviceFromMemberKey(e){return JSON.parse(`[${e}]`)[1]}class JoinedData{constructor(e,t,s,i,r,n){this.logItem=e,this.membersLogItem=t,this.localMedia=s,this.localPreviewMedia=i,this.localMuteSettings=r,this.turnServer=n}dispose(){var e;this.localMedia.dispose(),this.localPreviewMedia.dispose(),this.logItem.finish(),null==(e=this.renewMembershipTimeout)||e.dispose()}}class GroupCall extends EventEmitter{constructor(e,t,s,i,r,n,o){super(),this.id=e,this.isLoadedFromStorage=t,this.startTime=i,this.callContent=r,this.roomId=n,this.options=o,this._members=new ObservableMap,this.bufferedDeviceMessages=new Map,this.errorBoundary=new ErrorBoundary((e=>{this.emitChange(),this.joinedData&&(this.joinedData.logItem.log("error at boundary").catch(e),console.error(e))})),this._state=s?"fledgling":"created",this._memberOptions=Object.assign({},o,{confId:this.id,emitUpdate:e=>{var t;const s=getMemberKey(e.userId,e.deviceId);if(e.isExpired&&!e.isConnected){const i=this.options.logger.log({l:"removing expired member from call",memberKey:s,callId:this.id});null==(t=e.logItem)||t.refDetached(i),e.dispose(),this._members.remove(s)}else this._members.update(s)},encryptDeviceMessage:(e,t,s,i)=>this.options.encryptDeviceMessage(this.roomId,e,t,s,i)})}get localMedia(){var e;return null==(e=this.joinedData)?void 0:e.localMedia}get localPreviewMedia(){var e;return null==(e=this.joinedData)?void 0:e.localPreviewMedia}get members(){return this._members}get isTerminated(){var e;return!!(null==(e=this.callContent)?void 0:e["m.terminated"])}get usesFoci(){for(const e of this._members.values())if(e.usesFoci)return!0;return!1}get duration(){if("number"==typeof this.startTime)return this.options.clock.now()-this.startTime}get isRinging(){return"created"===this._state&&"m.ring"===this.intent&&!this.isMember(this.options.ownUserId)}get name(){var e;return null==(e=this.callContent)?void 0:e["m.name"]}get intent(){var e;return null==(e=this.callContent)?void 0:e["m.intent"]}get deviceIndex(){return this._deviceIndex}get eventTimestamp(){return this._eventTimestamp}get type(){var e;return null==(e=this.callContent)?void 0:e["m.type"]}get logItem(){var e;return null==(e=this.joinedData)?void 0:e.logItem}get error(){return this.errorBoundary.error}join(e,t){return this.options.logger.wrapOrRun(t,"Call.join",(async t=>{if("created"!==this._state||this.joinedData||this.usesFoci)return void e.dispose();const s=this.options.logger.child({l:"Call.connection",t:"call",id:this.id,ownSessionId:this.options.sessionId}),i=await this.options.turnServerSource.getSettings(s),r=s.child("member connections"),n=new MuteSettings;n.updateTrackInfo(e.userMedia);const o=e.asPreview(),a=new JoinedData(s,r,e,o,n,i);this.joinedData=a,await a.logItem.wrap("join",(async e=>{t.refDetached(e),this._state="joining",this.emitChange(),await e.wrap("update member state",(async e=>{const t=await this._createMemberPayload(!0);e.set("payload",t);const s=this.options.hsApi.sendState(this.roomId,EventType.GroupCallMember,this.options.ownUserId,t,{log:e});await s.response(),this.emitChange()}));for(const t of this._members.values())this.connectToMember(t,a,e)}))}))}async setMedia(e){var t;if(("joining"===this._state||"joined"===this._state)&&this.joinedData){const s=this.joinedData.localMedia;this.joinedData.localMedia=e,null==(t=this.joinedData.localPreviewMedia)||t.dispose(),this.joinedData.localPreviewMedia=e.asPreview(),this.joinedData.localMuteSettings.updateTrackInfo(e.userMedia),this.emitChange(),await Promise.all(Array.from(this._members.values()).map((t=>t.setMedia(e,s)))),null==s||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&&mute(this.localPreviewMedia,e,this.joinedData.logItem),this.localMedia&&mute(this.localMedia,e,this.joinedData.logItem),await Promise.all(Array.from(this._members.values()).map((e=>e.setMuted(t.localMuteSettings)))),this.emitChange())}get muteSettings(){var e;return null==(e=this.joinedData)?void 0:e.localMuteSettings}get hasJoined(){return"joining"===this._state||"joined"===this._state}async leave(e){await this.options.logger.wrapOrRun(e,"Call.leave",(async e=>{var t;const{joinedData:s}=this;if(s)try{null==(t=s.renewMembershipTimeout)||t.dispose(),s.renewMembershipTimeout=void 0;const i=await this._createMemberPayload(!1);if(i){const t=this.options.hsApi.sendState(this.roomId,EventType.GroupCallMember,this.options.ownUserId,i,{log:e});await t.response(),this.intent!==CallIntent.Ring&&this.intent!==CallIntent.Prompt||0!==this._members.size||await this.terminate(e)}else e.set("already_left",!0)}finally{if(!this.disconnect(e))throw this.errorBoundary.error}}))}terminate(e){return this.options.logger.wrapOrRun(e,{l:"terminate call",t:"call"},(async e=>{if("fledgling"===this._state)return;const t=this.options.hsApi.sendState(this.roomId,EventType.GroupCall,this.id,Object.assign({},this.callContent,{"m.terminated":!0}),{log:e});await t.response()}))}create(e,t){return t.wrap({l:"create call",t:"call"},(async t=>{if("fledgling"!==this._state)return;this._state="creating",this.emitChange(),this.callContent=Object.assign({"m.type":e},this.callContent);const s=this.options.hsApi.sendState(this.roomId,EventType.GroupCall,this.id,this.callContent,{log:t});await s.response(),this._state="created",this.emitChange()}))}updateCallEvent(e,t){this.errorBoundary.try((()=>{t.wrap({l:"update call",t:"call",id:this.id},(t=>{"number"!=typeof this.startTime&&(this.startTime=e.origin_server_ts),this.callContent=e.content,"creating"===this._state&&(this._state="created"),t.set("status",this._state),this.emitChange()}))}))}updateRoomMembers(e){this.errorBoundary.try((()=>{for(const t of e.values()){const{member:e}=t;for(const t of this._members.values())t.userId===e.userId&&t.updateRoomMember(e)}}))}updateMembership(e,t,s,i,r){this.errorBoundary.try((async()=>{await r.wrap({l:"update call membership",t:"call",id:this.id,userId:e},(async r=>{const n=this.options.clock.now(),o=s["m.devices"],a=this.getDeviceIdsForUserId(e);for(let s=0;s<o.length;s++){const a=o[s],l=a.device_id,c=getMemberKey(e,l);e===this.options.ownUserId&&l===this.options.ownDeviceId?(this._deviceIndex=s,this._eventTimestamp=i,r.wrap("update own membership",(e=>{this.hasJoined&&(this.joinedData&&this.joinedData.logItem.refDetached(e),this._setupRenewMembershipTimeout(a,e)),"joining"===this._state&&(e.set("joined",!0),this._state="joined",this.emitChange())}))):await r.wrap({l:"update device membership",id:c,sessionId:a.session_id},(async e=>{if(isMemberExpired(a,n)){e.set("expired",!0);const t=this._members.get(c);return void(t?(t.dispose(),this._members.remove(c),e.set("removed",!0)):e.discard())}let r=this._members.get(c);const o=r&&r.sessionId!==a.session_id;if(r&&!o)e.set("update",!0),r.updateCallInfo(a,s,i,e);else{if(r&&o){e.set("removedSessionId",r.sessionId);const t=await r.disconnect(!1);t&&e.refDetached(t),r.dispose(),this._members.remove(c),r=void 0}e.set("add",!0),r=new Member(t,a,s,i,this._memberOptions,e),this._members.add(c,r),this.joinedData&&this.connectToMember(r,this.joinedData,e)}this.flushPendingIncomingDeviceMessages(r,e)}))}const l=new Set(o.map((e=>e.device_id)));for(const t of a)l.has(t)||this.removeMemberDevice(e,t,r);e!==this.options.ownUserId||l.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:"call",id:this.id,userId:e},(t=>{for(const i of s)this.removeMemberDevice(e,i,t);e===this.options.ownUserId&&this.removeOwnDevice(t)}))}))}flushPendingIncomingDeviceMessages(e,t){const s=getMemberKey(e.userId,e.deviceId),i=this.bufferedDeviceMessages.get(s);if(i){for(const s of i)s.content.sender_session_id===e.sessionId&&(e.handleDeviceMessage(s,t),i.delete(s));0===i.size&&this.bufferedDeviceMessages.delete(s)}}getDeviceIdsForUserId(e){return Array.from(this._members.keys()).filter((t=>memberKeyIsForUser(t,e))).map((e=>getDeviceFromMemberKey(e)))}isMember(e){return Array.from(this._members.keys()).some((t=>memberKeyIsForUser(t,e)))}removeOwnDevice(e){e.wrap("remove own membership",(e=>{this.disconnect(e)}))}disconnect(e){return this.errorBoundary.try((async()=>{var t;if(this.hasJoined){for(const t of this._members.values()){const s=await t.disconnect(!0);s&&e.refDetached(s)}this._state="created"}null==(t=this.joinedData)||t.dispose(),this.joinedData=void 0,this.emitChange()}),!1)||!0}async removeMemberDevice(e,t,s){const i=getMemberKey(e,t);await s.wrap({l:"remove device member",id:i},(async e=>{const t=this._members.get(i);if(t){e.set("leave",!0);const s=await t.disconnect(!1);s&&e.refDetached(s),t.dispose(),this._members.remove(i)}}))}handleDeviceMessage(e,t,s,i){this.errorBoundary.try((()=>{const r=getMemberKey(t,s);let n=this._members.get(r);if(n&&e.content.sender_session_id===n.sessionId)n.handleDeviceMessage(e,i);else{i.log({l:"call: buffering to_device message, member not found",t:"call",id:this.id,userId:t,deviceId:s,sessionId:e.content.sender_session_id,type:e.type});let n=this.bufferedDeviceMessages.get(r);n||(n=new Set,this.bufferedDeviceMessages.set(r,n)),n.add(e)}}))}async _createMemberPayload(e){var t,s;const{storage:i}=this.options,r=await i.readTxn([i.storeNames.roomState]),n=await r.roomState.get(this.roomId,EventType.GroupCallMember,this.options.ownUserId),o=null!=(s=null==(t=null==n?void 0:n.event)?void 0:t.content)?s:{"m.calls":[]};let a=o["m.calls"],l=a.find((e=>e["m.call_id"]===this.id));l||(l={"m.call_id":this.id,"m.devices":[]},a.push(l));const c=this.options.clock.now();return l["m.devices"]=l["m.devices"].filter((e=>e.device_id!==this.options.ownDeviceId&&(void 0!==memberExpiresAt(e)&&!isMemberExpired(e,c,36e5)))),e&&(l["m.devices"].push({device_id:this.options.ownDeviceId,session_id:this.options.sessionId,expires_ts:c+36e5,feeds:[{purpose:"m.usermedia"}]}),this._deviceIndex=l["m.devices"].length,this._eventTimestamp=Date.now()),o["m.calls"]=a.filter((e=>0!==e["m.devices"].length)),o}async connectToMember(e,t,s){const i=getMemberKey(e.userId,e.deviceId),r=t.membersLogItem.child({l:"member",id:i,sessionId:e.sessionId});await s.wrap({l:"connect",id:i},(async s=>{const i=await e.connect(t.localMedia,t.localMuteSettings,t.turnServer,r);i&&s.refDetached(i)}))}emitChange(){this.emit("change"),this.options.emitUpdate(this)}_setupRenewMembershipTimeout(e,t){var s;const{joinedData:i}=this;if(!i)return;null==(s=i.renewMembershipTimeout)||s.dispose(),i.renewMembershipTimeout=void 0;const r=memberExpiresAt(e);if("number"!=typeof r)return;const n=r-this.options.clock.now(),o=Math.max(1e4,Math.ceil(299988*(.2+.8*this.options.random()))),a=Math.max(0,n-o);t.set("expiresIn",n),t.set("renewIn",a),i.renewMembershipTimeout=this.options.clock.createTimeout(a),i.renewMembershipTimeout.elapsed().then((()=>{i.logItem.wrap("renew membership",(async e=>{const t=await this._createMemberPayload(!0);e.set("payload",t);const s=this.options.hsApi.sendState(this.roomId,EventType.GroupCallMember,this.options.ownUserId,t,{log:e});await s.response()}))}),(()=>{}))}dispose(){var e;null==(e=this.joinedData)||e.dispose();for(const e of this._members.values())e.dispose()}}const DEFAULT_TTL=300,DEFAULT_SETTINGS={urls:["stun:turn.matrix.org"],username:"",credential:""};class TurnServerSource{constructor(e,t,s=DEFAULT_SETTINGS){this.hsApi=e,this.clock=t,this.defaultSettings=s,this.isPolling=!1}getSettings(e){return e.wrap("get turn server",(async e=>{if(!this.isPolling){const t=await this.doRequest(e),s=t?toIceServer(t):this.defaultSettings;e.set("iceServer",s),this.currentObservable?this.currentObservable.set(s):this.currentObservable=new RetainedObservableValue(s,(()=>{this.stopPollLoop()}),(()=>{var e;this.runLoop(null!=(e=null==t?void 0:t.ttl)?e:300)}))}return this.currentObservable}))}async runLoop(e){let t=e;for(this.isPolling=!0;this.isPolling;)try{this.pollTimeout=this.clock.createTimeout(1e3*t),await this.pollTimeout.elapsed(),this.pollTimeout=void 0;const e=await this.doRequest(void 0);if(e){const s=toIceServer(e);shouldUpdate(this.currentObservable,s)&&this.currentObservable.set(s),e.ttl>0?t=e.ttl:this.stopPollLoop()}else t=300}catch(e){e.name}}async doRequest(e){try{this.pollRequest=this.hsApi.getTurnServer({log:e});return await this.pollRequest.response()}catch(e){if("HomeServerError"===e.name)return;throw e}finally{this.pollRequest=void 0}}stopPollLoop(){var e,t;this.isPolling=!1,this.currentObservable=void 0,null==(e=this.pollTimeout)||e.dispose(),this.pollTimeout=void 0,null==(t=this.pollRequest)||t.abort(),this.pollRequest=void 0}dispose(){this.stopPollLoop()}}function shouldUpdate(e,t){const s=e.get();if(!s)return!0;const i=Array.isArray(s.urls)?s.urls:[s.urls],r=Array.isArray(t.urls)?t.urls:[t.urls];return!(i.length===r.length&&!r.some((e=>!i.includes(e))))||t.username!==s.username||t.credential!==s.credential}function toIceServer(e){return{urls:e.uris,username:e.username,credential:e.password,credentialType:"password"}}function getRoomMemberKey(e,t){return JSON.stringify(e)+","+JSON.stringify(t)}class CallHandler{constructor(e){this.options=e,this._calls=new ObservableMap,this.roomMemberToCallIds=new Map,this.sessionId=makeId("s"),this.groupCallOptions=Object.assign({},this.options,{turnServerSource:new TurnServerSource(this.options.hsApi,this.options.clock),emitUpdate:(e,t)=>this._calls.update(e.id,t),createTimeout:this.options.clock.createTimeout,sessionId:this.sessionId})}loadCalls(e,t){return this.options.logger.wrapOrRun(t,"CallHandler.loadCalls",(async t=>{e||(e=CallIntent.Ring),t.set("intent",e);const s=await this._getLoadTxn(),i=await s.calls.getByIntent(e);await this._loadCallEntries(i,s,t)}))}loadCallsForRoom(e,t,s){return this.options.logger.wrapOrRun(s,"CallHandler.loadCallsForRoom",(async s=>{s.set("intent",e),s.set("roomId",t);const i=await this._getLoadTxn(),r=await i.calls.getByIntentAndRoom(e,t);await this._loadCallEntries(r,i,s)}))}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 e=>{if(this._calls.get(e.callId))return;const s=await t.roomState.get(e.roomId,EventType.GroupCall,e.callId);if(s){const t=new GroupCall(s.event.state_key,!0,!1,e.timestamp,s.event.content,s.roomId,this.groupCallOptions);this._calls.set(t.id,t)}})));const i=Array.from(new Set(e.map((e=>e.roomId))));await Promise.all(i.map((async e=>{const i=await t.roomState.getAllForType(e,EventType.GroupCallMember);await Promise.all(i.map((async i=>{const r=i.event.sender,n=await t.roomState.get(e,EVENT_TYPE$1,r);let o;n&&(o=RoomMember.fromMemberEvent(n.event)),o||(o=RoomMember.fromUserId(e,r,"join")),this.handleCallMemberEvent(i.event,o,e,s)})))}))),s.set("newSize",this._calls.size)}createCall(e,t,s,i,r){return this.options.logger.wrapOrRun(r,"CallHandler.createCall",(async r=>{i||(i=CallIntent.Ring);const n=new GroupCall(makeId("conf-"),!1,!0,void 0,{"m.name":s,"m.intent":i},e,this.groupCallOptions);this._calls.set(n.id,n);try{await n.create(t,r);const s=await this.options.storage.readWriteTxn([this.options.storage.storeNames.calls]);s.calls.add({intent:n.intent,callId:n.id,timestamp:this.options.clock.now(),roomId:e}),await s.complete()}catch(e){throw this._calls.remove(n.id),e}return n}))}get calls(){return this._calls}async handleRoomState(e,t,s,i,r){if(t.type===EventType.GroupCall&&this.handleCallEvent(t,e.id,i,r),t.type===EventType.GroupCallMember){let n=await s.lookupMemberAtEvent(t.sender,t,i);n||(n=RoomMember.fromUserId(e.id,t.sender,"join")),this.handleCallMemberEvent(t,n,e.id,r)}}updateRoomMembers(e,t){for(const s of this._calls.values())s.roomId===e.id&&s.updateRoomMembers(t)}handlesDeviceMessageEventType(e){return handlesEventType(e)}handleDeviceMessage(e,t,s,i){const r=this._calls.get(e.content.conf_id);null==r||r.handleDeviceMessage(e,t,s,i)}handleCallEvent(e,t,s,i){const r=e.state_key;let n=this._calls.get(r);n?(n.updateCallEvent(e,i),n.isTerminated&&(n.disconnect(i),this._calls.remove(n.id),s.calls.remove(n.intent,t,n.id))):e.content["m.terminated"]||(n=new GroupCall(e.state_key,!1,!1,e.origin_server_ts,e.content,t,this.groupCallOptions),this._calls.set(n.id,n),s.calls.add({intent:n.intent,callId:n.id,timestamp:e.origin_server_ts,roomId:t}))}handleCallMemberEvent(e,t,s,i){var r;const n=e.state_key,o=getRoomMemberKey(s,n),a=null!=(r=e.content["m.calls"])?r:[],l=e.origin_server_ts;for(const e of a){const s=e["m.call_id"],r=this._calls.get(s);null==r||r.updateMembership(n,t,e,l,i)}const c=new Set(a.map((e=>e["m.call_id"])));let d=this.roomMemberToCallIds.get(o);if(d)for(const e of d)if(!c.has(e)){const t=this._calls.get(e);null==t||t.removeMembership(n,i)}0===c.size?this.roomMemberToCallIds.delete(o):this.roomMemberToCallIds.set(o,c)}dispose(){this.groupCallOptions.turnServerSource.dispose();for(const e of this._calls.values())e.dispose()}}class RoomStateHandlerSet extends BaseObservable{async handleRoomState(e,t,s,i,r){const n=[];for(let o of this._handlers)n.push(o.handleRoomState(e,t,s,i,r));await Promise.all(n)}updateRoomMembers(e,t){for(let s of this._handlers)s.updateRoomMembers(e,t)}}const PICKLE_KEY="DEFAULT_KEY",PUSHER_KEY="pusher";class Session{constructor({storage:e,hsApi:t,sessionInfo:s,olm:i,olmWorker:r,platform:n,mediaRepository:o,features:a}){this._platform=n,this._storage=e,this._hsApi=t,this._mediaRepository=o,this._features=a,this._syncInfo=null,this._sessionInfo=s,this._rooms=new ObservableMap,this._roomUpdateCallback=(e,t)=>this._rooms.update(e.id,t),this._activeArchivedRooms=new Map,this._invites=new ObservableMap,this._inviteUpdateCallback=(e,t)=>this._invites.update(e.id,t),this._roomsBeingCreatedUpdateCallback=(e,t)=>{e.isCancelled?this._roomsBeingCreated.remove(e.id):this._roomsBeingCreated.update(e.id,t)},this._roomsBeingCreated=new ObservableMap,this._user=new User(s.userId),this._roomStateHandler=new RoomStateHandlerSet,a.calls&&this._setupCallHandler(),this._deviceMessageHandler=new DeviceMessageHandler({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 ObservableValue$1(void 0),this._crossSigning=new ObservableValue$1(void 0),this._observedRoomStatus=new Map,i&&(this._olmUtil=new i.Utility,this._deviceTracker=new DeviceTracker({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 ObservableValue$1(!1)}get hsApi(){return this._hsApi}get sessionInfo(){return this._sessionInfo}get fingerprintKey(){var e;return null==(e=this._e2eeAccount)?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}_setupCallHandler(){this._callHandler=new CallHandler({clock:this._platform.clock,random:this._platform.random,hsApi:this._hsApi,encryptDeviceMessage:async(e,t,s,i,r)=>{if(!this._deviceTracker||!this._olmEncryption)return void r.set("encryption_disabled",!0);const n=await r.wrap("get device key",(async e=>{const i=this._deviceTracker.deviceForId(t,s,this._hsApi,e);return i||e.set("not_found",!0),i}));if(n){return await this._olmEncryption.encrypt(i.type,i.content,[n],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)}_setupEncryption(){const e=new LockMap,t=new Decryption$1(this._e2eeAccount,PICKLE_KEY,this._platform.clock.now,this._user.id,this._olm,e);this._olmEncryption=new Encryption$1(this._e2eeAccount,PICKLE_KEY,this._olm,this._storage,this._platform.clock.now,this._user.id,this._olmUtil,e),this._keyLoader=new KeyLoader(this._olm,PICKLE_KEY,20),this._megolmEncryption=new Encryption({account:this._e2eeAccount,pickleKey:PICKLE_KEY,olm:this._olm,storage:this._storage,keyLoader:this._keyLoader,now:this._platform.clock.now,ownDeviceId:this._sessionInfo.deviceId}),this._megolmDecryption=new Decryption(this._keyLoader,this._olmWorker),this._deviceMessageHandler.enableEncryption({olmDecryption:t,megolmDecryption:this._megolmDecryption})}_createRoomEncryption(e,t){var s;if(!this._olmEncryption)throw new Error("creating room encryption before encryption got globally enabled");return t.algorithm!==MEGOLM_ALGORITHM?null:new RoomEncryption({room:e,deviceTracker:this._deviceTracker,olmEncryption:this._olmEncryption,megolmEncryption:this._megolmEncryption,megolmDecryption:this._megolmDecryption,storage:this._storage,keyBackup:null==(s=this._keyBackup)?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 s=>{var i,r;if(!this._olm)throw new Error("olm required");this._keyBackup.get()&&(this._keyBackup.get().dispose(),this._keyBackup.set(void 0));const n=this._crossSigning.get();n&&(n.dispose(),this._crossSigning.set(void 0));const o=await keyFromCredential(e,t,this._storage,this._platform,this._olm);if(await this._tryLoadSecretStorage(o,s))return await this._writeSSSSKey(o,s),await(null==(i=this._keyBackup.get())?void 0:i.start(s)),await(null==(r=this._crossSigning.get())?void 0:r.start(s)),o;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 n=await writeKey(e,i,r);if(t.set("previousBackupVersion",n),t.set("backupVersion",i),n&&n!==i){const e=await s.markAllForBackup(r);t.set("amountMarkedForBackup",e)}}catch(e){throw r.abort(),e}await r.complete()}async disableSecretStorage(){const e=await this._storage.readWriteTxn([this._storage.storeNames.session]);try{removeKey(e)}catch(t){throw e.abort(),t}if(await e.complete(),this._keyBackup.get()){for(const e of this._rooms.values())e.isEncrypted&&e.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 t=>{const s=new SecretStorage({key:e,platform:this._platform,storage:this._storage}),i=await s.hasValidKeyForAnyAccountData();return t.set("isValid",i),i&&await this._loadSecretStorageServices(s,t),i}))}async _loadSecretStorageServices(e,t){try{await t.wrap("enable key backup",(async t=>{const s=new KeyBackup(this._hsApi,this._olm,this._keyLoader,this._storage,this._platform);if(await s.load(e,t)){for(const e of this._rooms.values())e.isEncrypted&&e.enableKeyBackup(s);return this._keyBackup.set(s),!0}t.set("no_backup",!0)})),this._features.crossSigning&&await t.wrap("enable cross-signing",(async t=>{const s=new CrossSigning({storage:this._storage,secretStorage:e,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 s.load(t)?this._crossSigning.set(s):s.dispose()}))}catch(e){t.catch(e)}}get keyBackup(){return this._keyBackup}get crossSigning(){return this._crossSigning}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),this._setupEncryption()),await this._e2eeAccount.generateOTKsIfNeeded(this._storage,e),await e.wrap("uploadKeys",(e=>this._e2eeAccount.uploadKeys(this._storage,!1,e))))}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 Account.adoptDehydratedDevice({dehydratedDevice:e,hsApi:this._hsApi,olm:this._olm,pickleKey:PICKLE_KEY,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 Account.create({hsApi:this._hsApi,olm:this._olm,pickleKey:PICKLE_KEY,userId:this._sessionInfo.userId,olmWorker:this._olmWorker,deviceId:e,storage:t})}setupDehydratedDevice(e,t=null){return this._platform.logger.wrapOrRun(t,"setupDehydratedDevice",(async t=>{const s=await this._createNewAccount("temp-device-id");try{const i=await uploadAccountAsDehydratedDevice(s,this._hsApi,e,"Dehydrated device",t);return t.set("deviceId",i),i}finally{s.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 Account.load({hsApi:this._hsApi,olm:this._olm,pickleKey:PICKLE_KEY,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 t=>{const s=this.createInvite(t.roomId);e.wrap("invite",(e=>s.load(t,e))),this._invites.add(s.id,s)}))),n=await t.roomSummary.getAll(),o=Promise.all(n.map((async i=>{const r=this.createJoinedRoom(i.roomId,s.get(i.roomId));await e.wrap("room",(e=>r.load(i,t,e))),this._rooms.add(r.id,r)})));await Promise.all([r,o]);for(const[e,t]of this.invites){const s=this.rooms.get(e);s&&s.setInvite(t)}if(this._olm&&this._e2eeAccount){const s=await readKey(t);s&&await this._tryLoadSecretStorage(s,e)}}dispose(){var e,t,s,i,r,n;null==(e=this._olmWorker)||e.dispose(),this._olmWorker=void 0,null==(t=this._keyBackup.get())||t.dispose(),this._keyBackup.set(void 0),null==(s=this._megolmDecryption)||s.dispose(),this._megolmDecryption=void 0,null==(i=this._e2eeAccount)||i.dispose(),this._e2eeAccount=void 0,null==(r=this._callHandler)||r.dispose(),this._callHandler=void 0,null==(n=this._crossSigning.get())||n.dispose();for(const e of this._rooms.values())e.dispose();this._rooms=void 0}async start(e,t,s){var i,r;if(e){const t=await this._storage.readWriteTxn([this._storage.storeNames.session]);t.session.set("serverVersions",e),await t.complete()}t&&await s.wrap("SSSSKeyFromDehydratedDeviceKey",(async e=>{const s=await keyFromDehydratedDeviceKey(t.key,this._storage,this._platform);s&&await this._tryLoadSecretStorage(s,e)&&(e.set("success",!0),await this._writeSSSSKey(s))})),await(null==(i=this._keyBackup.get())?void 0:i.start(s)),await(null==(r=this._crossSigning.get())?void 0:r.start(s));const n=await this._storage.readWriteTxn([this._storage.storeNames.operations]),o=groupBy(await n.operations.getAll(),(e=>e.scope));for(const e of this._rooms.values()){let t;const i=o.get(e.id);i&&(t=groupBy(i,(e=>e.type))),e.start(t,s)}}async _getPendingEventsByRoom(e){return(await e.pendingEvents.getAll()).reduce(((e,t)=>{const s=e.get(t.roomId);return s?s.push(t):e.set(t.roomId,[t]),e}),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 Room({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 ArchivedRoom({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 Invite({roomId:e,hsApi:this._hsApi,emitCollectionUpdate:this._inviteUpdateCallback,mediaRepository:this._mediaRepository,user:this._user,platform:this._platform})}get roomsBeingCreated(){return this._roomsBeingCreated}createRoom(e){let t;return this._platform.logger.runDetached("create room",(async s=>{const i=`local-${Math.floor(this._platform.random()*Number.MAX_SAFE_INTEGER)}`;t=new RoomBeingCreated(i,e,this._roomsBeingCreatedUpdateCallback,this._mediaRepository,this._platform,s),this._roomsBeingCreated.set(i,t);const r=[t.create(this._hsApi,s)];!1!==e.loadProfiles&&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 t;const s=null==(t=e.to_device)?void 0:t.events;if(Array.isArray(s)&&s.length)return await this._deviceMessageHandler.obtainSyncLock(s)}async prepareSync(e,t,s,i){var r;const n=null==(r=e.to_device)?void 0:r.events;if(Array.isArray(n)&&n.length)return await i.wrap("deviceMsgs",(e=>this._deviceMessageHandler.prepareSync(n,t,s,e)))}async writeSync(e,t,s,i,r){const n={syncInfo:null,e2eeAccountChanges:null,hasNewRoomKeys:!1,deviceMessageDecryptionResults:null},o=e.next_batch;if(o!==this.syncToken){const e={token:o,filterId:t};i.session.set("sync",e),n.syncInfo=e}const a=e.device_one_time_keys_count;this._e2eeAccount&&a&&(n.e2eeAccountChanges=this._e2eeAccount.writeSync(a,i,r));const l=e.device_lists;if(this._deviceTracker&&Array.isArray(null==l?void 0:l.changed)&&l.changed.length&&await r.wrap("deviceLists",(e=>this._deviceTracker.writeDeviceChanges(l.changed,i,e))),s){const{hasNewRoomKeys:e,decryptionResults:t}=await r.wrap("deviceMsgs",(e=>this._deviceMessageHandler.writeSync(s,i,e)));n.hasNewRoomKeys=e,n.deviceMessageDecryptionResults=t}const c=e.account_data;if(Array.isArray(null==c?void 0:c.events))for(const e of c.events)"string"==typeof e.type&&i.accountData.set(e);return n}afterSync({syncInfo:e,e2eeAccountChanges:t}){e&&(this._syncInfo=e),this._e2eeAccount&&this._e2eeAccount.afterSync(t)}async afterSyncCompleted(e,t,s){var i;if(this._e2eeAccount&&!t){await this._e2eeAccount.generateOTKsIfNeeded(this._storage,s)&&await s.wrap("uploadKeys",(e=>this._e2eeAccount.uploadKeys(this._storage,!1,e)))}e.hasNewRoomKeys&&(null==(i=this._keyBackup.get())||i.flush(s)),e.deviceMessageDecryptionResults&&await this._deviceMessageHandler.afterSyncCompleted(e.deviceMessageDecryptionResults,this._deviceTracker,this._hsApi,s)}_tryReplaceRoomBeingCreated(e,t){for(const[,s]of this._roomsBeingCreated)if(s.roomId===e){const e=this._observedRoomStatus.get(s.id);return e&&(t.log("replacing room being created").set("localId",s.id).set("roomId",s.roomId),e.set(e.get()|RoomStatus.Replaced)),s.dispose(),void this._roomsBeingCreated.remove(s.id)}}async applyRoomCollectionChangesAfterSync(e,t,s,i){var r,n;for(const e of t)e.shouldAdd?(this._rooms.add(e.id,e.room),this._tryReplaceRoomBeingCreated(e.id,i)):e.shouldRemove&&this._rooms.remove(e.id);for(const t of e)t.shouldAdd?this._invites.add(t.id,t.invite):t.shouldRemove&&this._invites.remove(t.id);if(0!==this._observedRoomStatus.size){for(const e of s)e.shouldAdd&&(null==(r=this._observedRoomStatus.get(e.id))||r.set(RoomStatus.Archived));for(const e of t)e.shouldAdd&&(null==(n=this._observedRoomStatus.get(e.id))||n.set(RoomStatus.Joined));for(const t of e){const e=this._observedRoomStatus.get(t.id);if(e){const s=e.get()|RoomStatus.Invited;if(t.shouldAdd)e.set(s);else if(t.shouldRemove){const t=s^RoomStatus.Invited;e.set(t)}}}}}_forgetArchivedRoom(e){const t=this._observedRoomStatus.get(e);t&&t.set((t.get()|RoomStatus.Archived)^RoomStatus.Archived)}get syncToken(){var e;return null==(e=this._syncInfo)?void 0:e.token}get syncFilterId(){var e;return null==(e=this._syncInfo)?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=Pusher.createDefaultPayload(this._sessionInfo.id),s=await this._platform.notificationService.enablePush(Pusher,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("pusher",s.serialize()),await i.complete(),!0}))}async _disablePush(){return this._platform.logger.run("disablePush",(async e=>{await this._platform.notificationService.disablePush();const t=await this._storage.readTxn([this._storage.storeNames.session]),s=await t.session.get("pusher");if(!s)return!0;const i=new Pusher(s);await i.disable(this._hsApi,e);const r=await this._storage.readWriteTxn([this._storage.storeNames.session]);return r.session.remove("pusher"),await r.complete(),!0}))}async arePushNotificationsEnabled(){if(!await this._platform.notificationService.isPushEnabled())return!1;const e=await this._storage.readTxn([this._storage.storeNames.session]);return!!await e.session.get("pusher")}async checkPusherEnabledOnHomeserver(){const e=await this._storage.readTxn([this._storage.storeNames.session]),t=await e.session.get("pusher");if(!t)return!1;const s=new Pusher(t),i=await this._hsApi.getPushers().response();return((null==i?void 0:i.pushers)||[]).map((e=>new Pusher(e))).some((e=>e.equals(s)))}async getRoomStatus(e){if(!!this._roomsBeingCreated.get(e))return RoomStatus.BeingCreated;if(!!this._rooms.get(e))return RoomStatus.Joined;{const t=!!this._invites.get(e),s=await this._storage.readTxn([this._storage.storeNames.archivedRoomSummary]),i=await s.archivedRoomSummary.has(e);return t&&i?RoomStatus.Invited|RoomStatus.Archived:t?RoomStatus.Invited:i?RoomStatus.Archived:RoomStatus.None}}async observeRoomStatus(e){let t=this._observedRoomStatus.get(e);if(!t){let s;t=new RetainedObservableValue(s,(()=>{this._observedRoomStatus.delete(e)})),this._observedRoomStatus.set(e,t),s=await this.getRoomStatus(e),void 0===t.get()&&t.set(s)}return t}observeRoomState(e){return this._roomStateHandler.subscribe(e)}async setAccountData(e,t){const s=await this._storage.readWriteTxn([this._storage.storeNames.accountData]);s&&(s.accountData.set({type:e,content:t}),await s.complete()),await this.hsApi.setAccountData(this.userId,e,t).response()}async getAccountData(e){const t=await this._storage.readWriteTxn([this._storage.storeNames.accountData]),s=await t.accountData.get(e);if(s)return await t.complete(),s.content;try{const s=await this.hsApi.accountData(this.userId,e).response();return s&&(t.accountData.set({type:e,content:s}),await t.complete()),s}catch(e){return void t.abort()}}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 t=>{t.set("id",e);const s=this._activeArchivedRooms.get(e);if(s)return s.retain(),s;const i=await this._storage.readTxn([this._storage.storeNames.archivedRoomSummary,this._storage.storeNames.roomMembers]),r=await i.archivedRoomSummary.get(e);if(r){const s=this._createArchivedRoom(e);return await s.load(r,i,t),s}}))}joinRoom(e,t=null){return this._platform.logger.wrapOrRun(t,"joinRoom",(async t=>(await this._hsApi.joinIdOrAlias(e,{log:t}).response()).room_id))}}class PasswordLoginMethod{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 TokenLoginMethod{constructor({homeserver:e,loginToken:t}){this.homeserver=e,this._loginToken=t}async login(e,t,s){return await e.tokenLogin(this._loginToken,makeTxnId(),t,{log:s}).response()}}class SSOLoginHelper{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 BaseRegistrationStage{constructor(e,t){this._session=e,this._params=t}setNextStage(e){this._nextStage=e}get nextStage(){return this._nextStage}}class DummyAuth extends BaseRegistrationStage{generateAuthenticationData(){return{session:this._session,type:this.type}}get type(){return"m.login.dummy"}}class TermsAuth extends BaseRegistrationStage{generateAuthenticationData(){return{session:this._session,type:this.type}}get type(){return"m.login.terms"}get privacyPolicy(){var e;return null==(e=this._params)?void 0:e.policies.privacy_policy}get termsOfService(){var e;return null==(e=this._params)?void 0:e.policies.terms_of_service}}class TokenAuth extends BaseRegistrationStage{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 Registration{constructor(e,t,s,i){this.homeserver=e,this._hsApi=t,this._accountDetails=s,this._flowSelector=null!=i?i:e=>e[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:n}=this._accountDetails,o=this._hsApi.register(s,i,r,t,n),a=await o.response(),l=await o.responseCode(),c=__spreadProps(__spreadValues({},a),{status:l});return this.parseRegistrationResponse(c,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,n;for(const e of i.stages){const i=this._createRegistrationStage(e,t,s);r?(n.setNextStage(i),n=i):(r=i,n=i)}return r}async parseRegistrationResponse(e,t){var s;switch(e.status){case 200:return void(this._registerResponse=e);case 401:if(null==(s=e.completed)?void 0: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 DummyAuth(t,null==s?void 0:s[e]);case"m.login.terms":return new TermsAuth(t,null==s?void 0:s[e]);case"org.matrix.msc3231.login.registration_token":case"m.login.registration_token":return new TokenAuth(t,null==s?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 LoadStatus=createEnum("NotLoading","Login","LoginFailed","QueryAccount","AccountSetup","Loading","SessionSetup","Migrating","FirstSync","Error","Ready"),LoginFailure=createEnum("Connection","Credentials","Unknown");class Client{constructor(e,t=new FeatureSet(0),s={}){this._platform=e,this._sessionStartedByReconnector=!1,this._status=new ObservableValue$1(LoadStatus.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._deviceName=(null==s?void 0:s.deviceName)||"Hydrogen",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()===LoadStatus.NotLoading&&(this._status.set(LoadStatus.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(e){t.catch(e),this._error=e,this._status.set(LoadStatus.Error)}})))}_parseLoginOptions(e,t){const s=e.flows,i={homeserver:t};for(const e of s)"m.login.password"===e.type?i.password=(e,s)=>new PasswordLoginMethod({homeserver:t,username:e,password:s}):"m.login.sso"===e.type&&s.find((e=>"m.login.token"===e.type))?i.sso=new SSOLoginHelper(t):"m.login.token"===e.type&&(i.token=e=>new TokenLoginMethod({homeserver:t,loginToken:e}));return i}queryLogin(e){return new AbortableOperation((async t=>{const{homeserver:s,issuer:i,account:r}=await lookupHomeserver(e,((e,s)=>t(this._platform.request(e,s))));if(i)try{const e=new OidcApi({issuer:i,request:this._platform.request,encoding:this._platform.encoding,crypto:this._platform.crypto,staticClients:this._platform.config.staticOidcClients});await e.validate();return{homeserver:s,oidc:{issuer:i,account:r,guestAvailable:await e.isGuestAvailable()}}}catch(e){console.log(e)}const n=new HomeServerApi({homeserver:s,request:this._platform.request}),o=await t(n.getLoginFlows()).response();return this._parseLoginOptions(o,s)}))}async startRegistration(e,t,s,i,r){const n=this._platform.request,o=new HomeServerApi({homeserver:e,request:n});return new Registration(e,o,{username:t,password:s,initialDeviceDisplayName:i},r)}async startWithAuthData({accessToken:e,deviceId:t,userId:s,homeserver:i}){await this._platform.logger.run("startWithAuthData",(async r=>{await this._createSessionAfterAuth({accessToken:e,deviceId:t,userId:s,homeserver:i},!0,r)}))}async startWithLogin(e,{inspectAccountSetup:t}={}){const s=this._status.get();s!==LoadStatus.LoginFailed&&s!==LoadStatus.NotLoading&&s!==LoadStatus.Error||(this._resetStatus(),await this._platform.logger.run("login",(async s=>{let i;this._status.set(LoadStatus.Login),this._platform.clock;try{const t=this._platform.request,r=new HomeServerApi({homeserver:e.homeserver,request:t}),n=await e.login(r,this._deviceName,s);this.createNewSessionId();i={deviceId:n.device_id,userId:n.user_id,homeserver:e.homeserver,accessToken:n.access_token},n.refresh_token&&(i.refreshToken=n.refresh_token),n.expires_in&&(i.expiresIn=n.expires_in),n.id_token&&(i.idToken=n.id_token),n.oidc_issuer&&(i.oidcIssuer=n.oidc_issuer,i.oidcClientId=n.oidc_client_id,i.accountManagementUrl=n.oidc_account_management_url)}catch(e){return this._error=e,void("HomeServerError"===e.name?("M_FORBIDDEN"===e.errcode?this._loginFailure=LoginFailure.Credentials:this._loginFailure=LoginFailure.Unknown,s.set("loginFailure",this._loginFailure),this._status.set(LoadStatus.LoginFailed)):"ConnectionError"===e.name?(this._loginFailure=LoginFailure.Connection,this._status.set(LoadStatus.LoginFailed)):this._status.set(LoadStatus.Error))}await this._createSessionAfterAuth(i,t,s)})))}async _createSessionAfterAuth({deviceId:e,userId:t,accessToken:s,refreshToken:i,homeserver:r,expiresIn:n,idToken:o,oidcIssuer:a,oidcClientId:l,accountManagementUrl:c},d,h){const u=this.createNewSessionId(),m=this._platform.clock.now(),p={id:u,deviceId:e,userId:t,homeServer:r,homeserver:r,accessToken:s,lastUsed:m,refreshToken:i,oidcIssuer:a,oidcClientId:l,accountManagementUrl:c,idToken:o};let g;n&&(p.accessTokenExpiresAt=m+1e3*n),d&&(g=await this._inspectAccountAfterLogin(p,h),g&&(p.deviceId=g.deviceId)),h.set("id",u),await this._platform.sessionInfoStorage.add(p);try{await this._loadSessionInfo(p,g,h),h.set("status",this._status.get())}catch(e){h.catch(e),null==g||g.dispose(),this._error=e,this._status.set(LoadStatus.Error)}}async _loadSessionInfo(e,t,s){s.set("appVersion",this._platform.version);const i=this._platform.clock;let r;if(this._sessionStartedByReconnector=!1,this._status.set(LoadStatus.Loading),this._reconnector=new Reconnector({onlineStatus:this._platform.onlineStatus,retryDelay:new ExponentialRetryDelay(i.createTimeout),createMeasure:i.createMeasure}),e.oidcIssuer){const t=new OidcApi({issuer:e.oidcIssuer,staticClients:this._platform.config.staticOidcClients,clientId:e.oidcClientId,request:this._platform.request,encoding:this._platform.encoding,crypto:this._platform.crypto});this._tokenRefresher=new TokenRefresher({oidcApi:t,clock:this._platform.clock,accessToken:e.accessToken,accessTokenExpiresAt:e.accessTokenExpiresAt,refreshToken:e.refreshToken,anticipation:3e4}),this._tokenRefresher.token.subscribe((t=>{this._platform.sessionInfoStorage.updateToken(e.id,t.accessToken,t.accessTokenExpiresAt,t.refreshToken)})),await this._tokenRefresher.start(),r=this._tokenRefresher.accessToken}else r=new ObservableValue$1(e.accessToken);const n=new HomeServerApi({homeserver:e.homeServer,accessToken:r,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};e.accountManagementUrl&&(o.accountManagementUrl=e.accountManagementUrl);const a=await this._olmPromise;let l=null;this._workerPromise&&(l=await this._workerPromise),this._requestScheduler=new RequestScheduler({hsApi:n,clock:i}),this._requestScheduler.start();const c=new MediaRepository({homeserver:e.homeServer,platform:this._platform});if(this._session=new Session({storage:this._storage,sessionInfo:o,hsApi:this._requestScheduler.hsApi,olm:a,olmWorker:l,mediaRepository:c,platform:this._platform,features:this._features}),await this._session.load(s),t?(await s.wrap("dehydrateIdentity",(e=>this._session.dehydrateIdentity(t,e))),await this._session.setupDehydratedDevice(t.key,s)):this._session.hasIdentity||(this._status.set(LoadStatus.SessionSetup),await s.wrap("createIdentity",(e=>this._session.createIdentity(e)))),this._sync=new Sync({hsApi:this._requestScheduler.hsApi,storage:this._storage,session:this._session,logger:this._platform.logger}),this._reconnectSubscription=this._reconnector.connectionStatus.subscribe((e=>{e===ConnectionStatus.Online&&this._platform.logger.runDetached("reconnect",(async e=>{this._requestScheduler.start(),this._sync.start(),this._sessionStartedByReconnector=!0;const s=t;t=void 0,await e.wrap("session start",(e=>this._session.start(this._reconnector.lastVersionsResponse,s,e)))}))})),await s.wrap("wait first sync",(()=>this._waitForFirstSync())),!this._isDisposed&&(this._status.set(LoadStatus.Ready),!this._sessionStartedByReconnector)){const e=await n.versions({timeout:1e4,log:s}).response();if(this._isDisposed)return;const i=t;t=void 0,await s.wrap("session start",(t=>this._session.start(e,i,t)))}}async _waitForFirstSync(){this._sync.start(),this._status.set(LoadStatus.FirstSync),this._waitForFirstSyncHandle=this._sync.status.waitFor((e=>{var t;return e===SyncStatus.Stopped?"ConnectionError"!==(null==(t=this._sync.error)?void 0:t.name):e===SyncStatus.Syncing}));try{if(await this._waitForFirstSyncHandle.promise,this._sync.status.get()===SyncStatus.Stopped&&this._sync.error)throw this._sync.error}catch(e){if("AbortError"===e.name)return;throw e}finally{this._waitForFirstSyncHandle=null}}_inspectAccountAfterLogin(e,t){return t.wrap("inspectAccount",(async t=>{var s;this._status.set(LoadStatus.QueryAccount);const i=new HomeServerApi({homeserver:e.homeServer,accessToken:e.accessToken,request:this._platform.request}),r=await this._olmPromise;let n;try{n=await getDehydratedDevice(i,r,this._platform,t)}catch(e){if("HomeServerError"!==e.name)throw e;t.set("not_supported",!0)}if(n){let e;const t=new Promise((t=>e=t));this._accountSetup=new AccountSetup(n,e),this._status.set(LoadStatus.AccountSetup),await t;const i=null==(s=this._accountSetup)?void 0:s._dehydratedDevice;return this._accountSetup=null,i}}))}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,t){return this._platform.logger.run("logout",(async s=>{this._sessionId=e,s.set("id",this._sessionId);const i=await this._platform.sessionInfoStorage.get(this._sessionId);if(!i)throw new Error(`Could not find session for id ${this._sessionId}`);let r;try{if(i.oidcClientId){const e=new OidcApi({issuer:i.oidcIssuer,staticClients:this._platform.config.staticOidcClients,clientId:i.oidcClientId,request:this._platform.request,encoding:this._platform.encoding,crypto:this._platform.crypto,urlRouter:t});await e.revokeToken({token:i.accessToken,type:"access"}),i.refreshToken&&await e.revokeToken({token:i.refreshToken,type:"refresh"}),r=await e.endSessionEndpoint({idTokenHint:i.idToken,logoutHint:i.userId})}else{const e=new HomeServerApi({homeserver:i.homeServer,accessToken:i.accessToken,request:this._platform.request});await e.logout({log:s}).response()}}catch(e){console.error(e)}await this.deleteSession(s),r&&this._platform.openUrl(r)}))}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._tokenRefresher&&(this._tokenRefresher.stop(),this._tokenRefresher=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(LoadStatus.NotLoading),this._error=null,this._loginFailure=null}}class AccountSetup{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 OIDCLoginMethod{constructor({nonce:e,codeVerifier:t,code:s,homeserver:i,redirectUri:r,oidcApi:n,accountManagementUrl:o}){this._oidcApi=n,this._code=s,this._codeVerifier=t,this._nonce=e,this._redirectUri=r,this.homeserver=i,this._accountManagementUrl=o}async login(e,t,s){const{access_token:i,refresh_token:r,expires_in:n,id_token:o}=await this._oidcApi.completeAuthorizationCodeGrant({code:this._code,codeVerifier:this._codeVerifier,redirectUri:this._redirectUri}),{user_id:a,device_id:l}=await e.whoami({log:s,accessTokenOverride:i}).response();return{oidc_issuer:this._oidcApi.issuer,oidc_client_id:await this._oidcApi.clientId(),access_token:i,refresh_token:r,expires_in:n,id_token:o,user_id:a,device_id:l,oidc_account_management_url:this._accountManagementUrl}}}async function submitLogsToRageshakeServer(e,t,s,i){const r=new Map;e.text&&r.set("text",e.text),r.set("user_agent",e.userAgent),r.set("app",e.app),r.set("version",e.version),e.label&&r.set("label",e.label),r.set("file",{name:"logs.json",blob:t});const n=new Map;n.set("Accept","application/json");const o=i(s,{method:"POST",body:r,headers:n});let a;try{a=await o.response()}catch(e){throw new Error(`Could not submit logs to ${s}, got error ${e.message}`)}const{status:l,body:c}=a;if(l<200||l>=300)throw new Error(`Could not submit logs to ${s}, got status code ${l} with body ${c}`)}async function submitLogsFromSessionToDefaultServer(e,t){const{bugReportEndpointUrl:s}=t.config;if(!s)throw new Error("no server configured to submit logs");const i=t.logger.reporters.find((e=>!!e.export));if(!i)throw new Error("No logger that can export configured");const r=await i.export();await submitLogsToRageshakeServer({app:"hydrogen",userAgent:t.description,version:t.version,text:`Submit logs from settings for user ${e.userId} on device ${e.deviceId}`},r.asBlob(),s,t.request)}class Navigation{constructor(e){this._observables=new Map,this._allowsChild=e,this._path=new Path([],e),this._pathObservable=new ObservableValue$1(this._path)}get pathObservable(){return this._pathObservable}get path(){return this._path}push(e,...t){const s=this.path.with(new Segment(e,...t));s&&this.applyPath(s)}applyPath(e){const t=this._path;this._path=e;for(let e=t.segments.length-1;e>=0;e-=1){const s=t.segments[e];if(!this._path.get(s.type)){const e=this._observables.get(s.type);null==e||e.emitIfChanged()}}for(const e of this._path.segments){const t=this._observables.get(e.type);null==t||t.emitIfChanged()}this._pathObservable.set(this._path)}observe(e){let t=this._observables.get(e);return t||(t=new SegmentObservable(this,e),this._observables.set(e,t)),t}pathFrom(e){let t,s;for(s=0;s<e.length;s+=1){if(!this._allowsChild(t,e[s]))return new Path(e.slice(0,s),this._allowsChild);t=e[s]}return new Path(e,this._allowsChild)}segment(e,...t){return new Segment(e,...t)}}function segmentValueEqual(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){const s=Math.max(e.length,t.length);for(let i=0;i<s;i+=1)if(e[i]!==t[i])return!1;return!0}return!1}class Segment{constructor(e,...t){this.type=e,this.value=void 0===t[0]||t[0]}}class Path{constructor(e=[],t){this._segments=e,this._allowsChild=t}clone(){return new Path(this._segments.slice(),this._allowsChild)}with(e){let t=this._segments.length-1;do{if(this._allowsChild(this._segments[t],e)){const s=this._segments.slice(0,t+1);return s.push(e),new Path(s,this._allowsChild)}t-=1}while(t>=-1)}until(e){const t=this._segments.findIndex((t=>t.type===e));return new Path(-1!==t?this._segments.slice(0,t+1):[],this._allowsChild)}get(e){return this._segments.find((t=>t.type===e))}replace(e){const t=this._segments.findIndex((t=>t.type===e.type));if(-1!==t){const s=this._segments[t-1];if(this._allowsChild(s,e)){const s=this._segments[t+1];if(!s||this._allowsChild(e,s)){const s=this._segments.slice();return s[t]=e,new Path(s,this._allowsChild)}}}}get segments(){return this._segments}}class SegmentObservable extends BaseObservableValue$1{constructor(e,t){var s;super(),this._navigation=e,this._type=t,this._lastSetValue=null==(s=e.path.get(t))?void 0:s.value}get(){const e=this._navigation.path.get(this._type);return null==e?void 0:e.value}emitIfChanged(){const e=this.get();segmentValueEqual(e,this._lastSetValue)||(this._lastSetValue=e,this.emit(e))}}class URLRouter{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 e;const t=null==(e=this._urlAsNavPath(this._history.getLastSessionUrl()||"").get("session"))?void 0:e.value;if("string"==typeof t)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 0!==e.segments.length&&(this._applyNavPathToNavigation(e),!0)}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.origin}createOIDCRedirectURL(){return window.location.origin}createOIDCPostLogoutRedirectURL(){return window.location.origin}absoluteAppUrl(){return window.location.origin}absoluteUrlForAsset(e){return new URL("/assets/"+e,window.location.origin).toString()}normalizeUrl(){this._history.replaceUrlSilently(`${window.location.origin}/${window.location.hash}`)}}function createNavigation(){return new Navigation(allowsChild)}function createRouter({history:e,navigation:t}){return new URLRouter(e,t,parseUrlPath,stringifyPath)}function allowsChild(e,t){const{type:s}=t;switch(null==e?void 0:e.type){case void 0:return"login"===s||"session"===s||"sso"===s||"logout"===s||"oidc"===s;case"session":return"room"===s||"rooms"===s||"settings"===s||"create-room"===s||"join-room"===s||"device-verification"===s;case"rooms":return"room"===s||"empty-grid-tile"===s;case"room":return"lightbox"===s||"right-panel"===s;case"right-panel":return"details"===s||"members"===s||"member"===s;case"logout":return"forced"===s;default:return!1}}function roomsSegmentWithRoom(e,t,s){if(e.value.includes(t))return e;{const i=s.get("empty-grid-tile"),r=s.get("room");let n=0;i?n=i.value:r&&(n=e.value.indexOf(r.value));const o=e.value.slice();return o[n]=t,new Segment("rooms",o)}}function pushRightPanelSegment(e,t,...s){e.push(new Segment("right-panel")),e.push(new Segment(t,...s))}function addPanelIfNeeded(e,t){const s=e.path.segments,i=s.findIndex((e=>"right-panel"===e.type));let r=t;return-1!==i&&(r=t.until("room"),r=r.with(s[i]),r=r.with(s[i+1])),r}function parseUrlPath(e,t,s){const i=[];if(e.includes("state")){const t=new URLSearchParams(e),s=t.get("state"),r=t.get("code"),n=t.get("error");if(s){if(r)return i.push(new Segment("oidc",{success:!0,state:s,code:r})),i;if(n)return i.push(new Segment("oidc",{state:s,success:!1,error:n,errorDescription:t.get("error_description"),errorUri:t.get("error_uri")})),i}}const r=e.substring(1).split("/"),n=r[Symbol.iterator]();let o;for(;!(o=n.next()).done;){const e=o.value;if("rooms"===e){const t=n.next().value;if(void 0===t)break;const s=t.split(",").map((e=>decodeURIComponent(e)));i.push(new Segment(e,s));const r=parseInt(n.next().value||"0",10),o=s[r];o?i.push(new Segment("room",o)):i.push(new Segment("empty-grid-tile",r))}else if("open-room"===e){let e=n.next().value;if(!e)break;e=decodeURIComponent(e);const s=t.get("rooms");s&&i.push(roomsSegmentWithRoom(s,e,t)),i.push(new Segment("room",e));if(r.findIndex((e=>"open-room"===e))>=r.length-2){const e=t.segments,s=e.findIndex((e=>"right-panel"===e.type));-1!==s&&i.push(...e.slice(s))}}else if("last-session"===e){let e=t.get("session");"string"!=typeof(null==e?void 0:e.value)&&s&&(e=new Segment("session",s)),e&&i.push(e)}else if("details"===e||"members"===e)pushRightPanelSegment(i,e);else if("member"===e){let t=n.next().value;if(!t)break;t=decodeURIComponent(t),pushRightPanelSegment(i,e,t)}else if(e.includes("loginToken")){const t=e.split("=").pop();i.push(new Segment("sso",t))}else{let t=n.next().value;t&&(t=decodeURIComponent(t)),i.push(new Segment(e,t))}}return i}function stringifyPath(e){let t,s="";for(const i of e.segments){if("oidc"===i.type)continue;const e=encodeSegmentValue(i.value);switch(i.type){case"rooms":s+=`/rooms/${e}`;break;case"empty-grid-tile":s+=`/${e}`;break;case"room":if("rooms"===(null==t?void 0:t.type)){s+=`/${t.value.indexOf(i.value)}`}else s+=`/${i.type}/${e}`;break;case"right-panel":case"sso":case"oidc-callback":case"oidc-error":continue;default:s+=`/${i.type}`,e&&(s+=`/${e}`)}t=i}return s}function encodeSegmentValue(e){return!0===e?"":Array.isArray(e)?e.map((e=>encodeURIComponent(e))).join(","):encodeURIComponent(e)}function avatarInitials(e){let t=e.charAt(0);return"!"!==t&&"@"!==t&&"#"!==t||(t=e.charAt(1)),t.toUpperCase()}function hashCode(e){let t,s,i=0;if(0===e.length)return i;for(t=0;t<e.length;t++)s=e.charCodeAt(t),i=(i<<5)-i+s,i|=0;return Math.abs(i)}function getIdentifierColorNumber(e){return hashCode(e)%8+1}function getAvatarHttpUrl(e,t,s,i){if(e){const r=t*s.devicePixelRatio;return i.mxcUrlThumbnail(e,r,r,"crop")}}const KIND_ORDER=["roomBeingCreated","invite","room"];class BaseTileViewModel extends ViewModel{constructor(e){super(e),this._isOpen=!1,this._hidden=!1}get hidden(){return this._hidden}set hidden(e){e!==this._hidden&&(this._hidden=e,this.emitChange("hidden"))}close(){this._isOpen&&(this._isOpen=!1,this.emitChange("isOpen"))}open(){this._isOpen||(this._isOpen=!0,this.emitChange("isOpen"))}get isOpen(){return this._isOpen}compare(e){return e.kind!==this.kind?KIND_ORDER.indexOf(this.kind)-KIND_ORDER.indexOf(e.kind):0}get avatarLetter(){return avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._avatarSource.avatarColorId)}avatarUrl(e){return getAvatarHttpUrl(this._avatarSource.avatarUrl,e,this.platform,this._avatarSource.mediaRepository)}get avatarTitle(){return this.name}}class RoomTileViewModel extends BaseTileViewModel{constructor(e){super(e);const{room:t}=e;this._room=t,this._url=this.urlRouter.openRoomActionUrl(this._room.id)}get kind(){return"room"}get url(){return this._url}compare(e){const t=super.compare(e);if(0!==t)return t;const s=this._room,i=e._room;if(s.isLowPriority!==i.isLowPriority)return s.isLowPriority?1:-1;const r=s.lastMessageTimestamp,n=i.lastMessageTimestamp,o=Number.isSafeInteger(r),a=Number.isSafeInteger(n);if(o!==a)return a?1:-1;const l=n-r;if(0===l||!a||!o){const t=this.name.localeCompare(e.name);return 0===t?this._room.id.localeCompare(e._room.id):t}return l}get isUnread(){return this._room.isUnread}get name(){return this._room.name||this.i18n`Empty Room`}get badgeCount(){return this._room.notificationCount}get isHighlighted(){return 0!==this._room.highlightCount}get _avatarSource(){return this._room}}function comparePrimitive(e,t){return e===t?0:e<t?-1:1}class InviteTileViewModel extends BaseTileViewModel{constructor(e){super(e);const{invite:t}=e;this._invite=t,this._url=this.urlRouter.openRoomActionUrl(this._invite.id)}get busy(){return this._invite.accepting||this._invite.rejecting}get kind(){return"invite"}get url(){return this._url}get name(){return this._invite.name}get isHighlighted(){return!0}get isUnread(){return!0}get badgeCount(){return this.i18n`!`}get _avatarSource(){return this._invite}compare(e){const t=super.compare(e);if(0!==t)return t;const s=e._invite.timestamp-this._invite.timestamp;return 0!==s?s:comparePrimitive(this._invite.id,e._invite.id)}}class RoomBeingCreatedTileViewModel extends BaseTileViewModel{constructor(e){super(e);const{roomBeingCreated:t}=e;this._roomBeingCreated=t,this._url=this.urlRouter.openRoomActionUrl(this._roomBeingCreated.id)}get busy(){return!this._roomBeingCreated.error}get kind(){return"roomBeingCreated"}get isHighlighted(){return!this.busy}get badgeCount(){return!this.busy&&this.i18n`Failed`}get url(){return this._url}get name(){return this._roomBeingCreated.name}get _avatarSource(){return this._roomBeingCreated}compare(e){const t=super.compare(e);if(0!==t)return t;const s=comparePrimitive(this.name,e.name);return 0===s?comparePrimitive(this._roomBeingCreated.id,e._roomBeingCreated.id):s}avatarUrl(e){var t;return null!=(t=this._roomBeingCreated.avatarBlobUrl)?t:super.avatarUrl(e)}}class RoomFilter{constructor(e){this._parts=e.split(" ").map((e=>e.toLowerCase().trim()))}matches(e){const t=e.name.toLowerCase();return this._parts.every((e=>t.includes(e)))}}class LeftPanelViewModel extends ViewModel{constructor(e){super(e);const{session:t}=e;this._tileViewModelsMap=this._mapTileViewModels(t.roomsBeingCreated,t.invites,t.rooms),this._tileViewModelsFilterMap=new ApplyMap(this._tileViewModelsMap),this._tileViewModels=this._tileViewModelsFilterMap.sortValues(((e,t)=>e.compare(t))),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(((e,t)=>{var s;let i;i=e.isBeingCreated?new RoomBeingCreatedTileViewModel(this.childOptions({roomBeingCreated:e,emitChange:t})):e.isInvite?new InviteTileViewModel(this.childOptions({invite:e,emitChange:t})):new RoomTileViewModel(this.childOptions({room:e,emitChange:t}));return(null==(s=this.navigation.path.get("room"))?void 0:s.value)===e.id&&(i.open(),this._updateCurrentVM(i)),i}))}_updateCurrentVM(e){var t;null==(t=this._currentTileVM)||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((e=>this._open(e))));const t=this.navigation.observe("rooms");this.gridEnabled=!!t.get(),this.track(t.subscribe((e=>{const t=this.gridEnabled^!!e;this.gridEnabled=!!e,t&&this.emitChange("gridEnabled")})))}_open(e){var t,s;null==(t=this._currentTileVM)||t.close(),this._currentTileVM=null,e&&(this._currentTileVM=this._tileViewModelsMap.get(e),null==(s=this._currentTileVM)||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=addPanelIfNeeded(this.navigation,t)):e?(t=t.with(this.navigation.segment("rooms",[e.value])),t=t.with(e),t=addPanelIfNeeded(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(0===(e=e.trim()).length)return this.clearFilter(),!1;{const t=!this._tileViewModelsFilterMap.hasApply(),s=new RoomFilter(e);return this._tileViewModelsFilterMap.setApply(((e,t)=>{t.hidden=!s.matches(t)})),t}}}class UpdateAction{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 UpdateAction(!0,!1,!1,null)}static Update(e){return new UpdateAction(!1,!0,!1,e)}static Nothing(){return new UpdateAction(!1,!1,!1,null)}static Replace(e){return new UpdateAction(!1,!1,!0,e)}}class TilesCollection extends BaseObservableList{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 t of this._entries)e&&e.tryIncludeEntry(t)||(e=this._createTile(t),e&&this._tiles.push(e));let t=null;for(let e of this._tiles)t&&t.updateNextSibling(e),e.updatePreviousSibling(t),t=e;t&&t.updateNextSibling(null);for(let e=0;e<this._tiles.length;e+=1){const t=this._tiles[e];t.needsDateSeparator&&(this._addTileAt(e,t.createDateSeparator(),!0),e+=1)}for(const e of this._tiles)e.setUpdateEmit(this._emitSpontanousUpdate);this._silent=!1}_findTileIdx(e){return sortedIndex(this._tiles,e,((e,t)=>-t.compareEntry(e)))}_findTileAtIdx(e,t){const s=this._getTileAtIdx(t);if(s&&0===s.compareEntry(e))return s}_getTileAtIdx(e){return e>=0&&e<this._tiles.length?this._tiles[e]:null}onUnsubscribeLast(){this._entrySubscription=this._entrySubscription();for(let e=0;e<this._tiles.length;e+=1)this._tiles[e].dispose();this._tiles=null}onReset(){this._buildInitialTiles(),this.emitReset()}onAdd(e,t){const s=this._findTileIdx(t),i=this._getTileAtIdx(s-1);if(i&&i.tryIncludeEntry(t))return void this.emitUpdate(s-1,i);const r=this._getTileAtIdx(s);if(r&&r.tryIncludeEntry(t))return void this.emitUpdate(s,r);const n=this._createTile(t);n&&(this._addTileAt(s,n),this._evaluateDateHeaderAtIdx(s))}_evaluateDateHeaderAtIdx(e){for(let t=0;t<3;t+=1){const s=e+t;if(s>=this._tiles.length)break;const i=this._tiles[s],r=s>0?this._tiles[s-1]:void 0,n=(null==r?void 0:r.shape)===TileShape.DateHeader;i.needsDateSeparator&&!n?(e+=1,this._addTileAt(s,i.createDateSeparator())):!i.needsDateSeparator&&n&&this._removeTile(s-1,r)}}_addTileAt(e,t,s=!1){const i=e>0?this._tiles[e-1]:void 0,r=this._tiles[e];null==i||i.updateNextSibling(t),t.updatePreviousSibling(i),t.updateNextSibling(r),null==r||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 e=r.updateEntry(t,s);if(e.shouldReplace){const s=this._createTile(t);s?(this._replaceTile(i,r,s,e.updateParams),s.setUpdateEmit(this._emitSpontanousUpdate)):this._removeTile(i,r)}e.shouldRemove&&this._removeTile(i,r),e.shouldUpdate&&this.emitUpdate(i,r,e.updateParams)}}_replaceTile(e,t,s,i){t.dispose();const r=this._getTileAtIdx(e-1),n=this._getTileAtIdx(e+1);this._tiles[e]=s,null==r||r.updateNextSibling(s),s.updatePreviousSibling(r),s.updateNextSibling(n),null==n||n.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),null==s||s.updateNextSibling(i),null==i||i.updatePreviousSibling(s),!s||s.shape!==TileShape.DateHeader||i&&i.needsDateSeparator||this._removeTile(e-1,s)}onRemove(e,t){const s=this._findTileIdx(t),i=this._findTileAtIdx(t,s);if(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=sortedIndex(this._tiles,e,((e,t)=>e.compare(t))),s=this._tiles[t];return 0===(null==s?void 0:s.compare(e))?t:-1}sliceIterator(e,t){return this._tiles.slice(e,t)[Symbol.iterator]()}}class TimelineViewModel extends ViewModel{constructor(e){super(e);const{timeline:t,tileOptions:s}=e;this._timeline=this.track(t),this._tiles=new TilesCollection(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 e of this._tiles.sliceIterator(i,r+1))e.notifyVisible();s=i<10,this._setShowJumpDown(r<this._tiles.length-1)}else s=!0,this._setShowJumpDown(!1);s&&!this._topLoadingPromise&&(this._topLoadingPromise=this._timeline.loadAtTop(10).then((e=>{this._topLoadingPromise=null,e||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 ComposerViewModel extends ViewModel{constructor(e){super(e.options),this._roomVM=e,this._isEmpty=!0,this._replyVM=null}setReplyingTo(e){var t;(new Boolean(e)!==new Boolean(this._replyVM)||!(null==(t=this._replyVM)?void 0:t.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=0===e.length,t&&!this._isEmpty&&this._roomVM._room.ensureMessageKeyIsShared(),t!==this._isEmpty&&this.emitChange("canSend")}get kind(){return"composer"}}class ErrorViewModel extends ViewModel{get message(){return this.error.message}get error(){return this.getOption("error")}close(){this.getOption("onClose")()}async submitLogs(){try{return await submitLogsFromSessionToDefaultServer(this.getOption("session"),this.platform),!0}catch(e){return!1}}}class ErrorReportViewModel extends ViewModel{get errorViewModel(){return this._errorViewModel}reportError(e){var t;(null==(t=this._errorViewModel)?void 0:t.error)!==e&&(this.disposeTracked(this._errorViewModel),this._errorViewModel=this.track(new ErrorViewModel(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((e=>(this.reportError(e),s)))),i}catch(e){return this.reportError(e),s}}}class CallViewModel extends ErrorReportViewModel{constructor(e){super(e);const t=new EventObservableValue(this.call,"change");this.track(t.subscribe((()=>this.onUpdate())));const s=new ObservableValueMap("self",t).mapValues(((e,t)=>new OwnMemberViewModel(this.childOptions({call:e,emitChange:t}))),(()=>{})),i=this.call.members.filterValues((e=>e.isConnected)).mapValues(((e,t)=>new CallMemberViewModel(this.childOptions({member:e,emitChange:t,mediaRepository:this.getOption("room").mediaRepository}))),((e,t)=>null==t?void 0:t.onUpdate()));this.memberViewModels=i.join(s).sortValues(((e,t)=>e.compare(t))),this.track(this.memberViewModels.subscribe({onRemove:()=>{this.emitChange()},onAdd:()=>{this.emitChange()},onUpdate:()=>{},onReset:()=>{},onMove:()=>{}}))}get isCameraMuted(){var e,t;return null==(t=null==(e=this.call.muteSettings)?void 0:e.camera)||t}get isMicrophoneMuted(){var e,t;return null==(t=null==(e=this.call.muteSettings)?void 0:e.microphone)||t}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&&!getStreamVideoTrack(t.userMedia)){const e=await this.platform.mediaDevices.getMediaTracks(!s.microphone,!0);await this.call.setMedia(t.withUserMedia(e))}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&&!getStreamAudioTrack(t.userMedia)){const e=await this.platform.mediaDevices.getMediaTracks(!0,!s.camera);await this.call.setMedia(t.withUserMedia(e))}else await this.call.setMuted(s.toggleMicrophone());this.emitChange()}}))}}class OwnMemberViewModel extends ErrorReportViewModel{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 null==(e=this.call.localPreviewMedia)?void 0:e.userMedia}get call(){return this.getOption("call")}get isCameraMuted(){var e,t;return null==(t=null==(e=this.call.muteSettings)?void 0:e.camera)||t}get isMicrophoneMuted(){var e,t;return null==(t=null==(e=this.call.muteSettings)?void 0:e.microphone)||t}get avatarLetter(){var e;const t=null==(e=this.memberObservable)?void 0:e.get();return t?avatarInitials(t.name):this.getOption("room").user.id}get avatarColorNumber(){return getIdentifierColorNumber(this.getOption("room").user.id)}avatarUrl(e){var t;const s=null==(t=this.memberObservable)?void 0:t.get();if(s)return getAvatarHttpUrl(s.avatarUrl,e,this.platform,this.getOption("room").mediaRepository)}get avatarTitle(){var e;const t=null==(e=this.memberObservable)?void 0:e.get();return t?t.name:this.getOption("room").user.id}compare(e){return-1}}class CallMemberViewModel extends ErrorReportViewModel{get stream(){var e;return null==(e=this.member.remoteMedia)?void 0:e.userMedia}get member(){return this.getOption("member")}get isCameraMuted(){var e,t;return null==(t=null==(e=this.member.remoteMuteSettings)?void 0:e.camera)||t}get isMicrophoneMuted(){var e,t;return null==(t=null==(e=this.member.remoteMuteSettings)?void 0:e.microphone)||t}get avatarLetter(){return avatarInitials(this.member.member.name)}get avatarColorNumber(){return getIdentifierColorNumber(this.member.userId)}avatarUrl(e){const{avatarUrl:t}=this.member.member,s=this.getOption("mediaRepository");return getAvatarHttpUrl(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 CallMemberViewModel){const t=this.member.member.userId,s=e.member.member.userId;return t===s?0:t<s?-1:1}return-e.compare(this)}}function imageToInfo(e){return{w:e.width,h:e.height,mimetype:e.blob.mimeType,size:e.blob.size}}class LocalMedia{constructor(e,t,s){this.userMedia=e,this.screenShare=t,this.dataChannelOptions=s}withUserMedia(e){var t;return new LocalMedia(e,null==(t=this.screenShare)?void 0:t.clone(),this.dataChannelOptions)}withScreenShare(e){var t;return new LocalMedia(null==(t=this.userMedia)?void 0:t.clone(),e,this.dataChannelOptions)}withDataChannel(e){var t,s;return new LocalMedia(null==(t=this.userMedia)?void 0:t.clone(),null==(s=this.screenShare)?void 0:s.clone(),e)}asPreview(){const e=this.clone(),t=e.userMedia;if(t&&t.getVideoTracks().length>0){const e=getStreamAudioTrack(t);e&&(e.stop(),t.removeTrack(e))}return e}replaceClone(e,t){const s=(e,t,s)=>(null==e?void 0:e.id)===(null==s?void 0:s.id)?t:null==s?void 0:s.clone();return new LocalMedia(s(null==t?void 0:t.userMedia,null==e?void 0:e.userMedia,this.userMedia),s(null==t?void 0:t.screenShare,null==e?void 0:e.screenShare,this.screenShare),this.dataChannelOptions)}clone(){var e,t;return new LocalMedia(null==(e=this.userMedia)?void 0:e.clone(),null==(t=this.screenShare)?void 0:t.clone(),this.dataChannelOptions)}dispose(){var e,t,s;null==(e=getStreamAudioTrack(this.userMedia))||e.stop(),null==(t=getStreamVideoTrack(this.userMedia))||t.stop(),null==(s=getStreamVideoTrack(this.screenShare))||s.stop()}}class DateTile extends ViewModel{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 TileShape.DateHeader}get needsDateSeparator(){return!1}createDateSeparator(){}compareEntry(e){const t=this.refEntry.compare(e);return 0===t?-1:t}updateEntry(e,t){return UpdateAction.Nothing()}removeEntry(e){return!1}tryIncludeEntry(){return!1}get comparisonIsNotCommutative(){return!0}updatePreviousSibling(e){this._firstTileInDay.updatePreviousSibling(e)}updateNextSibling(e){var t;if(!e)return;this._firstTileInDay=e;const s=this._dateString;this._dateString=void 0,this._machineReadableString=void 0,s&&s!==this.relativeDate&&(null==(t=this._emitUpdate)||t.call(this,this,"relativeDate"))}notifyVisible(){}dispose(){}}class SimpleTile extends ErrorReportViewModel{constructor(e,t){super(t),this._entry=e,this._date=this._entry.timestamp?new Date(this._entry.timestamp):void 0,this._needsDateSeparator=!1,this._emitUpdate=void 0}get shape(){return null}get isContinuation(){return!1}get needsDateSeparator(){return this._needsDateSeparator}createDateSeparator(){return new DateTile(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!==SendStatus.Sent}get canAbortSending(){return this._entry.isPending&&!this._entry.pendingEvent.hasStartedSending}abortSending(){var e;null==(e=this._entry.pendingEvent)||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="redacted"===this.shape;return e.isGap||e.isRedacted===s?(this._entry=e,UpdateAction.Update(t)):UpdateAction.Replace("shape")}removeEntry(){return!0}tryIncludeEntry(){return!1}updatePreviousSibling(e){(null==e?void 0:e.shape)!==TileShape.DateHeader&&this._updateDateSeparator(e)}updateNextSibling(){}notifyVisible(){}dispose(){this.setUpdateEmit(null),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 GapTile extends SimpleTile{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 ConnectionError?(await this._waitForReconnection(),!e&&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,t=0;this._siblingChanged=!1;do{e=await this.fill(),t+=1}while(t<10&&!this._siblingChanged&&e&&!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?UpdateAction.Nothing():UpdateAction.Remove()}async _waitForReconnection(){this._waitingForConnection=!0,this.emitUpdate("status"),await this.options.client.reconnector.connectionStatus.waitFor((e=>e===ConnectionStatus.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…":this.errorViewModel?`Could not load ${e} messages`:this.isLoading?"Loading more messages…":"Gave up loading more messages"}}class ReactionsViewModel{constructor(e){this._parentTile=e,this._map=new ObservableMap,this._reactions=this._map.sortValues(((e,t)=>e._compare(t)))}update(e,t){if(e)for(const t in e)if(e.hasOwnProperty(t)){const s=e[t],i=this._map.get(t);i?i._tryUpdate(s)&&this._map.update(t):this._map.add(t,new ReactionViewModel(t,s,null,this._parentTile))}if(t)for(const[e,s]of t.entries()){const t=this._map.get(e);t?(t._tryUpdatePending(s),this._map.update(e)):this._map.add(e,new ReactionViewModel(e,null,s,this._parentTile))}for(const s of this._map.keys()){const i=null==t?void 0:t.has(s),r=null==e?void 0:e.hasOwnProperty(s);r||i?r?i||this._map.get(s)._tryUpdatePending(null)&&this._map.update(s):this._map.get(s)._tryUpdate(null)&&this._map.update(s):this._map.remove(s)}}get reactions(){return this._reactions}getReaction(e){return this._map.get(e)}}class ReactionViewModel{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,s=this._annotation&&e&&(e.me!==this._annotation.me||e.count!==this._annotation.count||e.firstTimestamp!==this._annotation.firstTimestamp);return!(!t&&!s)&&(this._annotation=e,!0)}_tryUpdatePending(e){return!(!e&&!this._pending)&&(this._pending=e,!0)}get key(){return this._key}get count(){var e,t;return((null==(e=this._pending)?void 0:e.count)||0)+((null==(t=this._annotation)?void 0:t.count)||0)}get isPending(){return null!==this._pending}get isActive(){var e;return(null==(e=this._annotation)?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 0===t?this.key<e.key?-1:1:t}}async toggle(e=null){if(this._isToggling)console.log("busy toggling reaction already");else{this._isToggling=!0;try{await this._parentTile.toggleReaction(this.key,e)}finally{this._isToggling=!1}}}}class BaseMessageTile extends SimpleTile{constructor(e,t){super(e,t),this._isContinuation=!1,this._reactions=null,this._replyTile=null,(this._entry.annotations||this._entry.pendingAnnotations)&&this._updateReactions(),this._updateReplyTileIfNeeded(void 0)}notifyVisible(){var e;super.notifyVisible(),null==(e=this._replyTile)||e.notifyVisible()}get _mediaRepository(){return this._room.mediaRepository}get permaLink(){return`https://matrix.to/#/${encodeURIComponent(this._room.id)}/${encodeURIComponent(this._entry.id)}`}copyPermalink(){this.platform.copyPlaintext(this.permaLink)}get senderProfileLink(){return`https://matrix.to/#/${encodeURIComponent(this.sender)}`}get memberPanelLink(){return`${this.urlRouter.urlUntilSegment("room")}/member/${this.sender}`}get avatarColorNumber(){return getIdentifierColorNumber(this._entry.sender)}avatarUrl(e){return getAvatarHttpUrl(this._entry.avatarUrl,e,this.platform,this._mediaRepository)}get avatarLetter(){return avatarInitials(this.sender)}get avatarTitle(){return this.sender}get time(){return this._date&&this.timeFormatter.formatTime(this._date)}get isOwn(){return this._entry.sender===this._ownMember.userId}get isContinuation(){return this._isContinuation}get isUnverified(){return this._entry.isUnverified}get isReply(){return this._entry.isReply}_getContent(){return this._entry.content}updatePreviousSibling(e){super.updatePreviousSibling(e);let t=!1;if(e&&e instanceof BaseMessageTile&&e.sender===this.sender){t=this._entry.timestamp-e._entry.timestamp<3e5}t!==this._isContinuation&&(this._isContinuation=t,this.emitChange("isContinuation"))}updateEntry(e,t){const s=super.updateEntry(e,t);return s.shouldUpdate&&this._updateReactions(),this._updateReplyTileIfNeeded(t),s}_updateReplyTileIfNeeded(e){var t,s;const i=this._entry.contextEntry;if(i){const r=null==(t=this._replyTile)?void 0:t.updateEntry(i,e);if((null==r?void 0:r.shouldReplace)||!this._replyTile){this.disposeTracked(this._replyTile);const e=(0,this._options.tileClassForEntry)(i,this._options);e&&(this._replyTile=new e(i,this._options))}(null==r?void 0:r.shouldUpdate)&&(null==(s=this._replyTile)||s.emitChange())}}startReply(){this._roomVM.startReply(this._entry)}createReplyContent(e,t){return this._entry.createReplyContent(e,t)}redact(e,t){return this._room.sendRedaction(this._entry.id,e,t)}get canRedact(){return this._powerLevels.canRedactFromSender(this._entry.sender)}get reactions(){return"redacted"!==this.shape?this._reactions:null}get canReact(){return this._powerLevels.canSendType("m.reaction")}react(e,t=null){return this.logger.wrapOrRun(t,"react",(async t=>{var s,i;if(!this.canReact)return void t.set("powerlevel_lacking",!0);if(this._entry.haveAnnotation(e))return void t.set("already_reacted",!0);const r=null==(i=null==(s=this._entry.pendingAnnotations)?void 0:s.get(e))?void 0:i.redactionEntry;r&&!r.pendingEvent.hasStartedSending?(t.set("abort_redaction",!0),await r.pendingEvent.abort()):await this._room.sendEvent("m.reaction",this._entry.annotate(e),null,t)}))}redactReaction(e,t=null){return this.logger.wrapOrRun(t,"redactReaction",(async t=>{var s,i;if(!this._powerLevels.canRedactFromSender(this._ownMember.userId))return void t.set("powerlevel_lacking",!0);if(!this._entry.haveAnnotation(e))return void t.set("not_yet_reacted",!0);let r=null==(i=null==(s=this._entry.pendingAnnotations)?void 0:s.get(e))?void 0:i.annotationEntry;r||(r=await this._timeline.getOwnAnnotationEntry(this._entry.id,e)),r?await this._room.sendRedaction(r.id,null,t):t.set("no_reaction",!0)}))}toggleReaction(e,t=null){return this.logger.wrapOrRun(t,"toggleReaction",(async t=>{this._entry.haveAnnotation(e)?await this.redactReaction(e,t):await this.react(e,t)}))}_updateReactions(){const{annotations:e,pendingAnnotations:t}=this._entry;e||t?(this._reactions||(this._reactions=new ReactionsViewModel(this)),this._reactions.update(e,t)):this._reactions&&(this._reactions=null)}get replyTile(){return this._entry.contextEventId?this._replyTile:null}}const scheme="(?:https|http|ftp):\\/\\/",noSpaceNorPunctuation="[^\\s.,?!)]",hostCharacter="[a-zA-Z0-9:.\\[\\]-]",host=`${hostCharacter}*(?=${hostCharacter})[^\\s.,?!)]`,pathOrFragment="(?:[\\/#](?:[^\\s]*[^\\s.,?!)])?)",urlRegex=`${scheme}${host}${pathOrFragment}?`,regex=new RegExp(urlRegex,"gi");function linkify(e,t){const s=e.matchAll(regex);let i=0;for(let r of s){t(e.slice(i,r.index),!1),t(r[0],!0);const s=r[0].length;i=r.index+s}t(e.slice(i),!1)}function parsePlainBody(e){const t=[],s=e.split("\n"),i=(e,s)=>{s?t.push(new LinkPart(e,[new TextPart(e)])):t.push(new TextPart(e))};for(let e=0;e<s.length;e+=1){const r=s[e];r.length&&linkify(r,i);e>=s.length-1||t.push(new NewLinePart)}return new MessageBody(e,t)}function stringAsBody(e){return new MessageBody(e,[new TextPart(e)])}class HeaderBlock{constructor(e,t){this.level=e,this.inlines=t}get type(){return"header"}}class CodeBlock{constructor(e,t){this.language=e,this.text=t}get type(){return"codeblock"}}class ListBlock{constructor(e,t){this.items=t,this.startOffset=e}get type(){return"list"}}class TableBlock{constructor(e,t){this.head=e,this.body=t}get type(){return"table"}}class RulePart{get type(){return"rule"}}class NewLinePart{get type(){return"newline"}}class FormatPart{constructor(e,t){this.format=e.toLowerCase(),this.children=t}get type(){return"format"}}class ImagePart{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 PillPart{constructor(e,t,s){this.id=e,this.href=t,this.children=s}get type(){return"pill"}get avatarColorNumber(){return getIdentifierColorNumber(this.id)}get avatarInitials(){return avatarInitials(this.id)}}class LinkPart{constructor(e,t){this.url=e,this.inlines=t}get type(){return"link"}}class TextPart{constructor(e){this.text=e}get type(){return"text"}}function isBlockquote(e){return"format"===e.type&&"blockquote"===e.format}class MessageBody{constructor(e,t){this.sourceString=e,this.parts=t}insertEmote(e){let t=0;for(;t<this.parts.length&&isBlockquote(this.parts[t]);t++);this.parts.splice(t,0,new TextPart(e))}}const BodyFormat=createEnum("Plain","Html");class BaseTextTile extends BaseMessageTile{constructor(e,t){super(e,t),this._messageBody=null,this._format=null}get shape(){return"message"}_parseBody(e){return stringAsBody(e)}_getBodyFormat(){return BodyFormat.Plain}get body(){const e=this._getBody(),t=this._getBodyFormat();return this._messageBody&&this._messageBody.sourceString===e&&this._format===t||(this._messageBody=this._parseBody(e,t),this._format=t),this._messageBody}}const basicInline=["EM","STRONG","CODE","DEL","SPAN"],basicBlock=["DIV","BLOCKQUOTE"],safeSchemas=["https","http","ftp","mailto","magnet"].map((e=>`${e}://`)),baseUrl="https://matrix.to",linkPrefix=`${baseUrl}/#/`;class Deserializer{constructor(e,t){this.result=e,this.mediaRepository=t}parsePillLink(e){if(!e.startsWith(linkPrefix))return null;const t=e.substring(linkPrefix.length);return"@"===t[0]?t:null}parseLink(e,t){const s=this.result.getAttributeValue(e,"href"),i=null==s?void 0:s.toLowerCase();if(!i||!safeSchemas.some((e=>i.startsWith(e))))return new FormatPart("span",t);const r=this.parsePillLink(s);return r?new PillPart(r,s,t):new LinkPart(s,t)}parseList(e){const t=this.result;let s=null;"OL"===t.getNodeElementName(e)&&(s=parseInt(t.getAttributeValue(e,"start"))||1);const i=[];for(const s of t.getChildNodes(e)){if("LI"!==t.getNodeElementName(s))continue;const e=this.parseAnyNodes(t.getChildNodes(s));i.push(e)}return new ListBlock(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 i of t.getChildNodes(e)){s=i;break}let i=null;if(!this._ensureElement(s,"CODE"))return new CodeBlock(i,this.result.getNodeText(e));const r=t.getAttributeValue(s,"class")||"";for(const e of r.split(" "))if(e.startsWith("language-")&&!e.startsWith("language-_")){i=e.substring(9);break}return new CodeBlock(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,n=parseInt(t.getAttributeValue(e,"height"))||null,o=t.getAttributeValue(e,"alt"),a=t.getAttributeValue(e,"title");return new ImagePart(i,r,n,o,a)}parseTableRow(e,t){const s=[];for(const i of this.result.getChildNodes(e)){if(!this._ensureElement(i,t))continue;const e=this.result.getChildNodes(i),r=this.parseInlineNodes(e);s.push(r)}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 TableBlock(s,i)}parseInlineElement(e){const t=this.result,s=t.getNodeElementName(e),i=t.getChildNodes(e);switch(s){case"A":{const t=this.parseInlineNodes(i);return this.parseLink(e,t)}case"BR":return new NewLinePart;default:{if(!basicInline.includes(s))return null;const e=this.parseInlineNodes(i);return new FormatPart(s,e)}}}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 e=this.parseInlineNodes(i);return new HeaderBlock(parseInt(s[1]),e)}case"UL":case"OL":return this.parseList(e);case"PRE":return this.parseCodeBlock(e);case"HR":return new RulePart;case"IMG":return this.parseImage(e);case"P":{const e=this.parseInlineNodes(i);return new FormatPart(s,e)}case"TABLE":return this.parseTable(e);default:{if(!basicBlock.includes(s))return null;const e=this.parseAnyNodes(i);return new FormatPart(s,e)}}}parseBlockNode(e){return this.result.isElementNode(e)?this.parseBlockElement(e):null}_parseTextParts(e,t){if(!this.result.isTextNode(e))return!1;return linkify(this.result.getNodeText(e),((e,s)=>{s?t.push(new LinkPart(e,[new TextPart(e)])):t.push(new TextPart(e))})),!0}_isAllowedNode(e){return!this._ensureElement(e,"MX-REPLY")}_parseInlineNodes(e,t){for(const s of e){if(this._parseTextParts(s,t))continue;const e=this.parseInlineNode(s);e?t.push(e):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 e=this.parseInlineNode(s)||this.parseBlockNode(s);e?t.push(e):this._isAllowedNode(s)&&this._parseAnyNodes(this.result.getChildNodes(s),t)}}parseAnyNodes(e){const t=[];return this._parseAnyNodes(e,t),t}}function parseHTMLBody(e,t,s){const i=e.parseHTML(s),r=new Deserializer(i,t).parseAnyNodes(i.rootNodes);return new MessageBody(s,r)}class TextTile extends BaseTextTile{_getContentString(e){var t;return(null==(t=this._getContent())?void 0:t[e])||""}_getPlainBody(){return this._getContentString("body")}_getFormattedBody(){return this._getContentString("formatted_body")}_getBody(){return this._getBodyFormat()===BodyFormat.Html?this._getFormattedBody():this._getPlainBody()}_getBodyFormat(){var e;return"org.matrix.custom.html"===(null==(e=this._getContent())?void 0:e.format)?BodyFormat.Html:BodyFormat.Plain}_parseBody(e,t){var s;let i;return i=t===BodyFormat.Html?parseHTMLBody(this.platform,this._mediaRepository,e):parsePlainBody(e),"m.emote"===(null==(s=this._getContent())?void 0:s.msgtype)&&i.insertEmote(`* ${this.displayName} `),i}}class RedactedTile extends BaseMessageTile{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 MAX_HEIGHT=300,MAX_WIDTH=400;class BaseMediaTile extends BaseMessageTile{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;let s;this._downloading=!0,this.emitChange("status");try{s=await this._mediaRepository.downloadAttachment(e),this.platform.saveFileAs(s,t)}catch(e){this._downloadError=e}finally{null==s||s.dispose(),this._downloading=!1}this.emitChange("status")}get isUploading(){return this.isPending&&this._entry.pendingEvent.status===SendStatus.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(null==e?void 0:e.status){case SendStatus.Waiting:return this.i18n`Waiting…`;case SendStatus.EncryptingAttachments:case SendStatus.Encrypting:return this.i18n`Encrypting…`;case SendStatus.UploadingAttachments:return this.i18n`Uploading…`;case SendStatus.Sending:return this.i18n`Sending…`;case SendStatus.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 t=null==(e=this._getContent().info)?void 0:e.thumbnail_url;if(t)return this._mediaRepository.mxcUrlThumbnail(t,this.width,this.height,"scale")}if(this._entry.isPending){const e=this._entry.pendingEvent.getAttachment("info.thumbnail_url");return e&&e.localPreview.url}if(this._isMainResourceImage()){if(this._decryptedFile)return this._decryptedFile.url;{const e=null==(t=this._getContent())?void 0:t.url;if("string"==typeof e)return this._mediaRepository.mxcUrlThumbnail(e,this.width,this.height,"scale")}}return""}notifyVisible(){super.notifyVisible(),this._isVisible=!0,this.emitChange("thumbnailUrl"),this.isPending||this._tryLoadEncryptedThumbnail()}get width(){var e;const t=null==(e=this._getContent())?void 0:e.info;return Math.round((null==t?void 0:t.w)*this._scaleFactor())}get height(){var e;const t=null==(e=this._getContent())?void 0:e.info;return Math.round((null==t?void 0:t.h)*this._scaleFactor())}get mimeType(){var e;const t=null==(e=this._getContent())?void 0:e.info;return null==t?void 0:t.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)return this.track(t);t.dispose()}async _tryLoadEncryptedThumbnail(){var e;try{const t=null==(e=this._getContent().info)?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(e){this._error=e,this.emitChange("error")}}_scaleFactor(){var e;const t=null==(e=this._getContent())?void 0:e.info,s=300/(null==t?void 0:t.h),i=400/(null==t?void 0:t.w);return Math.min(i,s,1)}_isMainResourceImage(){return!0}}class ImageTile extends BaseMediaTile{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 VideoTile extends BaseMediaTile{async loadVideo(){const e=this._getContent().file;e&&!this._decryptedFile&&(this._decryptedFile=await this._loadEncryptedFile(e),this.emitChange("videoUrl"))}get videoUrl(){var e;if(this._decryptedFile)return this._decryptedFile.url;const t=null==(e=this._getContent())?void 0:e.url;return"string"==typeof t?this._mediaRepository.mxcUrl(t):""}get shape(){return"video"}_isMainResourceImage(){return!1}}function formatSize(e,t=2){if(Number.isSafeInteger(e)){const s=Math.min(3,Math.floor(Math.log(e)/Math.log(1024))),i=Math.round(e/Math.pow(1024,s)).toFixed(t);switch(s){case 0:return`${i} bytes`;case 1:return`${i} KB`;case 2:return`${i} MB`;case 3:return`${i} GB`}}return""}class FileTile extends BaseMessageTile{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;let s;this._downloading=!0,this.emitChange("label");try{s=await this._mediaRepository.downloadAttachment(e),this.platform.saveFileAs(s,t)}catch(e){this._downloadError=e}finally{null==s||s.dispose(),this._downloading=!1}this.emitChange("label")}get label(){var e;if(this._downloadError)return`Could not download file: ${this._downloadError.message}`;const t=this._getContent().body;if(!this._entry.isPending){const s=formatSize(null==(e=this._getContent().info)?void 0:e.size);return this._downloading?this.i18n`Downloading ${t} (${s})…`:this.i18n`Download ${t} (${s})`}{const{pendingEvent:e}=this._entry;switch(null==e?void 0:e.status){case SendStatus.Waiting:return this.i18n`Waiting to send ${t}…`;case SendStatus.EncryptingAttachments:case SendStatus.Encrypting:return this.i18n`Encrypting ${t}…`;case SendStatus.UploadingAttachments:{const s=Math.round(e.attachmentsSentBytes/e.attachmentsTotalBytes*100);return this.i18n`Uploading ${t}: ${s}%`}case SendStatus.Sending:case SendStatus.Sent:return this.i18n`Sending ${t}…`;case SendStatus.Error:return this.i18n`Error: could not send ${t}: ${e.error.message}`;default:return`Unknown send status for ${t}`}}}get shape(){return"file"}}class LocationTile extends BaseMessageTile{get shape(){return"location"}get mapsLink(){try{const e=new URL(this._getContent().geo_uri);if("geo:"!==e.protocol)return"";const[t,...s]=e.pathname.split(";"),[i,r]=t.split(","),n=parseFloat(i),o=parseFloat(r);let a;for(const e of s){const[t,s]=e.split("=");"u"===t&&(a=parseFloat(s))}if(this.platform.isIOS)return`http://maps.apple.com/?ll=${n},${o}`;{let e=`geo:${n},${o}`;return a&&(e+=`;u=${a}`),e}}catch{return""}}get label(){return this.i18n`${this.displayName} sent their location`}}class RoomNameTile extends SimpleTile{get shape(){return"announcement"}get announcement(){const e=this._entry.content;return`${this._entry.displayName||this._entry.sender} named the room "${null==e?void 0:e.name}"`}}class RoomMemberTile extends SimpleTile{get shape(){return"announcement"}get announcement(){var e,t;const{sender:s,content:i,prevContent:r,stateKey:n}=this._entry,o=this._entry.displayName||s,a=s===n?o:(null==(e=this._entry.content)?void 0:e.displayname)||n,l=i&&i.membership,c=r&&r.membership;if("join"===c&&"join"===l){if(i.avatar_url!==r.avatar_url)return`${o} changed their avatar`;if(i.displayname!==r.displayname)return i.displayname?`${null!=(t=r.displayname)?t:n} changed their name to ${i.displayname}`:`${n} removed their name (${r.displayname})`}else{if("join"===l)return`${a} joined the room`;if("invite"===l)return`${a} was invited to the room by ${o}`;if("invite"===c){if("join"===l)return`${a} accepted the invitation to join the room`;if("leave"===l)return`${a} declined the invitation to join the room`}else{if("leave"===l){if(n===s)return`${a} left the room`;{const e=i.reason;return`${a} was kicked from the room by ${o}${e?`: ${e}`:""}`}}if("ban"===l)return`${a} was banned from the room by ${o}`}}return`${s} membership changed to ${i.membership}`}}class EncryptedEventTile extends BaseTextTile{updateEntry(e,t){const s=super.updateEntry(e,t);return"m.room.encrypted"!==e.eventType?UpdateAction.Replace("shape"):s}get shape(){return"message-status"}_getBody(){const e=this._entry.decryptionError;let t;return t="MEGOLM_NO_SESSION"===(null==e?void 0:e.code)?this.i18n`The sender hasn't sent us the key for this message yet.`:(null==e?void 0:e.message)||this.i18n`Could not decrypt message because of unknown reason.`,t}}class EncryptionEnabledTile extends SimpleTile{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 MissingAttachmentTile extends BaseMessageTile{get shape(){return"missing-attachment"}get label(){const e=this._getContent().body;return"m.image"===this._getContent().msgtype?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 CallTile extends SimpleTile{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(((e,t)=>new MemberAvatarViewModel(this.childOptions({member:e,emitChange:t,mediaRepository:this.getOption("room").mediaRepository})))).sortValues(((e,t)=>e.userId.localeCompare(t.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===CallType.Video?`${this.displayName} started a video call`:`${this.displayName} started a voice call`:this.type===CallType.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===CallType.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 LocalMedia).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 MemberAvatarViewModel extends ViewModel{get _member(){return this.getOption("member")}get userId(){return this._member.userId}get avatarLetter(){return avatarInitials(this._member.member.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._member.userId)}avatarUrl(e){const{avatarUrl:t}=this._member.member,s=this.getOption("mediaRepository");return getAvatarHttpUrl(t,e,this.platform,s)}get avatarTitle(){return this._member.member.name}}function tileClassForEntry(e,t){if(e.isGap)return GapTile;if(e.isPending&&e.pendingEvent.isMissingAttachments)return MissingAttachmentTile;if(e.eventType)switch(e.eventType){case"m.room.message":{if(e.isRedacted)return RedactedTile;const t=e.content;switch(t&&t.msgtype){case"m.text":case"m.notice":case"m.emote":return TextTile;case"m.image":return ImageTile;case"m.video":return VideoTile;case"m.file":return FileTile;case"m.location":return LocationTile;default:return}}case"m.room.name":return RoomNameTile;case"m.room.member":return RoomMemberTile;case"m.room.encrypted":return e.isRedacted?RedactedTile:EncryptedEventTile;case"m.room.encryption":return EncryptionEnabledTile;case"org.matrix.msc3401.call":return t.features.calls&&e.stateKey&&!e.prevContent?CallTile:void 0;default:return}}async function joinRoom(e,t){var s,i,r,n;try{const s=await t.joinRoom(e),i=await t.observeRoomStatus(s);return await i.waitFor((e=>e===RoomStatus.Joined)),s}catch(t){throw 400===(null!=(s=t.statusCode)?s:t.status)?new Error(`'${e}' is not a legal room ID or alias`):404===(null!=(i=t.statusCode)?i:t.status)||502===(null!=(r=t.statusCode)?r:t.status)||"Internal Server eor"==t.message?new Error(`Room '${e}' could not be found`):403===(null!=(n=t.statusCode)?n:t.status)?new Error(`You are not invited to join '${e}'`):t}}class RoomViewModel extends ErrorReportViewModel{constructor(e){super(e);const{room:t,tileClassForEntry:s}=e;this._room=t,this._timelineVM=null,this._tileClassForEntry=null!=s?s:tileClassForEntry,this._tileOptions=void 0,this._onRoomChange=this._onRoomChange.bind(this),this._composerVM=null,t.isArchived?this._composerVM=this.track(new ArchivedViewModel(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 PickMapObservableValue(e.filterValues((e=>e.roomId===this._room.id&&e.hasJoined))),this._callViewModel=void 0,this.track(this._callObservable.subscribe((e=>{e&&this._callViewModel&&e.id===this._callViewModel.id||(this._callViewModel=this.disposeTracked(this._callViewModel),e&&(this._callViewModel=this.track(new CallViewModel(this.childOptions({call:e,room:this._room})))),this.emitChange("callViewModel"))})));const t=this._callObservable.get();t&&(this._callViewModel=this.track(new CallViewModel(this.childOptions({call:t,room:this._room}))))}async load(){this.logAndCatch("RoomViewModel.load",(async e=>{this._room.on("change",this._onRoomChange);const t=await this._room.openTimeline(e);this._tileOptions=this.childOptions({session:this.getOption("session"),roomVM:this,timeline:t,tileClassForEntry:this._tileClassForEntry}),this._timelineVM=this.track(new TimelineViewModel(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=e=>{this._composerVM=this.disposeTracked(this._composerVM),this._composerVM=e?this.track(new ComposerViewModel(this)):this.track(new LowerPowerLevelViewModel(this.childOptions())),this.emitChange("powerLevelObservable")};this.track(e.subscribe((()=>{const e=t();s!==e&&(i(e),s=e)}))),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._clearUnreadTimout=null}catch(t){if("AbortError"!==t.name)throw t;e.set("clearUnreadCancelled",!0)}}}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;null==(e=this._composerVM)||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 avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._room.avatarColorId)}avatarUrl(e){return getAvatarHttpUrl(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,n="m.text";if(e.startsWith("//"))e=e.substring(1).trim();else if(e.startsWith("/")){const t=await this._processCommand(e);n=t.msgtype,e=t.message}t?(s.set("replyingTo",t.eventId),r=await t.createReplyContent(n,e)):r={msgtype:n,body:e},await this._room.sendEvent("m.room.message",r,void 0,s),i=!0}return s.set("success",i),i}),!1)}async _processCommandJoin(e){try{const t=this._options.client.session,s=await joinRoom(e,t);this.navigation.push("room",s)}catch(e){this.reportError(e)}}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(1===i.length){const e=i[0];await this._processCommandJoin(e)}else this.reportError(new Error("join syntax: /join <room-id>"));break;case"shrug":e="¯\\_(ツ)_/¯ "+i.join(" "),t="m.text";break;case"tableflip":e="(╯°□°）╯︵ ┻━┻ "+i.join(" "),t="m.text";break;case"unflip":e="┬──┬ ノ( ゜-゜ノ) "+i.join(" "),t="m.text";break;case"lenny":e="( ͡° ͜ʖ ͡°) "+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)return this._sendFile(t,e);e.set("cancelled",!0)}))}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(e){throw e instanceof window.MediaError&&4===e.code?new Error(`this browser does not support videos of type ${null==t?void 0:t.blob.mimeType}.`):e}const i={body:t.name,msgtype:"m.video",info:videoToInfo(s)},r={url:this._room.createAttachment(s.blob,t.name)},n=await this.platform.settingsStorage.getInt("sentImageSizeLimit")||Math.min(s.maxDimension,800),o=await s.scale(n);i.info.thumbnail_info=imageToInfo(o),r["info.thumbnail_url"]=this._room.createAttachment(o.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())return void alert("Please allow canvas image data access, so we can scale your images down.");const t=await this.platform.openFile("image/*");if(!t)return void e.set("cancelled",!0);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 e=await s.scale(i);s.dispose(),s=e}const r={body:t.name,msgtype:"m.image",info:imageToInfo(s)},n={url:this._room.createAttachment(s.blob,t.name)};if(s.maxDimension>600){const e=await s.scale(400);r.info.thumbnail_info=imageToInfo(e),n["info.thumbnail_url"]=this._room.createAttachment(e.blob,t.name)}await this._room.sendEvent("m.room.message",r,n,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)return void e.set("feature_disbled",!0);let t;e.set("roomId",this._room.id);try{const e=await this.platform.mediaDevices.getMediaTracks(!1,!0);t=(new LocalMedia).withUserMedia(e)}catch(e){throw new Error(`Could not get local audio and/or video stream: ${e.message}`)}const s=this.getOption("session");let i;try{i=await s.callHandler.createCall(this._room.id,"m.video","A call "+Math.round(100*this.platform.random()),void 0,e)}catch(e){throw new Error(`Could not create call: ${e.message}`)}try{await i.join(t,e)}catch(e){throw new Error(`Could not join call: ${e.message}`)}}))}}function videoToInfo(e){const t=imageToInfo(e);return t.duration=e.duration,t}class ArchivedViewModel extends ViewModel{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 LowerPowerLevelViewModel extends ViewModel{get description(){return this.i18n`You do not have the powerlevel necessary to send messages`}get kind(){return"disabled"}}class UnknownRoomViewModel extends ViewModel{constructor(e){super(e);const{roomIdOrAlias:t,session:s}=e;this._session=s,this.roomIdOrAlias=t,this._error=null,this._busy=!1}get error(){var e;return null==(e=this._error)?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 InviteViewModel extends ViewModel{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 RoomMemberViewModel(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 avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._invite.avatarColorId)}avatarUrl(e){return getAvatarHttpUrl(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(" • ")}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 RoomMemberViewModel{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 avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._member.userId)}avatarUrl(e){return getAvatarHttpUrl(this._member.avatarUrl,e,this._platform,this._mediaRepository)}get avatarTitle(){return this.name}}class RoomBeingCreatedViewModel extends ViewModel{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?"ConnectionError"===e.name?this.i18n`You seem to be offline`:e.message:""}get avatarLetter(){return avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._roomBeingCreated.avatarColorId)}get avatarTitle(){return this.name}avatarUrl(e){var t;return null!=(t=this._roomBeingCreated.avatarBlobUrl)?t:getAvatarHttpUrl(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 LightboxViewModel extends ViewModel{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((t=>{this._loadEvent(e,t)}))),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 null==(s=null==(t=null==(e=this._eventEntry)?void 0:e.content)?void 0:t.info)?void 0:s.w}get imageHeight(){var e,t,s;return null==(s=null==(t=null==(e=this._eventEntry)?void 0:e.content)?void 0:t.info)?void 0:s.h}get name(){var e,t;return null==(t=null==(e=this._eventEntry)?void 0:e.content)?void 0:t.body}get sender(){var e;return null==(e=this._eventEntry)?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 SessionStatus=createEnum("Disconnected","Connecting","FirstSync","Sending","Syncing","SyncError");class SessionStatusViewModel extends ViewModel{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!==SessionStatus.Syncing}get statusLabel(){switch(this._status){case SessionStatus.Disconnected:{const e=Math.round(this._reconnector.retryIn/1e3);return this.i18n`Disconnected, trying to reconnect in ${e}s…`}case SessionStatus.Connecting:return this.i18n`Trying to reconnect now…`;case SessionStatus.FirstSync:return this.i18n`Catching up with your conversations…`;case SessionStatus.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 SessionStatus.Connecting:case SessionStatus.FirstSync:return!0;default:return!1}}_updateStatus(){const e=this._calculateState(this._reconnector.connectionStatus.get(),this._sync.status.get());e!==this._status&&(e===SessionStatus.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!==ConnectionStatus.Online)switch(e){case ConnectionStatus.Reconnecting:return SessionStatus.Connecting;case ConnectionStatus.Waiting:return SessionStatus.Disconnected}else{if(t===SyncStatus.Syncing)return SessionStatus.Syncing;switch(t){case SyncStatus.InitialSync:case SyncStatus.CatchupSync:return SessionStatus.FirstSync;case SyncStatus.Stopped:return SessionStatus.SyncError}}}get isConnectNowShown(){return this._status===SessionStatus.Disconnected}get isSecretStorageShown(){return this._status===SessionStatus.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 dedupeSparse(e){return e.map(((t,s)=>e.slice(0,s).includes(t)?void 0:t))}class RoomGridViewModel extends ViewModel{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((e=>{"number"==typeof e&&this._setFocusIndex(e)}))),"number"==typeof e.get()&&(this._selectedIndex=e.get());const t=this.navigation.observe("room");this.track(t.subscribe((e=>{e&&this._setFocusRoom(e)})))}roomViewModelAt(e){var t;return null==(t=this._viewModelsObservables[e])?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=addPanelIfNeeded(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=dedupeSparse(e);let s=!1;if(t){const i=e.indexOf(t.id);-1!==i&&(this._viewModelsObservables[i]=this.track(t),t.subscribe((e=>this._refreshRoomViewModel(e))),s=!0)}this.setRoomIds(e);const i=this.navigation.path.get("room");if(i){const e=this._viewModelsObservables.findIndex((e=>e&&e.id===i.value));-1!==e&&(this._selectedIndex=e)}return s}setRoomIds(e){e=dedupeSparse(e);let t=!1;const s=this._height*this._width;for(let i=0;i<s;i+=1){const s=e[i],r=this._viewModelsObservables[i];if(!r&&s||r&&r.id!==s){if(r&&(this._viewModelsObservables[i]=this.disposeTracked(r)),s){const e=this._createRoomViewModelObservable(s);this._viewModelsObservables[i]=this.track(e),e.subscribe((e=>this._refreshRoomViewModel(e))),e.initialize()}t=!0}}return t&&this.emitChange(),t}_refreshRoomViewModel(e){this.emitChange(),null==e||e.focus()}releaseRoomViewModel(e){const t=this._viewModelsObservables.findIndex((t=>t&&t.id===e));if(-1!==t){const e=this._viewModelsObservables[t];return this.untrack(e),e.unsubscribeAll(),this._viewModelsObservables[t]=null,e}}_setFocusIndex(e){var t;if(e===this._selectedIndex||e>=this._width*this._height)return;this._selectedIndex=e;const s=this._viewModelsObservables[this._selectedIndex];null==(t=null==s?void 0:s.get())||t.focus(),this.emitChange("focusIndex")}_setFocusRoom(e){const t=this._viewModelsObservables.findIndex((t=>(null==t?void 0:t.id)===e));t>=0&&this._setFocusIndex(t)}}class FeaturesViewModel extends ViewModel{constructor(e){super(e),this.featureViewModels=[new FeatureViewModel(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:FeatureFlag.Calls})),new FeatureViewModel(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:FeatureFlag.CrossSigning}))]}}class FeatureViewModel extends ViewModel{get enabled(){return this.features.isFeatureEnabled(this.getOption("feature"))}async enableFeature(e){let t;t=e?this.features.withFeature(this.getOption("feature")):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 PushNotificationStatus{constructor(){this.supported=null,this.enabled=!1,this.updating=!1,this.enabledOnServer=null,this.serverError=null}}function formatKey(e){const t=Math.ceil(e.length/4);let s="";for(let i=0;i<t;i+=1)s+=(s.length?" ":"")+e.slice(4*i,4*(i+1));return s}class SettingsViewModel extends ViewModel{constructor(e){super(e),this._updateService=e.updateService;const{client:t}=e;this._client=t,this._keyBackupViewModel=this.track(new KeyBackupViewModel(this.childOptions({session:this._session}))),this._closeUrl=this.urlRouter.urlUntilSegment("session"),this._estimate=null,this.sentImageSizeLimit=null,this.minSentImageSizeLimit=400,this.maxSentImageSizeLimit=4e3,this.pushNotifications=new PushNotificationStatus,this._activeTheme=void 0,this._logsFeedbackMessage=void 0,this._accountManagementUrl=null,this._featuresViewModel=new FeaturesViewModel(this.childOptions()),this._accountManagementUrl=null}get _session(){return this._client.session}async logout(){this.navigation.push("logout",this._client.sessionId)}setSentImageSizeLimit(e){e>this.maxSentImageSizeLimit||e<this.minSentImageSizeLimit?(this.sentImageSizeLimit=null,this.platform.settingsStorage.remove("sentImageSizeLimit")):(this.sentImageSizeLimit=Math.round(e),this.platform.settingsStorage.setInt("sentImageSizeLimit",e)),this.emitChange("sentImageSizeLimit")}async load(){this._estimate=await this.platform.estimateStorageUsage(),this.sentImageSizeLimit=await this.platform.settingsStorage.getInt("sentImageSizeLimit"),this.pushNotifications.supported=await this.platform.notificationService.supportsPush(),this.pushNotifications.enabled=await this._session.arePushNotificationsEnabled(),this._activeTheme=await this.platform.themeLoader.getActiveTheme();const{accountManagementUrl:e}=await this.platform.sessionInfoStorage.get(this._client._sessionId);this._accountManagementUrl=e,this.emitChange("")}get accountManagementUrl(){return this._accountManagementUrl}get closeUrl(){return this._closeUrl}get fingerprintKey(){const e=this._session.fingerprintKey;return e?formatKey(e):null}get deviceId(){return this._session.deviceId}get userId(){return this._session.userId}get version(){const{updateService:e}=this.platform;return e?`${e.version} (${e.buildHash})`:this.i18n`development version`}checkForUpdate(){var e;null==(e=this.platform.updateService)||e.checkForUpdate()}get showUpdateButton(){return!!this.platform.updateService}get keyBackupViewModel(){return this._keyBackupViewModel}get featuresViewModel(){return this._featuresViewModel}get storageQuota(){var e;return this._formatBytes(null==(e=this._estimate)?void 0:e.quota)}get storageUsage(){var e;return this._formatBytes(null==(e=this._estimate)?void 0:e.usage)}get themeMapping(){return this.platform.themeLoader.themeMapping}get activeTheme(){return this._activeTheme}_formatBytes(e){return"number"==typeof e?Math.round(e/1048576).toFixed(1)+" MB":this.i18n`unknown`}async exportLogs(){const e=await this.exportLogsBlob();this.platform.saveFileAs(e,`hydrogen-logs-${this.platform.clock.now()}.json`)}async exportLogsBlob(){const e=this.logger.reporters.find((e=>"function"==typeof e.export));return(await e.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(e){}return""}async sendLogsToServer(){this._logsFeedbackMessage=this.i18n`Sending logs…`;try{await submitLogsFromSessionToDefaultServer(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 CreateRoomViewModel extends ViewModel{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}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}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 e,t;let s;this._avatarScaledBlob&&(s={info:this._avatarInfo,name:this._avatarFileName,blob:this._avatarScaledBlob});const i=this._session.createRoom({type:this.isPublic?RoomVisibility.Public:RoomVisibility.Private,name:null!=(e=this._name)?e:void 0,topic:null!=(t=this._topic)?t:void 0,isEncrypted:!this.isPublic&&this._isEncrypted,isFederationDisabled:this._isFederationDisabled,alias:this.isPublic?ensureAliasIsLocalPart(this._roomAlias):void 0,avatar:s});this.navigation.push("room",i.id)}async selectAvatar(){if(!this.platform.hasReadPixelPermission())return void alert("Please allow canvas image data access, so we can scale your images down.");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/"))return void this.emitChange("hasAvatar");let t=await this.platform.loadImage(e.blob);if(t.maxDimension>800){const e=await t.scale(800);t.dispose(),t=e}this._avatarScaledBlob=t.blob,this._avatarInfo=imageToInfo(t),this._avatarFileName=e.name,this.emitChange("hasAvatar")}}function ensureAliasIsLocalPart(e){e.startsWith("#")&&(e=e.substr(1));const t=e.indexOf(":");return-1!==t&&(e=e.substr(0,t)),e}class JoinRoomViewModel extends ViewModel{constructor(e){super(e),this._joinInProgress=!1,this._session=e.session}async join(e){this._error=void 0,this._joinInProgress=!0,this.emitChange("joinInProgress");try{const t=await joinRoom(e,this._session);this.navigation.push("room",t)}catch(e){this._error=e,this._joinInProgress=!1,this.emitChange("error")}}get joinInProgress(){return this._joinInProgress}get status(){return this._error?this._error.message:this._joinInProgress?"Joining room":void 0}}class WaitingForOtherUserViewModel extends ViewModel{async cancel(){await this.options.sas.abort()}get kind(){return"waiting-for-user"}}class VerificationCancelledViewModel extends ViewModel{get cancelCode(){return this.options.cancellation.code}get isCancelledByUs(){return this.options.cancellation.cancelledByUs}gotoSettings(){this.navigation.push("settings",!0)}get kind(){return"verification-cancelled"}}class SelectMethodViewModel extends ErrorReportViewModel{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 kind(){return"select-method"}}class VerifyEmojisViewModel extends ErrorReportViewModel{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 VerificationCompleteViewModel extends ErrorReportViewModel{get otherDeviceId(){return this.options.deviceId}gotoSettings(){this.navigation.push("settings",!0)}get kind(){return"verification-completed"}}class DeviceVerificationViewModel extends ErrorReportViewModel{constructor(e){super(e);const t=e.request;e.request?this.start(t):this.start(this.getOption("session").userId)}async start(e){await this.logAndCatch("DeviceVerificationViewModel.start",(t=>{const s=this.getOption("session").crossSigning.get();return this.sas=s.startVerification(e,t),this.addEventListeners(),"string"==typeof e&&this.updateCurrentStageViewModel(new WaitingForOtherUserViewModel(this.childOptions({sas:this.sas}))),this.sas.start()}))}addEventListeners(){this.track(this.sas.disposableOn("SelectVerificationStage",(e=>{this.updateCurrentStageViewModel(new SelectMethodViewModel(this.childOptions({sas:this.sas,stage:e})))}))),this.track(this.sas.disposableOn("EmojiGenerated",(e=>{this.updateCurrentStageViewModel(new VerifyEmojisViewModel(this.childOptions({stage:e})))}))),this.track(this.sas.disposableOn("VerificationCancelled",(e=>{this.updateCurrentStageViewModel(new VerificationCancelledViewModel(this.childOptions({cancellation:e})))}))),this.track(this.sas.disposableOn("VerificationCompleted",(e=>{this.updateCurrentStageViewModel(new VerificationCompleteViewModel(this.childOptions({deviceId:e})))})))}updateCurrentStageViewModel(e){this._currentStageViewModel=this.disposeTracked(this._currentStageViewModel),this._currentStageViewModel=this.track(e),this.emitChange("currentStageViewModel")}dispose(){this.sas.finished||this.sas.abort().catch((()=>{})),super.dispose()}get currentStageViewModel(){return this._currentStageViewModel}}class RoomViewModelObservable extends ObservableValue$1{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 e=>{var t;null==(t=this.get())||t.dispose(),this.set(await this._statusToViewModel(e))}))}async _statusToViewModel(e){if(!(e&RoomStatus.Replaced))return e&RoomStatus.BeingCreated?this._sessionViewModel._createRoomBeingCreatedViewModel(this.id):e&RoomStatus.Invited?this._sessionViewModel._createInviteViewModel(this.id):e&RoomStatus.Joined?this._sessionViewModel._createRoomViewModelInstance(this.id):e&RoomStatus.Archived?await this._sessionViewModel._createArchivedRoomViewModel(this.id):this._sessionViewModel._createUnknownRoomViewModel(this.id);if(!(e&RoomStatus.BeingCreated))throw new Error("Don't know how to replace a room with this status: "+(e^RoomStatus.Replaced));{const{session:e}=this._sessionViewModel._client,t=e.roomsBeingCreated.get(this.id);this._sessionViewModel.notifyRoomReplaced(t.id,t.roomId)}}dispose(){var e;this._statusSubscription&&(this._statusSubscription=this._statusSubscription()),this.unsubscribeAll(),null==(e=this.get())||e.dispose()}}class RoomDetailsViewModel extends ViewModel{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 avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this._room.avatarColorId)}avatarUrl(e){return getAvatarHttpUrl(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 MemberTileViewModel extends ViewModel{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 avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this.userId)}avatarUrl(e){return getAvatarHttpUrl(this._member.avatarUrl,e,this.platform,this._mediaRepository)}get avatarTitle(){return this.name}}function createMemberComparator(e){const t=new Intl.Collator,s=e=>"@"===e.charAt(0)?e.slice(1):e;return function(i,r){const n=e.getUserLevel(i.userId),o=e.getUserLevel(r.userId);if(n!==o)return o-n;const a=s(i.name),l=s(r.name);return t.compare(a,l)}}class Disambiguator{constructor(){this._map=new Map}_unDisambiguate(e,t){const s=t.indexOf(e);if(-1!==s){const[e]=t.splice(s,1);e.setDisambiguation(!1)}}_handlePreviousName(e){const t=e.previousName;if("string"!=typeof t)return;const s=this._map.get(t);if(Array.isArray(s)){if(this._unDisambiguate(e,s),1===s.length){const e=s[0];e.setDisambiguation(!1),this._map.set(t,e)}}else this._map.delete(t)}_updateMap(e){const t=e.name,s=this._map.get(t);if(s){if(Array.isArray(s)){if(-1!==s.findIndex((t=>t.userId===e.userId)))return;return 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);null==t||t.forEach((e=>e.setDisambiguation(!0)))}}class MemberListViewModel extends ViewModel{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((e=>"join"===e.membership))).sortValues(createMemberComparator(i)),this.nameDisambiguator=new Disambiguator,this.mediaRepository=e.mediaRepository}get type(){return"member-list"}get shouldShowBackButton(){return!0}get previousSegmentName(){return"details"}_mapTileViewModels(e){return e.mapValues(((e,t)=>{const s=this.mediaRepository,i=new MemberTileViewModel(this.childOptions({member:e,emitChange:t,mediaRepository:s}));return this.nameDisambiguator.disambiguate(i),i}),((e,t,s)=>{t.updateFrom(s),this.nameDisambiguator.disambiguate(t)}))}}class MemberDetailsViewModel extends ViewModel{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 trustDescription(){var e;switch(null==(e=this._userTrust)?void 0:e.get()){case UserTrust.Trusted:return this.i18n`You have verified this user. This user has verified all of their sessions.`;case UserTrust.UserNotSigned:return this.i18n`You have not verified this user.`;case UserTrust.UserSignatureMismatch:return this.i18n`You appear to have signed this user, but the signature is invalid.`;case UserTrust.UserDeviceNotSigned:return this.i18n`You have verified this user, but they have one or more unverified sessions.`;case UserTrust.UserDeviceSignatureMismatch:return this.i18n`This user has a session signature that is invalid.`;case UserTrust.UserSetupError:return this.i18n`This user hasn't set up cross-signing correctly`;case UserTrust.OwnSetupError:return this.i18n`Cross-signing wasn't set up correctly on your side.`;default:return this.i18n`Please wait…`}}get trustShieldColor(){var e;if(!this._isEncrypted)return"";switch(null==(e=this._userTrust)?void 0:e.get()){case void 0:case UserTrust.OwnSetupError:return"";case UserTrust.Trusted:return"green";case UserTrust.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`:0===this.powerLevel?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)}))}get avatarLetter(){return avatarInitials(this.name)}get avatarColorNumber(){return getIdentifierColorNumber(this.userId)}avatarUrl(e){return getAvatarHttpUrl(this._member.avatarUrl,e,this.platform,this._mediaRepository)}get avatarTitle(){return this.name}get isEncrypted(){return this._isEncrypted}get powerLevel(){var e;return null==(e=this._powerLevelsObservable.get())?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=null==e?void 0:e.id;if(!t){t=(await this._session.createRoom({type:RoomVisibility.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 RightPanelViewModel extends ViewModel{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 e=this.navigation.path.get("member").value,t=await this._room.observeMember(e);if(!t)return!1;return{observableMember:t,isEncrypted:this._room.isEncrypted,powerLevelsObservable:await this._room.observePowerLevels(),mediaRepository:this._room.mediaRepository,session:this._session}}_setupNavigation(){this._hookUpdaterToSegment("details",RoomDetailsViewModel,(()=>({room:this._room}))),this._hookUpdaterToSegment("members",MemberListViewModel,(()=>this._getMemberListArguments())),this._hookUpdaterToSegment("member",MemberDetailsViewModel,(()=>this._getMemberDetailsArguments()),(()=>{const e=`${this.urlRouter.urlUntilSegment("room")}/members`;this.urlRouter.pushUrl(e)}))}_hookUpdaterToSegment(e,t,s,i){const r=this.navigation.observe(e),n=this._setupUpdater(e,t,s,i);this.track(r.subscribe(n))}_setupUpdater(e,t,s,i){const r=async(r=!1)=>{var n;r||(this._activeViewModel=this.disposeTracked(this._activeViewModel));if(!!(null==(n=this.navigation.path.get(e))?void 0:n.value)){const e=await s();if(!e&&i)return void i();this._activeViewModel=this.track(new t(this.childOptions(e)))}this.emitChange("activeViewModel")};return 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 BaseToastNotificationViewModel extends ErrorReportViewModel{constructor(e){super(e)}dismiss(){this.getOption("dismiss")()}}class CallToastNotificationViewModel extends BaseToastNotificationViewModel{constructor(e){super(e),this.track(this.call.members.observeSize().subscribe((()=>{this.emitChange("memberCount")}))),this.track(this.navigation.observe("room").subscribe((e=>{e===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 LocalMedia).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 avatarInitials(this.roomName)}get avatarColorNumber(){return getIdentifierColorNumber(this.room.avatarColorId)}avatarUrl(e){return getAvatarHttpUrl(this.room.avatarUrl,e,this.platform,this.room.mediaRepository)}get avatarTitle(){return this.roomName}}class CallToastCollectionViewModel extends ViewModel{constructor(e){super(e),this.toastViewModels=new ObservableArray;const t=this.getOption("session");if(this.features.calls){const e=t.callHandler.calls;this.track(e.subscribe(this))}}async onAdd(e,t){if(this._shouldShowNotification(t)){const e=await this._findRoomForCall(t),s=()=>{const e=this.toastViewModels.array.findIndex((e=>e.call===t));-1!==e&&this.toastViewModels.remove(e)};this.toastViewModels.append(new CallToastNotificationViewModel(this.childOptions({call:t,room:e,dismiss:s})))}}onRemove(e,t){const s=this.toastViewModels.array.findIndex((e=>e.call===t));-1!==s&&this.toastViewModels.remove(s)}onUpdate(e,t){const s=this.toastViewModels.array.findIndex((e=>e.call===t));-1!==s&&this.toastViewModels.update(s,this.toastViewModels.at(s))}onReset(){for(let e=0;e<this.toastViewModels.length;++e)this.toastViewModels.remove(e)}async _findRoomForCall(e){const t=e.roomId,s=this.getOption("session"),i=s.rooms,r=await s.observeRoomStatus(t);await r.waitFor((e=>e===RoomStatus.Joined)).promise;return i.get(t)}_shouldShowNotification(e){var t;const s=null==(t=this.navigation.path.get("room"))?void 0:t.value;return!e.isLoadedFromStorage&&e.roomId!==s&&!e.usesFoci}}class VerificationToastNotificationViewModel extends BaseToastNotificationViewModel{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 VerificationToastCollectionViewModel extends ViewModel{constructor(e){super(e),this.toastViewModels=new ObservableArray,this.subscribeToSASRequests()}async subscribeToSASRequests(){await this.getOption("session").crossSigning.waitFor((e=>!!e)).promise;const e=this.getOption("session").crossSigning.get();this.track(e.receivedSASVerifications.subscribe(this))}async onAdd(e,t){this.toastViewModels.append(this.track(new VerificationToastNotificationViewModel(this.childOptions({request:t,dismiss:()=>{const e=this.toastViewModels.array.findIndex((e=>e.request.id===t.id));-1!==e&&this.toastViewModels.remove(e)}}))))}onRemove(e,t){const s=this.toastViewModels.array.findIndex((e=>e.request.id===t.id));-1!==s&&this.toastViewModels.remove(s)}onUpdate(e,t){const s=this.toastViewModels.array.findIndex((e=>e.request.id===t.id));-1!==s&&this.toastViewModels.update(s,this.toastViewModels.at(s))}onReset(){for(let e=0;e<this.toastViewModels.length;++e)this.toastViewModels.remove(e)}}class ToastCollectionViewModel extends ViewModel{constructor(e){super(e);const t=this.getOption("session"),s=[];this.features.calls&&s.push(this.track(new CallToastCollectionViewModel(this.childOptions({session:t})))),this.features.crossSigning&&s.push(this.track(new VerificationToastCollectionViewModel(this.childOptions({session:t}))));const i=s.map((e=>e.toastViewModels));0!==i.length&&(this.toastViewModels=new ConcatList(...i))}}class SessionViewModel extends ViewModel{constructor(e){super(e);const{client:t}=e;this._client=this.track(t),this._sessionStatusViewModel=this.track(new SessionStatusViewModel(this.childOptions({sync:t.sync,reconnector:t.reconnector,session:t.session}))),this._leftPanelViewModel=this.track(new LeftPanelViewModel(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 ToastCollectionViewModel(this.childOptions({session:this._client.session}))),this._setupNavigation(),this._setupForcedLogoutOnAccessTokenInvalidation()}_setupNavigation(){const e=this.navigation.observe("rooms");this.track(e.subscribe((e=>{this._updateGrid(e)}))),e.get()&&this._updateGrid(e.get());const t=this.navigation.observe("room");this.track(t.subscribe((e=>{this._gridViewModel||this._updateRoom(e),this._updateRightPanel()}))),this._gridViewModel||this._updateRoom(t.get());const s=this.navigation.observe("settings");this.track(s.subscribe((e=>{this._updateSettings(e)}))),this._updateSettings(s.get());const i=this.navigation.observe("create-room");this.track(i.subscribe((e=>{this._updateCreateRoom(e)}))),this._updateCreateRoom(i.get());const r=this.navigation.observe("join-room");if(this.track(r.subscribe((e=>{this._updateJoinRoom(e)}))),this._updateJoinRoom(r.get()),this.features.crossSigning){const e=this.navigation.observe("device-verification");this.track(e.subscribe((e=>{this._updateVerification(e)}))),this._updateVerification(e.get())}const n=this.navigation.observe("lightbox");this.track(n.subscribe((e=>{this._updateLightbox(e)}))),this._updateLightbox(n.get());const o=this.navigation.observe("right-panel");this.track(o.subscribe((()=>this._updateRightPanel()))),this._updateRightPanel()}_setupForcedLogoutOnAccessTokenInvalidation(){this.track(this._client.sync.status.subscribe((e=>{if(e===SyncStatus.Stopped){const e=this._client.sync.error;if("M_UNKNOWN_TOKEN"===(null==e?void 0:e.errcode)){const e=[this.navigation.segment("logout",this.id),this.navigation.segment("forced",!0)],t=this.navigation.pathFrom(e);this.navigation.applyPath(t)}}})))}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(null==(e=this._roomViewModelObservable)?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 null==(e=this._roomViewModelObservable)?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 t;const s=!(this._gridViewModel&&e),i=this.navigation.path.get("room");if(e)this._gridViewModel?this._gridViewModel.setRoomIds(e):(this._gridViewModel=this.track(new RoomGridViewModel(this.childOptions({width:3,height:2,createRoomViewModelObservable:e=>new RoomViewModelObservable(this,e)}))),null==(t=this._roomViewModelObservable)||t.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(i){const e=this._gridViewModel.releaseRoomViewModel(i.value);e&&(this._roomViewModelObservable=this.track(e),this._roomViewModelObservable.subscribe((()=>{this.emitChange("activeMiddleViewModel")})))}this._gridViewModel=this.disposeTracked(this._gridViewModel)}s&&this.emitChange("activeMiddleViewModel")}_createRoomViewModelInstance(e){const t=this._client.session.rooms.get(e);if(t){const e=new RoomViewModel(this.childOptions({room:t,session:this._client.session}));return e.load(),e}return null}_createUnknownRoomViewModel(e){return new UnknownRoomViewModel(this.childOptions({roomIdOrAlias:e,session:this._client.session}))}async _createArchivedRoomViewModel(e){const t=await this._client.session.loadArchivedRoom(e);if(t){const e=new RoomViewModel(this.childOptions({room:t,session:this._client.session}));return e.load(),e}return null}_createInviteViewModel(e){const t=this._client.session.invites.get(e);return t?new InviteViewModel(this.childOptions({invite:t,mediaRepository:this._client.session.mediaRepository})):null}_createRoomBeingCreatedViewModel(e){const t=this._client.session.roomsBeingCreated.get(e);return t?new RoomBeingCreatedViewModel(this.childOptions({roomBeingCreated:t,mediaRepository:this._client.session.mediaRepository})):null}_updateRoom(e){var t;if((null==(t=this._roomViewModelObservable)?void 0:t.id)===e)return;if(this._roomViewModelObservable&&(this._roomViewModelObservable=this.disposeTracked(this._roomViewModelObservable)),!e)return void this.emitChange("activeMiddleViewModel");const s=new RoomViewModelObservable(this,e);this._roomViewModelObservable=this.track(s),this._roomViewModelObservable.subscribe((()=>{this.emitChange("activeMiddleViewModel")})),s.initialize()}_updateSettings(e){this._settingsViewModel&&(this._settingsViewModel=this.disposeTracked(this._settingsViewModel)),e&&(this._settingsViewModel=this.track(new SettingsViewModel(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 CreateRoomViewModel(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 JoinRoomViewModel(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=null==(t=this._client.session.crossSigning.get())?void 0:t.receivedSASVerifications.get(e);this._verificationViewModel=this.track(new DeviceVerificationViewModel(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 LightboxViewModel(this.childOptions({eventId:e,room:t})))}this.emitChange("lightboxViewModel")}get lightboxViewModel(){return this._lightboxViewModel}_roomFromNavigation(){var e;const t=null==(e=this.navigation.path.get("room"))?void 0:e.value;return this._client.session.rooms.get(t)}_updateRightPanel(){var e;this._rightPanelViewModel=this.disposeTracked(this._rightPanelViewModel);if(!!(null==(e=this.navigation.path.get("right-panel"))?void 0:e.value)){const e=this._roomFromNavigation();this._rightPanelViewModel=this.track(new RightPanelViewModel(this.childOptions({room:e,session:this._client.session})))}this.emitChange("rightPanelViewModel")}notifyRoomReplaced(e,t){this.navigation.push("room",t)}}class AccountSetupViewModel extends ViewModel{constructor(e){super(e),this._accountSetup=e.accountSetup,this._dehydratedDevice=void 0,this._decryptDehydratedDeviceViewModel=void 0,this._accountSetup.encryptedDehydratedDevice&&(this._decryptDehydratedDeviceViewModel=new DecryptDehydratedDeviceViewModel(this,(e=>{this._dehydratedDevice=e,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 DecryptDehydratedDeviceViewModel extends ViewModel{constructor(e,t){super(e.options),this._accountSetupViewModel=e,this._isBusy=!1,this._status=Status.SetupKey,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 null==(e=this._accountSetupViewModel._dehydratedDevice)?void 0:e.deviceId}get isBusy(){return this._isBusy}get backupVersion(){return 0}get status(){return this._status}get error(){var e;return null==(e=this._error)?void 0:e.message}showPhraseSetup(){this._status===Status.SetupKey&&(this._status=Status.SetupPhrase,this.emitChange("status"))}showKeySetup(){this._status===Status.SetupPhrase&&(this._status=Status.SetupKey,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(e){console.error(e),this._error=e,this.emitChange("error")}finally{this._isBusy=!1,this.emitChange("")}}enterSecurityPhrase(e){this._enterCredentials(KeyType.Passphrase,e)}enterSecurityKey(e){this._enterCredentials(KeyType.RecoveryKey,e)}disable(){}}class SessionLoadViewModel extends ViewModel{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((e=>{e===LoadStatus.AccountSetup?this._accountSetupViewModel=new AccountSetupViewModel(this.childOptions({accountSetup:this._client.accountSetup})):this._accountSetupViewModel=void 0,this.emitChange("loadLabel");return e===LoadStatus.FirstSync&&this._client.sync.status.get()===SyncStatus.CatchupSync||e===LoadStatus.LoginFailed||e===LoadStatus.Error||e===LoadStatus.Ready}));try{await this._waitHandle.promise}catch(e){return}const e=this._client.loadStatus.get(),t=this._client.loadError;if(e===LoadStatus.FirstSync||e===LoadStatus.Ready){const e=this._client;this._client=null,this._ready(e)}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()!==LoadStatus.AccountSetup)&&this._loading}get loadLabel(){const e=this._client,t=this._getError();if(t||e&&e.loadStatus.get()===LoadStatus.Error)return`Something went wrong: ${t&&t.message}.`;if(e)switch(e.loadStatus.get()){case LoadStatus.QueryAccount:return"Querying account encryption setup…";case LoadStatus.AccountSetup:return"";case LoadStatus.SessionSetup:return"Setting up your encryption keys…";case LoadStatus.Loading:return"Loading your conversations…";case LoadStatus.FirstSync:return"Getting your conversations from the server…";default:return this._client.loadStatus.get()}return"Preparing…"}_getError(){var e;return this._error||(null==(e=this._client)?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(){var e;await this._client.startLogout(null==(e=this.navigation.path.get("session"))?void 0:e.value,this.urlRouter),this.navigation.push("session",!0)}get accountSetupViewModel(){return this._accountSetupViewModel}}class PasswordLoginViewModel extends ViewModel{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");let s="";switch(await this._attemptLogin(this._loginOptions.password(e,t))){case LoginFailure.Credentials:s=this.i18n`Your username and/or password don't seem to be correct.`;break;case LoginFailure.Connection:s=this.i18n`Can't connect to ${this._loginOptions.homeserver}.`;break;case LoginFailure.Unknown:s=this.i18n`Something went wrong while checking your login and password.`}s&&this._showError(s)}}class StartSSOLoginViewModel extends ViewModel{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 CompleteSSOLoginViewModel extends ViewModel{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(e){return void this._showError(e.message)}if(!t.token)return void this.navigation.push("session");let s="";switch(await this._attemptLogin(t.token(this._loginToken))){case LoginFailure.Credentials:s=this.i18n`Your login token is invalid.`;break;case LoginFailure.Connection:s=this.i18n`Can't connect to ${e}.`;break;case LoginFailure.Unknown:s=this.i18n`Something went wrong while checking your login token.`}s&&this._showError(s)}}class StartOIDCLoginViewModel extends ViewModel{constructor(e){super(e),this._isBusy=!0,this._issuer=e.loginOptions.oidc.issuer,this._accountManagementUrl=e.loginOptions.oidc.account,this._homeserver=e.loginOptions.homeserver,this._api=new OidcApi({issuer:this._issuer,request:this.platform.request,encoding:this.platform.encoding,crypto:this.platform.crypto,urlRouter:this.urlRouter,staticClients:this.platform.config.staticOidcClients}),this._asGuest=e.asGuest}get isBusy(){return this._isBusy}setBusy(e){this._isBusy=e,this.emitChange("isBusy")}async discover(){try{await this._api.metadata()}catch(e){throw this.logger.log("Failed to discover OIDC metadata: "+e),new Error("Failed to discover OIDC metadata: "+e.message)}try{await this._api.registration()}catch(e){throw this.logger.log("Failed to register OIDC client: "+e),new Error("Failed to register OIDC client: "+e.message)}}async startOIDCLogin(){const e=this._api.generateDeviceScope(),t=this._api.generateParams({scope:`openid urn:matrix:org.matrix.msc2967.client:api:${this._asGuest?"guest":"*"} ${e}`,redirectUri:this.urlRouter.createOIDCRedirectURL()}),s=await this._api.clientId();await Promise.all([this.platform.settingsStorage.setInt(`oidc_${t.state}_started_at`,Date.now()),this.platform.settingsStorage.setString(`oidc_${t.state}_nonce`,t.nonce),this.platform.settingsStorage.setString(`oidc_${t.state}_code_verifier`,t.codeVerifier),this.platform.settingsStorage.setString(`oidc_${t.state}_redirect_uri`,t.redirectUri),this.platform.settingsStorage.setString(`oidc_${t.state}_homeserver`,this._homeserver),this.platform.settingsStorage.setString(`oidc_${t.state}_issuer`,this._issuer),this.platform.settingsStorage.setString(`oidc_${t.state}_client_id`,s),this.platform.settingsStorage.setString(`oidc_${t.state}_account_management_url`,this._accountManagementUrl)]);const i=await this._api.authorizationEndpoint(t);this.platform.openUrl(i)}}class CompleteOIDCLoginViewModel extends ViewModel{constructor(e){super(e);const{state:t,code:s,attemptLogin:i}=e;this._request=e.platform.request,this._encoding=e.platform.encoding,this._crypto=e.platform.crypto,this._state=t,this._code=s,this._attemptLogin=i,this._errorMessage="",this.performOIDCLoginCompletion()}get errorMessage(){return this._errorMessage}_showError(e){this._errorMessage=e,this.emitChange("errorMessage")}async performOIDCLoginCompletion(){if(!this._state||!this._code)return;const e=this._code,[t,s,i,r,n,o,a,l]=await Promise.all([this.platform.settingsStorage.getInt(`oidc_${this._state}_started_at`),this.platform.settingsStorage.getString(`oidc_${this._state}_nonce`),this.platform.settingsStorage.getString(`oidc_${this._state}_code_verifier`),this.platform.settingsStorage.getString(`oidc_${this._state}_redirect_uri`),this.platform.settingsStorage.getString(`oidc_${this._state}_homeserver`),this.platform.settingsStorage.getString(`oidc_${this._state}_issuer`),this.platform.settingsStorage.getString(`oidc_${this._state}_client_id`),this.platform.settingsStorage.getString(`oidc_${this._state}_account_management_url`)]),c=new OidcApi({issuer:o,clientId:a,request:this._request,encoding:this._encoding,crypto:this._crypto}),d=new OIDCLoginMethod({oidcApi:c,nonce:s,codeVerifier:i,code:e,homeserver:n,startedAt:t,redirectUri:r,accountManagementUrl:l});let h="";switch(await this._attemptLogin(d)){case LoginFailure.Credentials:h=this.i18n`Your login token is invalid.`;break;case LoginFailure.Connection:h=this.i18n`Can't connect to ${n}.`;break;case LoginFailure.Unknown:h=this.i18n`Something went wrong while checking your login token.`}h&&this._showError(h)}}class LoginViewModel extends ViewModel{constructor(e){super(e),this._hideHomeserver=!1,this._isBusy=!1,this._errorMessage="";const{ready:t,defaultHomeserver:s,loginToken:i,oidc:r}=e;this._ready=t,this._loginToken=i,this._oidc=r,this._client=new Client(this.platform,this.features),this._oidc=r,this._homeserver=s,this._initViewModels()}get passwordLoginViewModel(){return this._passwordLoginViewModel}get startSSOLoginViewModel(){return this._startSSOLoginViewModel}get completeSSOLoginViewModel(){return this._completeSSOLoginViewModel}get startOIDCLoginViewModel(){return this._startOIDCLoginViewModel}get startOIDCGuestLoginViewModel(){return this._startOIDCGuestLoginViewModel}get completeOIDCLoginViewModel(){return this._completeOIDCLoginViewModel}get homeserver(){return this._homeserver}get resolvedHomeserver(){var e;return null==(e=this._loginOptions)?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(){var e,t,s;this._loginToken?(this._hideHomeserver=!0,this._completeSSOLoginViewModel=this.track(new CompleteSSOLoginViewModel(this.childOptions({client:this._client,attemptLogin:e=>this.attemptLogin(e),loginToken:this._loginToken}))),this.emitChange("completeSSOLoginViewModel")):!0===(null==(e=this._oidc)?void 0:e.success)?(this._hideHomeserver=!0,this._completeOIDCLoginViewModel=this.track(new CompleteOIDCLoginViewModel(this.childOptions({client:this._client,attemptLogin:e=>this.attemptLogin(e),state:this._oidc.state,code:this._oidc.code}))),this.emitChange("completeOIDCLoginViewModel")):!1===(null==(t=this._oidc)?void 0:t.success)?(this._hideHomeserver=!1,this._showError(`Sign in failed: ${null!=(s=this._oidc.errorDescription)?s:this._oidc.error} `)):this.queryHomeserver()}_showPasswordLogin(){this._passwordLoginViewModel=this.track(new PasswordLoginViewModel(this.childOptions({loginOptions:this._loginOptions,attemptLogin:e=>this.attemptLogin(e)}))),this.emitChange("passwordLoginViewModel")}_showSSOLogin(){this._startSSOLoginViewModel=this.track(new StartSSOLoginViewModel(this.childOptions({loginOptions:this._loginOptions}))),this.emitChange("startSSOLoginViewModel")}async _showOIDCLogin(){this._startOIDCLoginViewModel=this.track(new StartOIDCLoginViewModel(this.childOptions({loginOptions:this._loginOptions,asGuest:!1}))),this.emitChange("startOIDCLoginViewModel");try{await this._startOIDCLoginViewModel.discover()}catch(e){this._showError(e.message),this._disposeViewModels()}}async _showOIDCGuestLogin(){this._startOIDCGuestLoginViewModel=this.track(new StartOIDCLoginViewModel(this.childOptions({loginOptions:this._loginOptions,asGuest:!0}))),this.emitChange("startOIDCGuestLoginViewModel");try{await this._startOIDCLoginViewModel.discover()}catch(e){this._showError(e.message),this._disposeViewModels()}}_showError(e){this._errorMessage=e,this.emitChange("errorMessage")}_setBusy(e){var t,s,i,r;this._isBusy=e,null==(t=this._passwordLoginViewModel)||t.setBusy(e),null==(s=this._startSSOLoginViewModel)||s.setBusy(e),null==(i=this._startOIDCLoginViewModel)||i.setBusy(e),null==(r=this._startOIDCGuestLoginViewModel)||r.setBusy(e),this.emitChange("isBusy")}async attemptLogin(e){this._setBusy(!0),this._client.startWithLogin(e,{inspectAccountSetup:!0});const t=this._client.loadStatus,s=t.waitFor((e=>e!==LoadStatus.Login));await s.promise,this._setBusy(!1);return t.get()===LoadStatus.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 SessionLoadViewModel(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._startOIDCLoginViewModel=this.disposeTracked(this._startOIDCLoginViewModel),this._startOIDCGuestLoginViewModel=this.disposeTracked(this._startOIDCGuestLoginViewModel),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(e){if("AbortError"===e.name)return;throw e}this._abortHomeserverQueryTimeout=this.disposeTracked(this._abortHomeserverQueryTimeout),this.queryHomeserver()}async queryHomeserver(){var e;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("AbortError"===e.name)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.oidc&&this._showOIDCLogin(),(null==(e=this._loginOptions.oidc)?void 0:e.guestAvailable)&&this._showOIDCGuestLogin(),this._loginOptions.sso||this._loginOptions.password||this._loginOptions.oidc||this._showError("This homeserver supports neither SSO nor password based login flows or has a usable OIDC Provider")):this._showError(`Could not query login methods supported by ${this.homeserver}`)}}dispose(){super.dispose(),this._client&&this._client.deleteSession()}}class LogoutViewModel extends ViewModel{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{const e=new Client(this.platform);await e.startLogout(this._sessionId,this.urlRouter),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 ForcedLogoutViewModel extends ViewModel{constructor(e){super(e),this._showStatus=!1,this._showSpinner=!1,this._sessionId=e.sessionId,this._logoutPromise=this.forceLogout()}async forceLogout(){try{const e=new Client(this.platform);await e.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 SessionItemViewModel extends ViewModel{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 getIdentifierColorNumber(this._sessionInfo.userId)}get avatarInitials(){return avatarInitials(this._sessionInfo.userId)}}class SessionPickerViewModel extends ViewModel{constructor(e){super(e),this._sessions=new SortedArray(((e,t)=>e.id.localeCompare(t.id))),this._loadViewModel=null,this._error=null}async load(){const e=await this.platform.sessionInfoStorage.getAll();this._sessions.setManyUnsorted(e.map((e=>new SessionItemViewModel(this.childOptions({sessionInfo:e}),this))))}get loadViewModel(){return this._loadViewModel}get sessions(){return this._sessions}get cancelUrl(){return this.urlRouter.urlForSegment("login")}}class RootViewModel extends ViewModel{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.track(this.navigation.observe("oidc").subscribe((()=>this._applyNavigation()))),this._applyNavigation(!0)}async _applyNavigation(e){var t,s,i,r,n;const o=this.navigation.path.get("login"),a=null==(t=this.navigation.path.get("logout"))?void 0:t.value,l=null==(s=this.navigation.path.get("forced"))?void 0:s.value,c=null==(i=this.navigation.path.get("session"))?void 0:i.value,d=null==(r=this.navigation.path.get("sso"))?void 0:r.value,h=null==(n=this.navigation.path.get("oidc"))?void 0:n.value;if(o)"login"!==this.activeSection&&this._showLogin();else if(a&&l)"forced-logout"!==this.activeSection&&this._showForcedLogout(a);else if(a)"logout"!==this.activeSection&&this._showLogout(a);else if(!0===c)"picker"!==this.activeSection&&this._showPicker();else if(c){if(!this._sessionViewModel||this._sessionViewModel.id!==c)if(this._pendingClient&&this._pendingClient.sessionId===c){const e=this._pendingClient;this._pendingClient=null,this._showSession(e)}else this._pendingClient&&(this._pendingClient.dispose(),this._pendingClient=null),this._showSessionLoader(c)}else if(d)this.urlRouter.normalizeUrl(),"login"!==this.activeSection&&this._showLogin({loginToken:d});else if(h)this.urlRouter.normalizeUrl(),"login"!==this.activeSection&&this._showLogin({oidc:h});else try{if(!e||!this.urlRouter.tryRestoreLastUrl()){const e=await this.platform.sessionInfoStorage.getAll();0===e.length?this.navigation.push("login"):1===e.length?this.navigation.push("session",e[0].id):this.navigation.push("session")}}catch(e){this._setSection((()=>this._error=e))}}async _showPicker(){this._setSection((()=>{this._sessionPickerViewModel=new SessionPickerViewModel(this.childOptions())}));try{await this._sessionPickerViewModel.load()}catch(e){this._setSection((()=>this._error=e))}}_showLogin({loginToken:e,oidc:t}={}){this._setSection((()=>{this._loginViewModel=new LoginViewModel(this.childOptions({defaultHomeserver:this.platform.config.defaultHomeServer,ready:e=>{this._pendingClient=e,this.navigation.push("session",e.sessionId)},loginToken:e,oidc:t}))}))}_showLogout(e){this._setSection((()=>{this._logoutViewModel=new LogoutViewModel(this.childOptions({sessionId:e}))}))}_showForcedLogout(e){this._setSection((()=>{this._forcedLogoutViewModel=new ForcedLogoutViewModel(this.childOptions({sessionId:e}))}))}_showSession(e){this._setSection((()=>{this._sessionViewModel=new SessionViewModel(this.childOptions({client:e})),this._sessionViewModel.start()}))}_showSessionLoader(e){const t=new Client(this.platform,this.features);t.startWithExistingSession(e),this._setSection((()=>{this._sessionLoadViewModel=new SessionLoadViewModel(this.childOptions({client:t,ready:e=>this._showSession(e)})),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}}exports.AnnouncementView=AnnouncementView,exports.AsyncMappedList=AsyncMappedList,exports.AttachmentUpload=AttachmentUpload,exports.AvatarView=AvatarView,exports.BaseMediaView=BaseMediaView,exports.BaseMessageView=BaseMessageView,exports.BaseObservableValue=BaseObservableValue$1,exports.BlobHandle=BlobHandle,exports.CallIntent=CallIntent,exports.Client=Client,exports.ComposerViewModel=ComposerViewModel,exports.ConcatList=ConcatList,exports.ConsoleReporter=ConsoleReporter,exports.Disposables=Disposables,exports.EncryptedEventTile=EncryptedEventTile,exports.EncryptionEnabledTile=EncryptionEnabledTile,exports.EventEmitter=EventEmitter,exports.FeatureFlag=FeatureFlag,exports.FeatureSet=FeatureSet,exports.FileTile=FileTile,exports.FileView=FileView,exports.GapTile=GapTile,exports.GapView=GapView,exports.IDBLogPersister=IDBLogPersister,exports.ImageTile=ImageTile,exports.ImageView=ImageView,exports.LoadStatus=LoadStatus,exports.LoadingView=LoadingView,exports.LocalMedia=LocalMedia,exports.LocationTile=LocationTile,exports.LocationView=LocationView,exports.Logger=Logger,exports.LoginFailure=LoginFailure,exports.MappedList=MappedList,exports.MessageComposer=MessageComposer,exports.MissingAttachmentTile=MissingAttachmentTile,exports.MissingAttachmentView=MissingAttachmentView,exports.Navigation=Navigation,exports.OIDCLoginMethod=OIDCLoginMethod,exports.ObservableArray=ObservableArray,exports.ObservableMap=ObservableMap,exports.ObservableValue=ObservableValue$1,exports.OidcApi=OidcApi,exports.Platform=Platform,exports.PowerLevels=PowerLevels,exports.ReactionsView=ReactionsView,exports.RedactedTile=RedactedTile,exports.RedactedView=RedactedView,exports.ReplyPreviewView=ReplyPreviewView,exports.RetainedObservableValue=RetainedObservableValue,exports.RoomMemberTile=RoomMemberTile,exports.RoomNameTile=RoomNameTile,exports.RoomStatus=RoomStatus,exports.RoomType=RoomType,exports.RoomView=RoomView,exports.RoomViewModel=RoomViewModel,exports.RoomVisibility=RoomVisibility,exports.RootView=RootView,exports.RootViewModel=RootViewModel,exports.SessionView=SessionView,exports.SessionViewModel=SessionViewModel,exports.SimpleTile=SimpleTile,exports.SortedArray=SortedArray,exports.TemplateView=TemplateView,exports.TextMessageView=TextMessageView,exports.TextTile=TextTile,exports.TimelineView=TimelineView,exports.TimelineViewModel=TimelineViewModel,exports.VideoTile=VideoTile,exports.VideoView=VideoView,exports.ViewModel=ViewModel,exports.createNavigation=createNavigation,exports.createRouter=createRouter,exports.makeTxnId=makeTxnId,exports.submitLogsToRageshakeServer=submitLogsToRageshakeServer,exports.tileClassForEntry=tileClassForEntry,exports.viewClassForTile=viewClassForTile;
//# sourceMappingURL=/sm/db30a689bce63dfa92e4adb21475d9292b37771044e74d3a303f09c5aa7dae20.map