{"version":3,"file":"405.7373165804a1f4a12f8a.chunk.js","mappings":"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","sources":["webpack://tweb/./src/components/ripple.ts","webpack://tweb/./src/config/debug.ts","webpack://tweb/./src/config/modes.ts","webpack://tweb/./src/helpers/cancellablePromise.ts","webpack://tweb/./src/helpers/dom/findUpAsChild.ts","webpack://tweb/./src/helpers/dom/isInDOM.ts","webpack://tweb/./src/helpers/eventListenerBase.ts","webpack://tweb/./src/helpers/noop.ts","webpack://tweb/./src/helpers/schedulers.ts","webpack://tweb/./src/helpers/sequentialDom.ts","webpack://tweb/./src/lib/mtproto/mtproto_config.ts","webpack://tweb/./src/lib/rootScope.ts"],"sourcesContent":["/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport sequentialDom from \"../helpers/sequentialDom\";\r\nimport {IS_TOUCH_SUPPORTED} from \"../environment/touchSupport\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\n\r\nlet rippleClickId = 0;\r\nexport function ripple(\r\n elem: HTMLElement, \r\n callback: (id: number) => Promise = () => Promise.resolve(), \r\n onEnd: (id: number) => void = null, \r\n prepend = false,\r\n attachListenerTo = elem\r\n) {\r\n //return;\r\n if(elem.querySelector('.c-ripple')) return;\r\n elem.classList.add('rp');\r\n \r\n let r = document.createElement('div');\r\n r.classList.add('c-ripple');\r\n\r\n const isSquare = elem.classList.contains('rp-square');\r\n if(isSquare) {\r\n r.classList.add('is-square');\r\n }\r\n\r\n elem[prepend ? 'prepend' : 'append'](r);\r\n\r\n let handler: () => void;\r\n //let animationEndPromise: Promise;\r\n const drawRipple = (clientX: number, clientY: number) => {\r\n const startTime = Date.now();\r\n const elem = document.createElement('div');\r\n\r\n const clickId = rippleClickId++;\r\n \r\n //console.log('ripple drawRipple');\r\n \r\n const duration = +window.getComputedStyle(r).getPropertyValue('--ripple-duration').replace('s', '') * 1000;\r\n //console.log('ripple duration', duration);\r\n\r\n handler = () => {\r\n //handler = () => animationEndPromise.then((duration) => {\r\n //console.log('ripple animation was:', duration);\r\n\r\n //const duration = isSquare || mediaSizes.isMobile ? 200 : 700;\r\n //return;\r\n let elapsedTime = Date.now() - startTime;\r\n const cb = () => {\r\n //console.log('ripple elapsedTime total pre-remove:', Date.now() - startTime);\r\n sequentialDom.mutate(() => {\r\n elem.remove();\r\n });\r\n \r\n if(onEnd) onEnd(clickId);\r\n };\r\n if(elapsedTime < duration) {\r\n let delay = Math.max(duration - elapsedTime, duration / 2);\r\n setTimeout(() => elem.classList.add('hiding'), Math.max(delay - duration / 2, 0));\r\n\r\n setTimeout(cb, delay);\r\n } else {\r\n elem.classList.add('hiding');\r\n setTimeout(cb, duration / 2);\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('contextmenu', handler);\r\n }\r\n\r\n handler = null;\r\n touchStartFired = false;\r\n };\r\n //});\r\n\r\n callback && callback(clickId);\r\n\r\n /* callback().then((bad) => {\r\n if(bad) {\r\n span.remove();\r\n return;\r\n } */\r\n \r\n //console.log('ripple after promise', Date.now() - startTime);\r\n //console.log('ripple tooSlow:', tooSlow);\r\n /* if(tooSlow) {\r\n span.remove();\r\n return;\r\n } */\r\n\r\n window.requestAnimationFrame(() => {\r\n const rect = r.getBoundingClientRect();\r\n elem.classList.add('c-ripple__circle');\r\n\r\n const clickX = clientX - rect.left;\r\n const clickY = clientY - rect.top;\r\n\r\n const radius = Math.sqrt((Math.abs(clickY - rect.height / 2) + rect.height / 2) ** 2 + (Math.abs(clickX - rect.width / 2) + rect.width / 2) ** 2);\r\n const size = radius;\r\n\r\n // center of circle\r\n const x = clickX - size / 2;\r\n const y = clickY - size / 2;\r\n\r\n //console.log('ripple click', offsetFromCenter, size, clickX, clickY);\r\n\r\n elem.style.width = elem.style.height = size + 'px';\r\n elem.style.left = x + 'px';\r\n elem.style.top = y + 'px';\r\n\r\n // нижний код выполняется с задержкой\r\n /* animationEndPromise = new Promise((resolve) => {\r\n span.addEventListener('animationend', () => {\r\n // 713 -> 700\r\n resolve(((Date.now() - startTime) / 100 | 0) * 100);\r\n }, {once: true});\r\n }); */\r\n \r\n // нижний код не всегда включает анимацию ПРИ КЛИКЕ НА ТАЧПАД БЕЗ ТАПТИК ЭНЖИНА\r\n /* span.style.display = 'none';\r\n r.append(span);\r\n duration = +window.getComputedStyle(span).getPropertyValue('animation-duration').replace('s', '') * 1000;\r\n span.style.display = ''; */\r\n\r\n r.append(elem);\r\n\r\n //r.classList.add('active');\r\n //handler();\r\n });\r\n //});\r\n };\r\n\r\n const isRippleUnneeded = (e: Event) => e.target !== elem && (\r\n ['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) \r\n || findUpClassName(e.target as HTMLElement, 'c-ripple') !== r\r\n ) && (\r\n attachListenerTo === elem \r\n || !findUpAsChild(e.target, attachListenerTo)\r\n );\r\n\r\n // TODO: rename this variable\r\n let touchStartFired = false;\r\n if(IS_TOUCH_SUPPORTED) {\r\n let touchEnd = () => {\r\n handler && handler();\r\n };\r\n \r\n attachListenerTo.addEventListener('touchstart', (e) => {\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n\r\n //console.log('ripple touchstart', e);\r\n if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {\r\n return;\r\n }\r\n \r\n //console.log('touchstart', e);\r\n touchStartFired = true;\r\n \r\n let {clientX, clientY} = e.touches[0];\r\n drawRipple(clientX, clientY);\r\n attachListenerTo.addEventListener('touchend', touchEnd, {once: true});\r\n \r\n window.addEventListener('touchmove', (e) => {\r\n e.cancelBubble = true;\r\n e.stopPropagation();\r\n touchEnd();\r\n attachListenerTo.removeEventListener('touchend', touchEnd);\r\n }, {once: true});\r\n }, {passive: true});\r\n } else {\r\n attachListenerTo.addEventListener('mousedown', (e) => {\r\n if(![0, 2].includes(e.button)) { // only left and right buttons\r\n return;\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n //console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);\r\n\r\n if(attachListenerTo.dataset.ripple === '0' || isRippleUnneeded(e)) {\r\n return;\r\n } else if(touchStartFired) {\r\n touchStartFired = false;\r\n return;\r\n }\r\n \r\n let {clientX, clientY} = e;\r\n drawRipple(clientX, clientY);\r\n window.addEventListener('mouseup', handler, {once: true, passive: true});\r\n window.addEventListener('contextmenu', handler, {once: true, passive: true});\r\n }, {passive: true});\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport Modes from \"./modes\";\r\n\r\nexport const DEBUG = process.env.NODE_ENV !== 'production' || Modes.debug;\r\nconst ctx: any = typeof(window) !== 'undefined' ? window : self;\r\nexport const MOUNT_CLASS_TO: any = DEBUG || true/* && false */ ? ctx : {};\r\nexport default DEBUG;\r\n\r\n//let m = DEBUG;\r\n/* if(!DEBUG) {\r\n ctx.sandpitTurtle = () => {\r\n //if(!m) {\r\n for(let i in MOUNT_CLASS_TO) {\r\n ctx[i] = MOUNT_CLASS_TO[i];\r\n }\r\n //m = true;\r\n //}\r\n \r\n //DEBUG = !DEBUG;\r\n };\r\n} */\r\n\r\n/* export const superDebug = (object: any, key: string) => {\r\n var d = object[key];\r\n var beforeStr = '', afterStr = '';\r\n for(var r of d) {\r\n beforeStr += r.before.hex + '\\n';\r\n afterStr += r.after.hex + '\\n';\r\n }\r\n\r\n beforeStr = beforeStr.trim();\r\n afterStr = afterStr.trim();\r\n //var beforeStr = d.map(r => r.before.hex).join('\\n');\r\n //var afterStr = d.map(r => r.after.hex).join('\\n');\r\n\r\n var dada = (name: string, str: string) => {\r\n var a = document.createElement('a');\r\n a.target = '_blank';\r\n a.download = name + '.txt';\r\n a.href = URL.createObjectURL(new Blob([str], {\r\n type: 'text/plain'\r\n }));\r\n document.body.append(a);\r\n a.click();\r\n };\r\n\r\n dada(key + '_' + 'before', beforeStr);\r\n dada(key + '_' + 'after', afterStr);\r\n}\r\n\r\nMOUNT_CLASS_TO.superDebug = superDebug; */\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n * \n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov \n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport type { TransportType } from \"../lib/mtproto/dcConfigurator\";\n\nconst Modes = {\n test: location.search.indexOf('test=1') > 0/* || true */,\n debug: location.search.indexOf('debug=1') > 0,\n http: false,\n ssl: true, // location.search.indexOf('ssl=1') > 0 || location.protocol === 'https:' && location.search.indexOf('ssl=0') === -1,\n multipleConnections: true,\n asServiceWorker: false,\n transport: 'websocket' as TransportType\n};\n\n \nModes.http = location.search.indexOf('http=1') > 0;\n \n\n \n \n \n\nif(Modes.http) {\n Modes.transport = 'https';\n}\n\n \n \n \n\nexport default Modes;\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport noop from \"./noop\";\r\n\r\nexport interface CancellablePromise extends Promise {\r\n resolve?: (value: T) => void,\r\n reject?: (...args: any[]) => void,\r\n cancel?: () => void,\r\n\r\n notify?: (...args: any[]) => void,\r\n notifyAll?: (...args: any[]) => void,\r\n lastNotify?: any,\r\n listeners?: Array<(...args: any[]) => void>,\r\n addNotifyListener?: (callback: (...args: any[]) => void) => void,\r\n\r\n isFulfilled?: boolean,\r\n isRejected?: boolean\r\n}\r\n\r\nexport function deferredPromise() {\r\n let deferredHelper: any = {\r\n isFulfilled: false, \r\n isRejected: false,\r\n\r\n notify: () => {}, \r\n notifyAll: (...args: any[]) => {\r\n deferredHelper.lastNotify = args;\r\n deferredHelper.listeners.forEach((callback: any) => callback(...args));\r\n }, \r\n\r\n listeners: [],\r\n addNotifyListener: (callback: (...args: any[]) => void) => {\r\n if(deferredHelper.lastNotify) {\r\n callback(...deferredHelper.lastNotify);\r\n }\r\n\r\n deferredHelper.listeners.push(callback);\r\n }\r\n };\r\n\r\n let deferred: CancellablePromise = new Promise((resolve, reject) => {\r\n deferredHelper.resolve = (value: T) => {\r\n if(deferred.isFulfilled || deferred.isRejected) return;\r\n\r\n deferred.isFulfilled = true;\r\n resolve(value);\r\n };\r\n \r\n deferredHelper.reject = (...args: any[]) => {\r\n if(deferred.isRejected || deferred.isFulfilled) return;\r\n \r\n deferred.isRejected = true;\r\n reject(...args);\r\n };\r\n });\r\n\r\n // @ts-ignore\r\n /* deferred.then = (resolve: (value: T) => any, reject: (...args: any[]) => any) => {\r\n const n = deferredPromise>();\r\n \r\n }; */\r\n\r\n deferred.catch(noop).finally(() => {\r\n deferred.notify = deferred.notifyAll = deferred.lastNotify = null;\r\n deferred.listeners.length = 0;\r\n\r\n if(deferred.cancel) {\r\n deferred.cancel = () => {};\r\n }\r\n });\r\n\r\n Object.assign(deferred, deferredHelper);\r\n\r\n return deferred;\r\n}","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nexport default function findUpAsChild(el: any, parent: any) {\r\n if(el.parentElement === parent) return el;\r\n \r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.parentElement === parent) {\r\n return el;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov \r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\n/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {\r\n if(!element) {\r\n return false;\r\n }\r\n\r\n parentNode = parentNode || document.body;\r\n if(element === parentNode) {\r\n return true;\r\n }\r\n return isInDOM(element.parentNode as HTMLElement, parentNode);\r\n} */\r\nexport default function isInDOM(element: Element): boolean {\r\n return element?.isConnected;\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n//import { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport type { ArgumentTypes, SuperReturnType } from \"../types\";\r\n\r\n// class EventSystem {\r\n// wm: WeakMap>> = new WeakMap();\r\n\r\n// add(target: any, event: any, listener: any) {\r\n// let listeners = this.wm.get(target);\r\n// if (listeners === undefined) {\r\n// listeners = {};\r\n// }\r\n// let listenersForEvent = listeners[event];\r\n// if (listenersForEvent === undefined) {\r\n// listenersForEvent = new Set();\r\n// }\r\n// listenersForEvent.add(listener);\r\n// listeners[event] = listenersForEvent;\r\n// //target.addEventListener(event, listener);\r\n// this.wm.set(target, listeners);\r\n// };\r\n\r\n// remove(target: any, event: any, listener: any) {\r\n// let listeners = this.wm.get(target);\r\n// if (!listeners) return;\r\n// let listenersForEvent = listeners[event];\r\n// if (!listenersForEvent) return;\r\n// listenersForEvent.delete(listener);\r\n// };\r\n \r\n// /* fire(target, event) {\r\n// let listeners = this.wm.get(target);\r\n// if (!listeners) return;\r\n// let listenersForEvent = listeners[event];\r\n// if (!listenersForEvent) return;\r\n// for (let handler of handlers) {\r\n// setTimeout(handler, 0, event, target); // we use a setTimeout here because we want event triggering to be asynchronous. \r\n// }\r\n// }; */\r\n// }\r\n\r\n// console.log = () => {};\r\n\r\n// const e = new EventSystem();\r\n// MOUNT_CLASS_TO.e = e;\r\n\r\nexport type EventListenerListeners = Record;\r\n// export type EventListenerListeners = Record any>;\r\n// export type EventListenerListeners = {[name in string]: Function};\r\n\r\n/**\r\n * Better not to remove listeners during setting\r\n * Should add listener callback only once\r\n */\r\n\r\n// type EventLitenerCallback = (data: T) => \r\n// export default class EventListenerBase {\r\nexport default class EventListenerBase {\r\n protected listeners: Partial<{\r\n [k in keyof Listeners]: Array<{callback: Listeners[k], options: boolean | AddEventListenerOptions}>\r\n }>;\r\n protected listenerResults: Partial<{\r\n [k in keyof Listeners]: ArgumentTypes\r\n }>;\r\n\r\n private reuseResults: boolean;\r\n\r\n constructor(reuseResults?: boolean) {\r\n this._constructor(reuseResults);\r\n }\r\n\r\n public _constructor(reuseResults = false): any {\r\n this.reuseResults = reuseResults;\r\n this.listeners = {};\r\n this.listenerResults = {};\r\n }\r\n\r\n public addEventListener(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {\r\n (this.listeners[name] ?? (this.listeners[name] = [])).push({callback, options}); // ! add before because if you don't, you won't be able to delete it from callback\r\n\r\n if(this.listenerResults.hasOwnProperty(name)) {\r\n callback(...this.listenerResults[name]);\r\n \r\n if((options as AddEventListenerOptions)?.once) {\r\n this.listeners[name].pop();\r\n return;\r\n }\r\n }\r\n \r\n //e.add(this, name, {callback, once});\r\n }\r\n\r\n public addMultipleEventsListeners(obj: {\r\n [name in keyof Listeners]?: Listeners[name]\r\n }) {\r\n for(const i in obj) {\r\n this.addEventListener(i, obj[i]);\r\n }\r\n }\r\n\r\n public removeEventListener(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {\r\n if(this.listeners[name]) {\r\n this.listeners[name].findAndSplice(l => l.callback === callback);\r\n }\r\n //e.remove(this, name, callback);\r\n }\r\n\r\n // * must be protected, but who cares\r\n private _dispatchEvent(name: T, collectResults: boolean, ...args: ArgumentTypes) {\r\n if(this.reuseResults) {\r\n this.listenerResults[name] = args;\r\n }\r\n\r\n const arr: Array> = collectResults && [];\r\n\r\n const listeners = this.listeners[name];\r\n if(listeners) {\r\n // ! this one will guarantee execution even if delete another listener during setting\r\n const left = listeners.slice();\r\n left.forEach((listener) => {\r\n const index = listeners.findIndex((l) => l.callback === listener.callback);\r\n if(index === -1) {\r\n return;\r\n }\r\n\r\n let result: any;\r\n try {\r\n result = listener.callback(...args);\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n\r\n if(arr) {\r\n arr.push(result);\r\n }\r\n\r\n if((listener.options as AddEventListenerOptions)?.once) {\r\n this.removeEventListener(name, listener.callback);\r\n }\r\n });\r\n }\r\n\r\n return arr;\r\n }\r\n\r\n public dispatchResultableEvent(name: T, ...args: ArgumentTypes) {\r\n return this._dispatchEvent(name, true, ...args);\r\n }\r\n\r\n // * must be protected, but who cares\r\n public dispatchEvent(name: T, ...args: ArgumentTypes) {\r\n // @ts-ignore\r\n this._dispatchEvent(name, false, ...args);\r\n }\r\n\r\n public cleanup() {\r\n this.listeners = {}; \r\n this.listenerResults = {};\r\n }\r\n}\r\n","export default function noop() {}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n// * Jolly Cobra's schedulers\r\nimport { NoneToVoidFunction } from \"../types\";\r\n\r\n/*\r\nexport function throttleWithTickEnd(fn: F) {\r\n return throttleWith(onTickEnd, fn);\r\n}\r\n\r\nexport function throttleWithNow(fn: F) {\r\n return throttleWith(runNow, fn);\r\n}\r\n\r\nexport function onTickEnd(cb: NoneToVoidFunction) {\r\n Promise.resolve().then(cb);\r\n}\r\n\r\nfunction runNow(fn: NoneToVoidFunction) {\r\n fn();\r\n} */\r\n\r\nlet fastRafCallbacks: NoneToVoidFunction[] | undefined;\r\nexport function fastRaf(callback: NoneToVoidFunction) {\r\n if(!fastRafCallbacks) {\r\n fastRafCallbacks = [callback];\r\n\r\n requestAnimationFrame(() => {\r\n const currentCallbacks = fastRafCallbacks!;\r\n fastRafCallbacks = undefined;\r\n currentCallbacks.forEach((cb) => cb());\r\n });\r\n } else {\r\n fastRafCallbacks.push(callback);\r\n }\r\n}\r\n\r\nlet fastRafConventionalCallbacks: NoneToVoidFunction[] | undefined, processing = false;\r\nexport function fastRafConventional(callback: NoneToVoidFunction) {\r\n if(!fastRafConventionalCallbacks) {\r\n fastRafConventionalCallbacks = [callback];\r\n\r\n requestAnimationFrame(() => {\r\n processing = true;\r\n for(let i = 0; i < fastRafConventionalCallbacks.length; ++i) {\r\n fastRafConventionalCallbacks[i]();\r\n }\r\n\r\n fastRafConventionalCallbacks = undefined;\r\n processing = false;\r\n });\r\n } else if(processing) {\r\n callback();\r\n } else {\r\n fastRafConventionalCallbacks.push(callback);\r\n }\r\n}\r\n\r\nlet rafPromise: Promise;\r\nexport function fastRafPromise() {\r\n if(rafPromise) return rafPromise;\r\n\r\n rafPromise = new Promise(requestAnimationFrame);\r\n rafPromise.then(() => {\r\n rafPromise = undefined;\r\n });\r\n\r\n return rafPromise;\r\n}\r\n\r\nexport function doubleRaf() {\r\n return new Promise((resolve) => {\r\n fastRaf(() => {\r\n fastRaf(resolve);\r\n });\r\n });\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { fastRaf } from \"./schedulers\";\r\nimport { CancellablePromise, deferredPromise } from \"./cancellablePromise\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"./dom/isInDOM\";\r\n\r\nclass SequentialDom {\r\n private promises: Partial<{\r\n read: CancellablePromise,\r\n write: CancellablePromise\r\n }> = {};\r\n private raf = fastRaf.bind(null);\r\n private scheduled = false;\r\n\r\n private do(kind: keyof SequentialDom['promises'], callback?: VoidFunction) {\r\n let promise = this.promises[kind];\r\n if(!promise) {\r\n this.scheduleFlush();\r\n promise = this.promises[kind] = deferredPromise();\r\n }\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n \r\n return promise;\r\n }\r\n\r\n public measure(callback?: VoidFunction) {\r\n return this.do('read', callback);\r\n }\r\n\r\n public mutate(callback?: VoidFunction) {\r\n return this.do('write', callback);\r\n }\r\n\r\n /**\r\n * Will fire instantly if element is not connected\r\n * @param element \r\n * @param callback \r\n */\r\n public mutateElement(element: HTMLElement, callback?: VoidFunction) {\r\n const isConnected = isInDOM(element);\r\n const promise = isConnected ? this.mutate() : Promise.resolve();\r\n\r\n if(callback !== undefined) {\r\n if(isConnected) {\r\n callback();\r\n } else {\r\n promise.then(() => callback());\r\n }\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n private scheduleFlush() {\r\n if(!this.scheduled) {\r\n this.scheduled = true;\r\n\r\n this.raf(() => {\r\n this.promises.read && this.promises.read.resolve();\r\n this.promises.write && this.promises.write.resolve();\r\n\r\n this.scheduled = false;\r\n this.promises = {};\r\n });\r\n }\r\n }\r\n}\r\n\r\nconst sequentialDom = new SequentialDom();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.sequentialDom = sequentialDom);\r\nexport default sequentialDom;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n\r\n/**\r\n * Legacy Webogram's format, don't change dcID to camelCase. date is timestamp\r\n */\r\nexport type UserAuth = {dcID: number | string, date: number, id: PeerId};\r\n\r\nexport const NULL_PEER_ID: PeerId = 0;\r\nexport const REPLIES_PEER_ID: PeerId = 1271266957;\r\nexport const SERVICE_PEER_ID: PeerId = 777000;\r\nexport const MUTE_UNTIL = 0x7FFFFFFF;\r\nexport const BOT_START_PARAM = '';\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type { Message, StickerSet, Update, NotifyPeer, PeerNotifySettings, ConstructorDeclMap, Config, PollResults, Poll, WebPage, GroupCall, GroupCallParticipant, PhoneCall, MethodDeclMap, MessageReactions, ReactionCount } from \"../layer\";\nimport type { MyDocument } from \"./appManagers/appDocsManager\";\nimport type { AppMessagesManager, Dialog, MessagesStorage, MyMessage } from \"./appManagers/appMessagesManager\";\nimport type { MyDialogFilter } from \"./storages/filters\";\nimport type { Folder } from \"./storages/dialogs\";\nimport type { UserTyping } from \"./appManagers/appProfileManager\";\nimport type { State, Theme } from \"./appManagers/appStateManager\";\nimport type { MyDraftMessage } from \"./appManagers/appDraftsManager\";\nimport type { PushSubscriptionNotify } from \"./mtproto/webPushApiManager\";\nimport type { PushNotificationObject } from \"./serviceWorker/push\";\nimport type { ConnectionStatusChange } from \"./mtproto/connectionStatus\";\nimport type { GroupCallId } from \"./appManagers/appGroupCallsManager\";\nimport type GroupCallInstance from \"./calls/groupCallInstance\";\nimport type CallInstance from \"./calls/callInstance\";\nimport type { StreamAmplitude } from \"./calls/streamManager\";\nimport type Chat from \"../components/chat/chat\";\nimport { NULL_PEER_ID, UserAuth } from \"./mtproto/mtproto_config\";\nimport EventListenerBase from \"../helpers/eventListenerBase\";\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\nimport { MTAppConfig } from \"./mtproto/appConfig\";\n\nexport type BroadcastEvents = {\n 'chat_full_update': ChatId,\n 'chat_update': ChatId,\n\n 'channel_update': ChatId,\n \n 'user_update': UserId,\n 'user_auth': UserAuth,\n 'user_full_update': UserId,\n\n 'chat_changing': {from: Chat, to: Chat},\n\n 'peer_changed': PeerId,\n 'peer_changing': Chat,\n 'peer_pinned_messages': {peerId: PeerId, mids?: number[], pinned?: boolean, unpinAll?: true},\n 'peer_pinned_hidden': {peerId: PeerId, maxId: number},\n 'peer_typings': {peerId: PeerId, typings: UserTyping[]},\n 'peer_block': {peerId: PeerId, blocked: boolean},\n 'peer_title_edit': PeerId,\n 'peer_bio_edit': PeerId,\n 'peer_deleted': PeerId, // left chat, deleted user dialog, left channel\n 'peer_full_update': PeerId,\n\n 'filter_delete': MyDialogFilter,\n 'filter_update': MyDialogFilter,\n 'filter_new': MyDialogFilter,\n 'filter_order': number[],\n\n 'folder_unread': Folder,\n \n 'dialog_draft': {peerId: PeerId, dialog: Dialog, drop: boolean, draft: MyDraftMessage | undefined, index: number},\n 'dialog_unread': {peerId: PeerId},\n 'dialog_flush': {peerId: PeerId},\n 'dialog_drop': {peerId: PeerId, dialog?: Dialog},\n 'dialog_migrate': {migrateFrom: PeerId, migrateTo: PeerId},\n //'dialog_top': Dialog,\n 'dialog_notify_settings': Dialog,\n // 'dialog_order': {dialog: Dialog, pos: number},\n 'dialogs_multiupdate': {[peerId: PeerId]: Dialog},\n \n 'history_append': {storage: MessagesStorage, peerId: PeerId, mid: number},\n 'history_update': {storage: MessagesStorage, peerId: PeerId, mid: number},\n 'history_reply_markup': {peerId: PeerId},\n 'history_multiappend': AppMessagesManager['newMessagesToHandle'],\n 'history_delete': {peerId: PeerId, msgs: Set},\n 'history_forbidden': PeerId,\n 'history_reload': PeerId,\n 'history_focus': {peerId: PeerId, threadId?: number, mid?: number, startParam?: string},\n //'history_request': void,\n \n 'message_edit': {storage: MessagesStorage, peerId: PeerId, mid: number},\n 'message_views': {peerId: PeerId, mid: number, views: number},\n 'message_sent': {storage: MessagesStorage, tempId: number, tempMessage: any, mid: number, message: MyMessage},\n 'message_reactions': {message: Message.message, changedResults: ReactionCount[]},\n 'messages_pending': void,\n 'messages_read': void,\n 'messages_downloaded': {peerId: PeerId, mids: number[]},\n 'messages_media_read': {peerId: PeerId, mids: number[]},\n\n 'replies_updated': Message.message,\n\n 'scheduled_new': {peerId: PeerId, mid: number},\n 'scheduled_delete': {peerId: PeerId, mids: number[]},\n\n 'album_edit': {peerId: PeerId, groupId: string, deletedMids: number[]},\n\n 'stickers_installed': StickerSet.stickerSet,\n 'stickers_deleted': StickerSet.stickerSet,\n\n 'media_play': {doc: MyDocument, message: Message.message, media: HTMLMediaElement},\n 'media_pause': void,\n 'media_playback_params': {volume: number, muted: boolean, playbackRate: number},\n 'media_stop': void,\n \n 'state_cleared': void,\n 'state_synchronized': ChatId | void,\n 'state_synchronizing': ChatId | void,\n \n 'contacts_update': UserId,\n 'avatar_update': PeerId,\n 'poll_update': {poll: Poll, results: PollResults},\n 'invalidate_participants': ChatId,\n //'channel_settings': {channelId: number},\n 'webpage_updated': {id: WebPage.webPage['id'], msgs: {peerId: PeerId, mid: number, isScheduled: boolean}[]},\n\n 'connection_status_change': ConnectionStatusChange,\n 'settings_updated': {key: string, value: any},\n 'draft_updated': {peerId: PeerId, threadId: number, draft: MyDraftMessage | undefined, force?: boolean},\n \n 'event-heavy-animation-start': void,\n 'event-heavy-animation-end': void,\n \n 'im_mount': void,\n 'im_tab_change': number,\n \n 'idle': boolean,\n \n 'overlay_toggle': boolean,\n \n 'background_change': void,\n \n 'privacy_update': Update.updatePrivacy,\n \n 'notify_settings': Update.updateNotifySettings,\n 'notify_peer_type_settings': {key: Exclude, settings: PeerNotifySettings},\n \n 'language_change': string,\n \n 'theme_change': void,\n \n 'instance_activated': void,\n 'instance_deactivated': void,\n \n 'push_notification_click': PushNotificationObject,\n 'push_init': PushSubscriptionNotify,\n 'push_subscribe': PushSubscriptionNotify,\n 'push_unsubscribe': PushSubscriptionNotify,\n \n 'emoji_recent': string,\n \n 'download_start': DocId,\n 'download_progress': any,\n 'document_downloaded': MyDocument,\n\n 'context_menu_toggle': boolean,\n 'choosing_sticker': boolean\n\n 'group_call_instance': GroupCallInstance,\n 'group_call_update': GroupCall,\n 'group_call_amplitude': {amplitudes: StreamAmplitude[], type: 'all' | 'input'},\n 'group_call_participant': {groupCallId: GroupCallId, participant: GroupCallParticipant},\n // 'group_call_video_track_added': {instance: GroupCallInstance}\n\n 'call_instance': {hasCurrent: boolean, instance: CallInstance},\n 'call_accepting': CallInstance, // это костыль. используется при параллельном вызове, чтобы заменить звонок в topbarCall\n\n 'quick_reaction': string,\n\n 'missed_reactions_element': {message: Message.message, changedResults: ReactionCount[]}\n};\n\nexport class RootScope extends EventListenerBase<{\n [name in Update['_']]: (update: ConstructorDeclMap[name]) => void\n} & {\n [name in keyof BroadcastEvents]: (e: BroadcastEvents[name]) => void\n}> {\n public overlaysActive = 0;\n public myId: PeerId;\n public idle = {\n isIDLE: true,\n deactivated: false,\n focusPromise: Promise.resolve(),\n focusResolve: () => {}\n };\n public connectionStatus: {[name: string]: ConnectionStatusChange} = {};\n public settings: State['settings'];\n public peerId: PeerId;\n public filterId = 0;\n public systemTheme: Theme['name'];\n public config: Partial = {\n forwarded_count_max: 100,\n edit_time_limit: 86400 * 2,\n pinned_dialogs_count_max: 5,\n pinned_infolder_count_max: 100,\n message_length_max: 4096,\n caption_length_max: 1024,\n };\n public appConfig: MTAppConfig;\n\n public themeColor: string;\n private _themeColorElem: Element;\n\n constructor() {\n super();\n\n this.addEventListener('peer_changed', (peerId) => {\n this.peerId = peerId;\n document.body.classList.toggle('has-chat', !!peerId);\n });\n\n this.addEventListener('user_auth', ({id}) => {\n // @ts-ignore\n this.myId = typeof(NULL_PEER_ID) === 'number' ? +id : '' + id;\n });\n\n this.addEventListener('connection_status_change', (status) => {\n this.connectionStatus[status.name] = status;\n });\n\n this.addEventListener('idle', (isIDLE) => {\n if(isIDLE) {\n this.idle.focusPromise = new Promise((resolve) => {\n this.idle.focusResolve = resolve;\n });\n } else {\n this.idle.focusResolve();\n }\n });\n }\n\n get themeColorElem() {\n if(this._themeColorElem !== undefined) {\n return this._themeColorElem;\n }\n\n return this._themeColorElem = document.head.querySelector('[name=\"theme-color\"]') as Element || null;\n }\n\n public setThemeColor(color = this.themeColor) {\n if(!color) {\n color = this.isNight() ? '#212121' : '#ffffff';\n }\n\n const themeColorElem = this.themeColorElem;\n if(themeColorElem) {\n themeColorElem.setAttribute('content', color);\n }\n }\n\n public setThemeListener() {\n try {\n const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const checkDarkMode = () => {\n //const theme = this.getTheme();\n this.systemTheme = darkModeMediaQuery.matches ? 'night' : 'day';\n //const newTheme = this.getTheme();\n\n if(this.myId) {\n this.dispatchEvent('theme_change');\n } else {\n this.setTheme();\n }\n };\n\n if('addEventListener' in darkModeMediaQuery) {\n darkModeMediaQuery.addEventListener('change', checkDarkMode);\n } else if('addListener' in darkModeMediaQuery) {\n (darkModeMediaQuery as any).addListener(checkDarkMode);\n }\n\n checkDarkMode();\n } catch(err) {\n\n }\n }\n\n public setTheme() {\n const isNight = this.isNight();\n const colorScheme = document.head.querySelector('[name=\"color-scheme\"]');\n if(colorScheme) {\n colorScheme.setAttribute('content', isNight ? 'dark' : 'light');\n }\n\n document.documentElement.classList.toggle('night', isNight);\n this.setThemeColor();\n }\n\n get isOverlayActive() {\n return this.overlaysActive > 0;\n }\n\n set isOverlayActive(value: boolean) {\n this.overlaysActive += value ? 1 : -1;\n this.dispatchEvent('overlay_toggle', this.isOverlayActive);\n }\n\n public isNight() {\n return this.getTheme().name === 'night';\n }\n\n public getTheme(name: Theme['name'] = this.settings.theme === 'system' ? this.systemTheme : this.settings.theme) {\n return this.settings.themes.find(t => t.name === name);\n }\n}\n\nconst rootScope = new RootScope();\nMOUNT_CLASS_TO.rootScope = rootScope;\nexport default rootScope;\n\n/* rootScope.addEventListener('album_edit', (e) => {\n \n});\n\nrootScope.addEventListener<'album_edit'>('album_edit', (e) => {\n \n}); */\n"],"names":["rippleClickId","ripple","elem","callback","Promise","resolve","onEnd","prepend","attachListenerTo","querySelector","classList","add","handler","r","document","createElement","contains","drawRipple","clientX","clientY","startTime","Date","now","clickId","duration","window","getComputedStyle","getPropertyValue","replace","elapsedTime","cb","remove","delay","Math","max","setTimeout","IS_TOUCH_SUPPORTED","removeEventListener","touchStartFired","requestAnimationFrame","rect","getBoundingClientRect","clickX","left","clickY","top","size","sqrt","abs","height","width","x","y","style","append","isRippleUnneeded","e","target","includes","tagName","touchEnd","addEventListener","touches","length","once","cancelBubble","stopPropagation","passive","button","dataset","DEBUG","MOUNT_CLASS_TO","self","Modes","test","location","search","indexOf","debug","http","ssl","multipleConnections","asServiceWorker","transport","deferredPromise","deferredHelper","isFulfilled","isRejected","notify","notifyAll","args","lastNotify","listeners","forEach","addNotifyListener","push","deferred","reject","value","catch","finally","cancel","Object","assign","findUpAsChild","el","parent","parentElement","isInDOM","element","isConnected","EventListenerBase","constructor","reuseResults","this","_constructor","listenerResults","name","options","hasOwnProperty","pop","addMultipleEventsListeners","obj","i","findAndSplice","l","_dispatchEvent","collectResults","arr","slice","listener","findIndex","result","err","console","error","dispatchResultableEvent","dispatchEvent","cleanup","noop","fastRafCallbacks","fastRaf","currentCallbacks","undefined","fastRafConventionalCallbacks","rafPromise","processing","fastRafConventional","fastRafPromise","then","doubleRaf","sequentialDom","promises","raf","scheduled","do","kind","promise","scheduleFlush","measure","mutate","mutateElement","read","write","NULL_PEER_ID","REPLIES_PEER_ID","SERVICE_PEER_ID","MUTE_UNTIL","BOT_START_PARAM","RootScope","super","overlaysActive","idle","isIDLE","deactivated","focusPromise","focusResolve","connectionStatus","filterId","config","forwarded_count_max","edit_time_limit","pinned_dialogs_count_max","pinned_infolder_count_max","message_length_max","caption_length_max","peerId","body","toggle","id","myId","status","themeColorElem","_themeColorElem","head","setThemeColor","color","themeColor","isNight","setAttribute","setThemeListener","darkModeMediaQuery","matchMedia","checkDarkMode","systemTheme","matches","setTheme","addListener","colorScheme","documentElement","isOverlayActive","getTheme","settings","theme","themes","find","t","rootScope"],"sourceRoot":""}