1 line
138 KiB
Plaintext
1 line
138 KiB
Plaintext
{"version":3,"sources":["webpack:///./src/helpers/animation.ts","webpack:///./src/components/horizontalMenu.ts","webpack:///./src/components/transition.ts","webpack:///./src/environment/canUseTransferables.ts","webpack:///./src/lib/rlottie/rlottiePlayer.ts","webpack:///./src/helpers/compareVersion.ts","webpack:///./src/lib/appManagers/appStateManager.ts","webpack:///./src/helpers/getTimeFormat.ts","webpack:///./src/helpers/array.ts","webpack:///./src/helpers/schedulers.ts","webpack:///./src/lib/rlottie/rlottie.worker.ts","webpack:///./src/lib/rlottie/queryableWorker.ts","webpack:///./src/lib/rlottie/lottieLoader.ts","webpack:///./src/helpers/number.ts","webpack:///./src/components/animationIntersector.ts","webpack:///./src/pages/pagesManager.ts","webpack:///./src/pages/page.ts","webpack:///./src/hooks/useHeavyAnimationCheck.ts","webpack:///./src/helpers/fastSmoothScroll.ts","webpack:///./src/helpers/dom/isInDOM.ts","webpack:///./src/helpers/dom/whichChild.ts","webpack:///./src/helpers/dom/findUpAsChild.ts"],"names":["instances","Map","cancelAnimationByKey","key","instance","get","getAnimationInstance","isCancelled","deferred","resolve","animateSingle","tick","set","then","delete","createAnimationInstance","animate","horizontalMenu","tabs","content","onClick","onTransitionEnd","transitionTime","scrollableX","selectTab","dataset","animation","proxy","Proxy","apply","target","that","args","id","undefined","el","querySelector","children","selectTarget","tabContent","canChange","scrollIntoViewNew","element","parentElement","position","forceDirection","Static","forceDuration","axis","settings","animationsEnabled","prevId","classList","contains","prev","tagName","toLowerCase","remove","useStripe","indicator","currentIndicator","shiftLeft","offsetLeft","scaleFactor","clientWidth","style","transform","requestAnimationFrame","add","firstElementChild","addEventListener","e","tab","slideNavigation","prevTabContent","toRight","width","getBoundingClientRect","elements","reverse","filter","offsetWidth","slideTabs","TransitionSlider","type","isHeavy","animationFunction","Transition","once","withAnimationListener","onTransitionEndCallbacks","animationDeferred","from","listenerName","onEndEvent","callback","removeEventListener","clear","overrideFrom","HTMLElement","to","timeout","clearTimeout","window","setTimeout","onTransitionEndCallback","toggle","_from","CAN_USE_TRANSFERABLES","navigator","userAgent","match","err","cache","this","name","frames","counter","height","color","toneIndex","Boolean","join","worker","options","super","reqId","paused","direction","speed","autoplay","loop","group","cachingDelta","i","hasOwnProperty","skipRatio","_loop","_autoplay","initFrame","inverseColor","skipFirstFrameRendering","needUpscale","skipDelta","pixelRatio","devicePixelRatio","Math","round","mediaSizes","isMobile","max","noCache","Infinity","canvas","document","createElement","context","getContext","clamped","Uint8ClampedArray","imageData","ImageData","cacheName","generateName","getCache","getCacheCounter","methodName","sendQuery","data","setMainLoop","clearPendingRAF","rafId","curFrame","minFrame","maxFrame","renderFirstFrame","pause","resetCurrentFrame","requestFrame","stop","play","lottieLoader","onDestroy","releaseCache","cleanup","frame","r","g","b","length","frameNo","applyColor","applyInversing","putImageData","console","error","dispatchEvent","has","frInterval","delta","Date","now","frThen","renderFrame2","renderFrame","onLap","fps","method","mainLoopForwards","mainLoopBackwards","bind","currentMethod","frameListener","listenerResults","enterFrame","playToFrame","setDirection","setSpeed","bounds","setMinMax","playToFrameOnFrameCallback","renderIfPaused","frameCount","diff","parentNode","appendChild","time","compareVersion","v1","v2","split","s1","s2","STATE_VERSION","version","BUILD","build","STATE_INIT","allDialogsLoaded","pinnedOrders","contactsList","updates","filters","maxSeenMsgId","stateCreatedTime","recentEmoji","topPeersCache","recentSearch","authState","_","hiddenPinnedMessages","messagesTextSize","distanceUnit","sendShortcut","autoDownload","photo","contacts","private","groups","channels","video","file","autoDownloadNew","file_size_max","pFlags","video_preload_large","audio_preload_next","photo_size_max","video_size_max","video_upload_maxbitrate","autoPlay","gifs","videos","stickers","suggest","emoji","big","themes","background","blur","slug","highlightningColor","intensity","theme","notifications","sound","timeFormat","toLocaleString","keepSigned","chatContextMenuHintWasShown","stateId","notifySettings","ALL_KEYS","Object","keys","REFRESH_KEYS","log","logger","neededPeers","singlePeerMap","storages","users","chats","dialogs","storagesResults","storage","stateStorage","loadSavedState","rootScope","requestPeerSingle","myId","loaded","Promise","storagesKeys","storagesPromises","map","getAll","promises","concat","sessionStorage","all","arr","state","value","pushToState","splice","auth","shift","shiftedWebKAuth","push","values","dcID","baseDcId","date","toPeerId","obj","forEach","idx","preserve","state_id","s","nightTheme","find","t","autoDownloadSettings","oldTypes","mediaType","peerTypeSettings","peerType","missingKey","result","migrated","newTheme","newVersion","timeEnd","catch","first","direct","setKeyValueToStorage","peerId","limit","Set","keepPeerSingle","keepPeerIdSingle","requestPeer","existsPeerId","size","appStateManager","accumulate","initialValue","reduce","acc","indexOfAndSplice","array","item","indexOf","spliced","findAndSpliceAll","verify","out","findIndex","forEachReverse","insertInDescendSortedArray","property","pos","sortProperty","next","len","unshift","filterUnique","fastRafCallbacks","fastRaf","currentCallbacks","cb","fastRafConventionalCallbacks","rafPromise","processing","fastRafConventional","fastRafPromise","doubleRaf","Worker_fn","Worker","onerror","terminate","onmessage","event","queryMethodListener","queryMethodArguments","message","postMessage","queryMethod","transfer","arg","ArrayBuffer","buffer","isWebAssemblySupported","loadPromise","reject","workersLimit","players","workers","curWorkerNum","Error","onPlayerLoaded","rlPlayer","debug","onLoad","warn","onFrame","onPlayerError","animationIntersector","getAnimations","checkAnimation","player","remain","params","loadAnimationFromURL","url","loadLottieWorkers","fetch","res","headers","blob","arrayBuffer","invokeCrypto","blobConstruct","newParams","assign","animationData","loadAnimationWorker","race","middleware","parseInt","container","initPlayer","addAnimation","loadFromData","numberThousandSplitter","x","joiner","parts","toString","replace","formatNumber","bytes","decimals","dm","floor","parseFloat","pow","toFixed","clamp","v","min","visible","byGroups","lockedGroups","onlyOnePlayableGroup","intersectionLockedGroups","videosLocked","observer","IntersectionObserver","entries","entry","p","isIntersecting","clearCache","overrideIdleGroups","doc","checkAnimations","override","found","HTMLVideoElement","src","load","unobserve","observe","blurred","destroy","animations","removeAnimation","idle","isIDLE","refreshGroup","pagesManager","pageId","pagesDiv","getElementById","scrollableDiv","page","onShown","isAuthPage","display","whichChild","pageEl","fastSmoothScroll","className","onFirstMount","onMount","installed","body","setPage","isAnimating","heavyAnimationPromise","promisesInQueue","dispatchHeavyAnimationEvent","promise","finally","perf","performance","_heavyAnimationPromise","isFulfilled","onHeavyAnimationEnd","interruptHeavyAnimation","getHeavyAnimationPromise","handleAnimationStart","handleAnimationEnd","listenerSetter","removeManual","FocusDirection","margin","maxDistance","scrollWithJs","getNormalSize","rectStartKey","rectEndKey","sizeKey","scrollSizeKey","scrollPositionKey","elementRect","containerRect","elementPosition","elementSize","containerSize","rect","scrollPosition","scrollSize","path","fallbackToElementStartWhenCentering","abs","scrollTop","remainingPath","absPath","duration","startAt","transition","shortTransition","longTransition","currentPath","isInDOM","isConnected","elem","previousElementSibling","findUpAsChild","parent"],"mappings":"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","file":"2.405f100e2516e3c485ee.chunk.js","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\n// * Jolly Cobra's animation.ts\r\n\r\nimport { fastRaf } from './schedulers';\r\nimport { CancellablePromise, deferredPromise } from './cancellablePromise';\r\n\r\ninterface AnimationInstance {\r\n isCancelled: boolean;\r\n deferred: CancellablePromise<void>\r\n}\r\n\r\ntype AnimationInstanceKey = any;\r\nconst instances: Map<AnimationInstanceKey, AnimationInstance> = new Map();\r\n\r\nexport function createAnimationInstance(key: AnimationInstanceKey) {\r\n cancelAnimationByKey(key);\r\n\r\n const instance: AnimationInstance = {\r\n isCancelled: false, \r\n deferred: deferredPromise<void>()\r\n };\r\n\r\n instances.set(key, instance);\r\n instance.deferred.then(() => {\r\n instances.delete(key);\r\n });\r\n\r\n return instance;\r\n}\r\n\r\nexport function getAnimationInstance(key: AnimationInstanceKey) {\r\n return instances.get(key);\r\n}\r\n\r\nexport function cancelAnimationByKey(key: AnimationInstanceKey) {\r\n const instance = getAnimationInstance(key);\r\n if(instance) {\r\n instance.isCancelled = true;\r\n instance.deferred.resolve();\r\n }\r\n}\r\n\r\nexport function animateSingle(tick: Function, key: AnimationInstanceKey, instance?: AnimationInstance) {\r\n if(!instance) {\r\n instance = createAnimationInstance(key);\r\n }\r\n\r\n fastRaf(() => {\r\n if(instance.isCancelled) {\r\n return;\r\n }\r\n \r\n if(tick()) {\r\n animateSingle(tick, key, instance);\r\n } else {\r\n instance.deferred.resolve();\r\n }\r\n });\r\n\r\n return instance.deferred;\r\n}\r\n\r\nexport function animate(tick: Function) {\r\n fastRaf(() => {\r\n if(tick()) {\r\n animate(tick);\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 { TransitionSlider } from \"./transition\";\r\nimport { ScrollableX } from \"./scrollable\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport { fastRaf } from \"../helpers/schedulers\";\r\nimport { FocusDirection } from \"../helpers/fastSmoothScroll\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\nimport whichChild from \"../helpers/dom/whichChild\";\r\n\r\nexport function horizontalMenu(\r\n tabs: HTMLElement, \r\n content: HTMLElement, \r\n onClick?: (id: number, tabContent: HTMLDivElement, animate: boolean) => void | boolean, \r\n onTransitionEnd?: () => void, \r\n transitionTime = 250, \r\n scrollableX?: ScrollableX\r\n) {\r\n const selectTab = TransitionSlider(content, tabs || content.dataset.animation === 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd);\r\n\r\n if(tabs) {\r\n const proxy = new Proxy(selectTab, {\r\n apply: (target, that, args) => {\r\n const id = +args[0];\r\n const animate = args[1] !== undefined ? args[1] : true;\r\n \r\n const el = (tabs.querySelector(`[data-tab=\"${id}\"]`) || tabs.children[id]) as HTMLElement;\r\n selectTarget(el, id, animate);\r\n }\r\n });\r\n\r\n const selectTarget = (target: HTMLElement, id: number, animate = true) => {\r\n const tabContent = content.children[id] as HTMLDivElement;\r\n\r\n if(onClick) {\r\n const canChange = onClick(id, tabContent, animate);\r\n if(canChange !== undefined && !canChange) {\r\n return;\r\n }\r\n }\r\n\r\n if(scrollableX) {\r\n scrollableX.scrollIntoViewNew({\r\n element: target.parentElement.children[id] as HTMLElement, \r\n position: 'center', \r\n forceDirection: animate ? undefined : FocusDirection.Static, \r\n forceDuration: transitionTime, \r\n axis: 'x'\r\n });\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n animate = false;\r\n }\r\n\r\n const prevId = selectTab.prevId();\r\n if(target.classList.contains('active') || id === prevId) {\r\n return false;\r\n }\r\n \r\n const prev = tabs.querySelector(tagName.toLowerCase() + '.active') as HTMLElement;\r\n\r\n fastRaf(() => {\r\n prev && prev.classList.remove('active');\r\n });\r\n \r\n // stripe from ZINCHUK\r\n if(useStripe && prevId !== -1 && animate) {\r\n fastRaf(() => {\r\n const indicator = target.querySelector('i')!;\r\n const currentIndicator = target.parentElement.children[prevId].querySelector('i')!;\r\n \r\n currentIndicator.classList.remove('animate');\r\n indicator.classList.remove('animate');\r\n \r\n // We move and resize our indicator so it repeats the position and size of the previous one.\r\n const shiftLeft = currentIndicator.parentElement.parentElement.offsetLeft - indicator.parentElement.parentElement.offsetLeft;\r\n const scaleFactor = currentIndicator.clientWidth / indicator.clientWidth;\r\n indicator.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;\r\n \r\n //console.log(`translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`);\r\n \r\n requestAnimationFrame(() => {\r\n // Now we remove the transform to let it animate to its own position and size.\r\n indicator.classList.add('animate');\r\n indicator.style.transform = 'none';\r\n });\r\n });\r\n }\r\n // stripe END\r\n\r\n fastRaf(() => {\r\n target.classList.add('active');\r\n });\r\n \r\n selectTab(id, animate);\r\n };\r\n\r\n const useStripe = !tabs.classList.contains('no-stripe');\r\n\r\n //const tagName = tabs.classList.contains('menu-horizontal-div') ? 'BUTTON' : 'LI';\r\n const tagName = tabs.firstElementChild.tagName;\r\n tabs.addEventListener('click', function(e) {\r\n let target = e.target as HTMLElement;\r\n \r\n target = findUpAsChild(target, tabs);\r\n \r\n //console.log('tabs click:', target);\r\n \r\n if(!target) return false;\r\n\r\n let id: number;\r\n if(target.dataset.tab) {\r\n id = +target.dataset.tab;\r\n if(id === -1) {\r\n return false;\r\n }\r\n } else {\r\n id = whichChild(target);\r\n }\r\n\r\n selectTarget(target, id);\r\n });\r\n\r\n return proxy;\r\n }\r\n \r\n return selectTab;\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 rootScope from \"../lib/rootScope\";\r\nimport { CancellablePromise, deferredPromise } from \"../helpers/cancellablePromise\";\r\nimport { dispatchHeavyAnimationEvent } from \"../hooks/useHeavyAnimationCheck\";\r\nimport whichChild from \"../helpers/dom/whichChild\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\n\r\nfunction slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {\r\n const width = prevTabContent.getBoundingClientRect().width;\r\n const elements = [tabContent, prevTabContent];\r\n if(toRight) elements.reverse();\r\n elements[0].style.filter = `brightness(80%)`;\r\n elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;\r\n elements[1].style.transform = `translate3d(${width}px, 0, 0)`;\r\n \r\n tabContent.classList.add('active');\r\n void tabContent.offsetWidth; // reflow\r\n\r\n tabContent.style.transform = '';\r\n tabContent.style.filter = '';\r\n\r\n return () => {\r\n prevTabContent.style.transform = prevTabContent.style.filter = '';\r\n };\r\n}\r\n\r\nfunction slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {\r\n // Jolly Cobra's // Workaround for scrollable content flickering during animation.\r\n // const scrollableContainer = findUpClassName(tabContent, 'scrollable-y');\r\n // if(scrollableContainer && scrollableContainer.style.overflowY !== 'hidden') {\r\n // // const scrollBarWidth = scrollableContainer.offsetWidth - scrollableContainer.clientWidth;\r\n // scrollableContainer.style.overflowY = 'hidden';\r\n // // scrollableContainer.style.paddingRight = `${scrollBarWidth}px`;\r\n // // this.container.classList.add('sliding');\r\n // }\r\n\r\n //window.requestAnimationFrame(() => {\r\n const width = prevTabContent.getBoundingClientRect().width;\r\n /* tabContent.style.setProperty('--width', width + 'px');\r\n prevTabContent.style.setProperty('--width', width + 'px');\r\n\r\n tabContent.classList.add('active'); */\r\n //void tabContent.offsetWidth; // reflow\r\n const elements = [tabContent, prevTabContent];\r\n if(toRight) elements.reverse();\r\n elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;\r\n elements[1].style.transform = `translate3d(${width}px, 0, 0)`;\r\n \r\n tabContent.classList.add('active');\r\n void tabContent.offsetWidth; // reflow\r\n \r\n tabContent.style.transform = '';\r\n //});\r\n \r\n return () => {\r\n prevTabContent.style.transform = '';\r\n\r\n // if(scrollableContainer) {\r\n // // Jolly Cobra's // Workaround for scrollable content flickering during animation.\r\n // if(isSafari) { // ! safari doesn't respect sticky header, so it flicks when overflow is changing\r\n // scrollableContainer.style.display = 'none';\r\n // }\r\n\r\n // scrollableContainer.style.overflowY = '';\r\n\r\n // if(isSafari) {\r\n // void scrollableContainer.offsetLeft; // reflow\r\n // scrollableContainer.style.display = '';\r\n // }\r\n\r\n // // scrollableContainer.style.paddingRight = '0';\r\n // // this.container.classList.remove('sliding');\r\n // }\r\n };\r\n}\r\n\r\nexport const TransitionSlider = (\r\n content: HTMLElement, \r\n type: 'tabs' | 'navigation' | 'zoom-fade' | 'slide-fade' | 'none'/* | 'counter' */, \r\n transitionTime: number, \r\n onTransitionEnd?: (id: number) => void, \r\n isHeavy = true\r\n) => {\r\n let animationFunction: TransitionFunction = null;\r\n\r\n switch(type) {\r\n case 'tabs':\r\n animationFunction = slideTabs;\r\n break;\r\n case 'navigation':\r\n animationFunction = slideNavigation;\r\n break;\r\n /* default:\r\n break; */\r\n }\r\n\r\n content.dataset.animation = type;\r\n \r\n return Transition(content, animationFunction, transitionTime, onTransitionEnd, isHeavy);\r\n};\r\n\r\ntype TransitionFunction = (tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) => void | (() => void);\r\n\r\nconst Transition = (\r\n content: HTMLElement, \r\n animationFunction: TransitionFunction, \r\n transitionTime: number, \r\n onTransitionEnd?: (id: number) => void, \r\n isHeavy = true,\r\n once = false,\r\n withAnimationListener = true\r\n) => {\r\n const onTransitionEndCallbacks: Map<HTMLElement, Function> = new Map();\r\n let animationDeferred: CancellablePromise<void>;\r\n // let animationStarted = 0;\r\n let from: HTMLElement = null;\r\n\r\n if(withAnimationListener) {\r\n const listenerName = animationFunction ? 'transitionend' : 'animationend';\r\n\r\n const onEndEvent = (e: TransitionEvent | AnimationEvent) => {\r\n cancelEvent(e);\r\n \r\n if((e.target as HTMLElement).parentElement !== content) {\r\n return;\r\n }\r\n \r\n //console.log('Transition: transitionend', /* content, */ e, selectTab.prevId, performance.now() - animationStarted);\r\n \r\n const callback = onTransitionEndCallbacks.get(e.target as HTMLElement);\r\n if(callback) callback();\r\n \r\n if(e.target !== from) {\r\n return;\r\n }\r\n \r\n if(!animationDeferred && isHeavy) return;\r\n \r\n if(animationDeferred) {\r\n animationDeferred.resolve();\r\n animationDeferred = undefined;\r\n }\r\n \r\n if(onTransitionEnd) {\r\n onTransitionEnd(selectTab.prevId());\r\n }\r\n \r\n content.classList.remove('animating', 'backwards', 'disable-hover');\r\n \r\n if(once) {\r\n content.removeEventListener(listenerName, onEndEvent/* , {capture: false} */);\r\n from = animationDeferred = undefined;\r\n onTransitionEndCallbacks.clear();\r\n }\r\n };\r\n \r\n // TODO: check for transition type (transform, etc) using by animationFunction\r\n content.addEventListener(listenerName, onEndEvent/* , {passive: true, capture: false} */);\r\n }\r\n\r\n function selectTab(id: number | HTMLElement, animate = true, overrideFrom?: typeof from) {\r\n if(overrideFrom) {\r\n from = overrideFrom;\r\n }\r\n\r\n if(id instanceof HTMLElement) {\r\n id = whichChild(id);\r\n }\r\n \r\n const prevId = selectTab.prevId();\r\n if(id === prevId) return false;\r\n\r\n //console.log('selectTab id:', id);\r\n\r\n const to = content.children[id] as HTMLElement;\r\n\r\n if(!rootScope.settings.animationsEnabled || prevId === -1) {\r\n animate = false;\r\n }\r\n\r\n if(!withAnimationListener) {\r\n const timeout = content.dataset.timeout;\r\n if(timeout !== undefined) {\r\n clearTimeout(+timeout);\r\n }\r\n\r\n delete content.dataset.timeout;\r\n }\r\n\r\n if(!animate) {\r\n if(from) from.classList.remove('active', 'to', 'from');\r\n else if(to) { // fix instant opening back from closed slider (e.g. instant closening and opening right sidebar)\r\n const callback = onTransitionEndCallbacks.get(to);\r\n if(callback) {\r\n callback();\r\n }\r\n }\r\n\r\n if(to) {\r\n to.classList.remove('to', 'from');\r\n to.classList.add('active');\r\n }\r\n\r\n content.classList.remove('animating', 'backwards', 'disable-hover');\r\n\r\n from = to;\r\n\r\n if(onTransitionEnd) onTransitionEnd(id);\r\n return;\r\n }\r\n\r\n if(!withAnimationListener) {\r\n content.dataset.timeout = '' + window.setTimeout(() => {\r\n to.classList.remove('to');\r\n from && from.classList.remove('from');\r\n content.classList.remove('animating', 'backwards', 'disable-hover');\r\n delete content.dataset.timeout;\r\n }, transitionTime);\r\n }\r\n\r\n if(from) {\r\n from.classList.remove('to');\r\n from.classList.add('from');\r\n }\r\n\r\n content.classList.add('animating'/* , 'disable-hover' */);\r\n const toRight = prevId < id;\r\n content.classList.toggle('backwards', !toRight);\r\n\r\n let onTransitionEndCallback: ReturnType<TransitionFunction>;\r\n if(!to) {\r\n //prevTabContent.classList.remove('active');\r\n } else {\r\n if(animationFunction) {\r\n onTransitionEndCallback = animationFunction(to, from, toRight);\r\n } else {\r\n to.classList.add('active');\r\n }\r\n\r\n to.classList.remove('from');\r\n to.classList.add('to');\r\n }\r\n \r\n if(to) {\r\n onTransitionEndCallbacks.set(to, () => {\r\n to.classList.remove('to');\r\n onTransitionEndCallbacks.delete(to);\r\n });\r\n }\r\n\r\n if(from/* && false */) {\r\n const _from = from;\r\n const callback = () => {\r\n _from.classList.remove('active', 'from');\r\n\r\n if(onTransitionEndCallback) {\r\n onTransitionEndCallback();\r\n }\r\n\r\n onTransitionEndCallbacks.delete(_from);\r\n };\r\n\r\n if(to) {\r\n onTransitionEndCallbacks.set(_from, callback);\r\n } else {\r\n const timeout = window.setTimeout(callback, transitionTime);\r\n onTransitionEndCallbacks.set(_from, () => {\r\n clearTimeout(timeout);\r\n onTransitionEndCallbacks.delete(_from);\r\n });\r\n }\r\n\r\n if(isHeavy) {\r\n if(!animationDeferred) {\r\n animationDeferred = deferredPromise<void>();\r\n // animationStarted = performance.now();\r\n }\r\n \r\n dispatchHeavyAnimationEvent(animationDeferred, transitionTime * 2);\r\n }\r\n }\r\n \r\n from = to;\r\n }\r\n\r\n //selectTab.prevId = -1;\r\n selectTab.prevId = () => from ? whichChild(from) : -1;\r\n \r\n return selectTab;\r\n};\r\n\r\nexport default Transition;\r\n","import { IS_SAFARI } from \"./userAgent\";\n\n/*\n * This is used as a workaround for a memory leak in Safari caused by using Transferable objects to\n * transfer data between WebWorkers and the main thread.\n * https://github.com/mapbox/mapbox-gl-js/issues/8771\n *\n * This should be removed once the underlying Safari issue is fixed.\n */\n\nlet CAN_USE_TRANSFERABLES: boolean;\nif(!IS_SAFARI) CAN_USE_TRANSFERABLES = true;\nelse {\n try {\n const match = navigator.userAgent.match(/Version\\/(.+?) /);\n CAN_USE_TRANSFERABLES = +match[1] >= 14;\n } catch(err) {\n CAN_USE_TRANSFERABLES = false;\n }\n}\n\nexport default CAN_USE_TRANSFERABLES;\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 CAN_USE_TRANSFERABLES from \"../../environment/canUseTransferables\";\nimport { IS_ANDROID, IS_APPLE_MOBILE, IS_APPLE, IS_SAFARI } from \"../../environment/userAgent\";\nimport EventListenerBase from \"../../helpers/eventListenerBase\";\nimport mediaSizes from \"../../helpers/mediaSizes\";\nimport { clamp } from \"../../helpers/number\";\nimport lottieLoader from \"./lottieLoader\";\nimport QueryableWorker from \"./queryableWorker\";\n\nexport type RLottieOptions = {\n container: HTMLElement, \n canvas?: HTMLCanvasElement, \n autoplay?: boolean, \n animationData: Blob, \n loop?: boolean, \n width?: number,\n height?: number,\n group?: string,\n noCache?: boolean,\n needUpscale?: boolean,\n skipRatio?: number,\n initFrame?: number, // index\n color?: RLottieColor,\n inverseColor?: RLottieColor,\n name?: string,\n skipFirstFrameRendering?: boolean,\n toneIndex?: number\n};\n\ntype RLottieCacheMap = Map<number, Uint8ClampedArray>;\nclass RLottieCache {\n private cache: Map<string, {frames: RLottieCacheMap, counter: number}>;\n \n constructor() {\n this.cache = new Map();\n }\n\n public getCache(name: string) {\n let cache = this.cache.get(name);\n if(!cache) {\n this.cache.set(name, cache = {frames: new Map(), counter: 0});\n } else {\n // console.warn('[RLottieCache] cache will be reused', cache);\n }\n\n ++cache.counter;\n return cache.frames;\n }\n\n public releaseCache(name: string) {\n const cache = this.cache.get(name);\n if(cache && !--cache.counter) {\n this.cache.delete(name);\n // console.warn('[RLottieCache] released cache', cache);\n }\n }\n\n public getCacheCounter(name: string) {\n const cache = this.cache.get(name);\n return cache?.counter;\n }\n\n public generateName(name: string, width: number, height: number, color: RLottieColor, toneIndex: number) {\n return [\n name, \n width, \n height, \n // color ? rgbaToHexa(color) : ''\n color ? 'colored' : '',\n toneIndex || ''\n ].filter(Boolean).join('-');\n }\n}\n\nconst cache = new RLottieCache();\n\nexport type RLottieColor = [number, number, number];\n\nexport default class RLottiePlayer extends EventListenerBase<{\n enterFrame: (frameNo: number) => void,\n ready: () => void,\n firstFrame: () => void,\n cached: () => void\n}> {\n private static reqId = 0;\n\n public reqId = 0;\n public curFrame: number;\n private frameCount: number;\n private fps: number;\n private skipDelta: number;\n private name: string;\n private cacheName: string;\n private toneIndex: number;\n\n private worker: QueryableWorker;\n \n private width = 0;\n private height = 0;\n\n public el: HTMLElement;\n public canvas: HTMLCanvasElement;\n private context: CanvasRenderingContext2D;\n\n public paused = true;\n //public paused = false;\n public direction = 1;\n private speed = 1;\n public autoplay = true;\n public _autoplay: boolean; // ! will be used to store original value for settings.stickers.loop\n public loop = true;\n private _loop: boolean; // ! will be used to store original value for settings.stickers.loop\n private group = '';\n\n private frInterval: number;\n private frThen: number;\n private rafId: number;\n\n //private caching = false;\n //private removed = false;\n\n private frames: RLottieCacheMap;\n private imageData: ImageData;\n public clamped: Uint8ClampedArray;\n private cachingDelta = 0;\n\n private initFrame: number;\n private color: RLottieColor;\n private inverseColor: RLottieColor;\n\n public minFrame: number;\n public maxFrame: number;\n\n //private playedTimes = 0;\n\n private currentMethod: RLottiePlayer['mainLoopForwards'] | RLottiePlayer['mainLoopBackwards'];\n private frameListener: (currentFrame: number) => void;\n private skipFirstFrameRendering: boolean;\n private playToFrameOnFrameCallback: (frameNo: number) => void;\n\n constructor({el, worker, options}: {\n el: HTMLElement,\n worker: QueryableWorker,\n options: RLottieOptions\n }) {\n super(true);\n\n this.reqId = ++RLottiePlayer['reqId'];\n this.el = el;\n this.worker = worker;\n\n for(let i in options) {\n if(this.hasOwnProperty(i)) {\n // @ts-ignore\n this[i] = options[i];\n }\n }\n\n this._loop = this.loop;\n this._autoplay = this.autoplay;\n\n // ! :(\n this.initFrame = options.initFrame;\n this.color = options.color;\n this.inverseColor = options.inverseColor;\n this.name = options.name;\n this.skipFirstFrameRendering = options.skipFirstFrameRendering;\n this.toneIndex = options.toneIndex;\n\n // * Skip ratio (30fps)\n let skipRatio: number;\n if(options.skipRatio !== undefined) skipRatio = options.skipRatio;\n else if((IS_ANDROID || IS_APPLE_MOBILE || (IS_APPLE && !IS_SAFARI)) && this.width < 100 && this.height < 100 && !options.needUpscale) {\n skipRatio = 0.5;\n }\n\n this.skipDelta = skipRatio !== undefined ? 1 / skipRatio | 0 : 1;\n\n //options.needUpscale = true;\n\n // * Pixel ratio\n //const pixelRatio = window.devicePixelRatio;\n const pixelRatio = clamp(window.devicePixelRatio, 1, 2);\n if(pixelRatio > 1) {\n //this.cachingEnabled = true;//this.width < 100 && this.height < 100;\n if(options.needUpscale) {\n this.width = Math.round(this.width * pixelRatio);\n this.height = Math.round(this.height * pixelRatio);\n } else if(pixelRatio > 1) {\n if(this.width > 100 && this.height > 100) {\n if(IS_APPLE || !mediaSizes.isMobile) {\n /* this.width = Math.round(this.width * (pixelRatio - 1));\n this.height = Math.round(this.height * (pixelRatio - 1)); */\n this.width = Math.round(this.width * pixelRatio);\n this.height = Math.round(this.height * pixelRatio);\n } else if(pixelRatio > 2.5) {\n this.width = Math.round(this.width * (pixelRatio - 1.5));\n this.height = Math.round(this.height * (pixelRatio - 1.5));\n }\n } else {\n this.width = Math.round(this.width * Math.max(1.5, pixelRatio - 1.5));\n this.height = Math.round(this.height * Math.max(1.5, pixelRatio - 1.5));\n }\n }\n }\n\n //options.noCache = true;\n \n // * Cache frames params\n if(!options.noCache/* && false */) {\n // проверка на размер уже после скейлинга, сделано для попапа и сайдбара, где стикеры 80х80 и 68х68, туда нужно 75%\n if(IS_APPLE && this.width > 100 && this.height > 100) {\n this.cachingDelta = 2; //2 // 50%\n } else if(this.width < 100 && this.height < 100) {\n this.cachingDelta = Infinity; // 100%\n } else {\n this.cachingDelta = 4; // 75%\n }\n }\n \n // this.cachingDelta = Infinity;\n // if(isApple) {\n // this.cachingDelta = 0; //2 // 50%\n // }\n\n /* this.width *= 0.8;\n this.height *= 0.8; */\n \n //console.log(\"RLottiePlayer width:\", this.width, this.height, options);\n if(!this.canvas) {\n this.canvas = document.createElement('canvas');\n this.canvas.classList.add('rlottie');\n this.canvas.width = this.width;\n this.canvas.height = this.height;\n }\n\n this.context = this.canvas.getContext('2d');\n\n if(CAN_USE_TRANSFERABLES) {\n this.clamped = new Uint8ClampedArray(this.width * this.height * 4);\n }\n\n this.imageData = new ImageData(this.width, this.height);\n\n if(this.name) {\n this.cacheName = cache.generateName(this.name, this.width, this.height, this.color, this.toneIndex);\n this.frames = cache.getCache(this.cacheName);\n } else {\n this.frames = new Map();\n }\n }\n\n public clearCache() {\n if(this.cachingDelta === Infinity) {\n return;\n }\n \n if(this.cacheName && cache.getCacheCounter(this.cacheName) > 1) { // skip clearing because same sticker can be still visible\n return;\n }\n \n this.frames.clear();\n }\n\n public sendQuery(methodName: string, ...args: any[]) {\n //console.trace('RLottie sendQuery:', methodName);\n this.worker.sendQuery(methodName, this.reqId, ...args);\n }\n\n public loadFromData(data: RLottieOptions['animationData']) {\n this.sendQuery('loadFromData', data, this.width, this.height, this.toneIndex/* , this.canvas.transferControlToOffscreen() */);\n }\n\n public play() {\n if(!this.paused) {\n return;\n }\n\n //return;\n\n //console.log('RLOTTIE PLAY' + this.reqId);\n\n this.paused = false;\n this.setMainLoop();\n }\n\n public pause(clearPendingRAF = true) {\n if(this.paused) {\n return;\n }\n\n this.paused = true;\n if(clearPendingRAF) {\n clearTimeout(this.rafId);\n }\n //window.cancelAnimationFrame(this.rafId);\n }\n\n private resetCurrentFrame() {\n return this.curFrame = this.initFrame ?? (this.direction === 1 ? this.minFrame : this.maxFrame);\n }\n\n public stop(renderFirstFrame = true) {\n this.pause();\n\n const curFrame = this.resetCurrentFrame();\n if(renderFirstFrame) {\n this.requestFrame(curFrame);\n //this.sendQuery('renderFrame', this.curFrame);\n }\n }\n\n public restart() {\n this.stop(false);\n this.play();\n }\n\n public setSpeed(speed: number) {\n if(this.speed === speed) {\n return;\n }\n\n this.speed = speed;\n\n if(!this.paused) {\n this.setMainLoop();\n }\n }\n\n public setDirection(direction: number) {\n if(this.direction === direction) {\n return;\n }\n\n this.direction = direction;\n \n if(!this.paused) {\n this.setMainLoop();\n }\n }\n\n public remove() {\n //alert('remove');\n lottieLoader.onDestroy(this.reqId);\n this.pause();\n this.sendQuery('destroy');\n if(this.cacheName) cache.releaseCache(this.cacheName);\n this.cleanup();\n //this.removed = true;\n }\n\n private applyColor(frame: Uint8ClampedArray) {\n const [r, g, b] = this.color;\n for(let i = 0, length = frame.length; i < length; i += 4) {\n if(frame[i + 3] !== 0) {\n frame[i] = r;\n frame[i + 1] = g;\n frame[i + 2] = b;\n }\n }\n }\n\n private applyInversing(frame: Uint8ClampedArray) {\n const [r, g, b] = this.inverseColor;\n for(let i = 0, length = frame.length; i < length; i += 4) {\n if(frame[i + 3] === 0) {\n frame[i] = r;\n frame[i + 1] = g;\n frame[i + 2] = b;\n frame[i + 3] = 255;\n } else {\n frame[i + 3] = 0;\n }\n }\n }\n\n public renderFrame2(frame: Uint8ClampedArray, frameNo: number) {\n /* this.setListenerResult('enterFrame', frameNo);\n return; */\n\n try {\n if(this.color) {\n this.applyColor(frame);\n }\n\n if(this.inverseColor) {\n this.applyInversing(frame);\n }\n\n this.imageData.data.set(frame);\n \n //this.context.putImageData(new ImageData(frame, this.width, this.height), 0, 0);\n //let perf = performance.now();\n this.context.putImageData(this.imageData, 0, 0);\n //console.log('renderFrame2 perf:', performance.now() - perf);\n } catch(err) {\n console.error('RLottiePlayer renderFrame error:', err/* , frame */, this.width, this.height);\n this.autoplay = false;\n this.pause();\n return;\n }\n \n //console.log('set result enterFrame', frameNo);\n this.dispatchEvent('enterFrame', frameNo);\n }\n\n public renderFrame(frame: Uint8ClampedArray, frameNo: number) {\n //console.log('renderFrame', frameNo, this);\n if(this.cachingDelta && (frameNo % this.cachingDelta || !frameNo) && !this.frames.has(frameNo)) {\n this.frames.set(frameNo, new Uint8ClampedArray(frame));//frame;\n }\n\n /* if(!this.listenerResults.hasOwnProperty('cached')) {\n this.setListenerResult('enterFrame', frameNo);\n if(frameNo === (this.frameCount - 1)) {\n this.setListenerResult('cached');\n }\n\n return;\n } */\n\n if(this.frInterval) {\n const now = Date.now(), delta = now - this.frThen;\n //console.log(`renderFrame delta${this.reqId}:`, this, delta, this.frInterval);\n\n if(delta < 0) {\n if(this.rafId) clearTimeout(this.rafId);\n return this.rafId = window.setTimeout(() => {\n this.renderFrame2(frame, frameNo);\n }, this.frInterval > -delta ? -delta % this.frInterval : this.frInterval);\n //await new Promise((resolve) => setTimeout(resolve, -delta % this.frInterval));\n }\n }\n\n this.renderFrame2(frame, frameNo);\n }\n\n public requestFrame(frameNo: number) {\n const frame = this.frames.get(frameNo);\n if(frame) {\n this.renderFrame(frame, frameNo);\n } else {\n if(this.clamped && !this.clamped.length) { // fix detached\n this.clamped = new Uint8ClampedArray(this.width * this.height * 4);\n }\n \n this.sendQuery('renderFrame', frameNo, this.clamped);\n }\n }\n\n private onLap() {\n //this.playedTimes++;\n\n if(!this.loop) {\n this.pause(false);\n return false;\n }\n\n return true;\n }\n\n private mainLoopForwards() {\n const {skipDelta, maxFrame} = this;\n const frame = (this.curFrame + skipDelta) > maxFrame ? this.curFrame = (this.loop ? this.minFrame : this.maxFrame) : this.curFrame += skipDelta;\n // console.log('mainLoopForwards', this.curFrame, skipDelta, frame);\n\n this.requestFrame(frame);\n if((frame + skipDelta) > maxFrame) {\n return this.onLap();\n }\n\n return true;\n }\n \n private mainLoopBackwards() {\n const {skipDelta, minFrame} = this;\n const frame = (this.curFrame - skipDelta) < minFrame ? this.curFrame = (this.loop ? this.maxFrame : this.minFrame) : this.curFrame -= skipDelta;\n // console.log('mainLoopBackwards', this.curFrame, skipDelta, frame);\n\n this.requestFrame(frame);\n if((frame - skipDelta) < minFrame) {\n return this.onLap();\n }\n\n return true;\n }\n\n public setMainLoop() {\n //window.cancelAnimationFrame(this.rafId);\n clearTimeout(this.rafId);\n\n this.frInterval = 1000 / this.fps / this.speed * this.skipDelta;\n this.frThen = Date.now() - this.frInterval;\n\n //console.trace('setMainLoop', this.frInterval, this.direction, this, JSON.stringify(this.listenerResults), this.listenerResults);\n\n const method = (this.direction === 1 ? this.mainLoopForwards : this.mainLoopBackwards).bind(this);\n this.currentMethod = method;\n //this.frameListener && this.removeListener('enterFrame', this.frameListener);\n\n //setTimeout(() => {\n //this.addListener('enterFrame', this.frameListener);\n //}, 0);\n\n if(this.frameListener) {\n const lastResult = this.listenerResults.enterFrame;\n if(lastResult !== undefined) {\n this.frameListener(this.curFrame);\n }\n }\n \n //this.mainLoop(method);\n //this.r(method);\n //method();\n }\n\n public playPart(options: {\n from: number, \n to: number, \n callback?: () => void\n }) {\n this.pause();\n\n const {from, to, callback} = options;\n this.curFrame = from - 1;\n\n return this.playToFrame({\n frame: to,\n direction: to > from ? 1 : -1,\n callback\n });\n }\n\n public playToFrame(options: {\n frame: number, \n speed?: number, \n direction?: number,\n callback?: () => void\n }) {\n this.pause();\n \n const {frame, speed, callback, direction} = options;\n this.setDirection(direction === undefined ? this.curFrame > frame ? -1 : 1 : direction);\n speed !== undefined && this.setSpeed(speed);\n\n const bounds = [this.curFrame, frame];\n if(this.direction === -1) bounds.reverse();\n \n this.loop = false;\n this.setMinMax(bounds[0], bounds[1]);\n\n if(this.playToFrameOnFrameCallback) {\n this.removeEventListener('enterFrame', this.playToFrameOnFrameCallback);\n }\n\n if(callback) {\n this.playToFrameOnFrameCallback = (frameNo: number) => {\n if(frameNo === frame) {\n this.removeEventListener('enterFrame', this.playToFrameOnFrameCallback);\n callback();\n }\n };\n\n this.addEventListener('enterFrame', this.playToFrameOnFrameCallback);\n }\n\n this.play();\n }\n\n public setColor(color: RLottieColor, renderIfPaused: boolean) {\n this.color = color;\n\n if(renderIfPaused && this.paused) {\n this.renderFrame2(this.imageData.data, this.curFrame);\n }\n }\n\n public setInverseColor(color: RLottieColor) {\n this.inverseColor = color;\n }\n\n private setMinMax(minFrame = 0, maxFrame = this.frameCount - 1) {\n this.minFrame = minFrame;\n this.maxFrame = maxFrame;\n }\n\n public async onLoad(frameCount: number, fps: number) {\n this.frameCount = frameCount;\n this.fps = fps;\n this.setMinMax();\n if(this.initFrame !== undefined) {\n this.initFrame = clamp(this.initFrame, this.minFrame, this.maxFrame);\n }\n\n const curFrame = this.resetCurrentFrame();\n\n // * Handle 30fps stickers if 30fps set\n if(this.fps < 60 && this.skipDelta !== 1) {\n const diff = 60 / fps;\n this.skipDelta = this.skipDelta / diff | 0;\n }\n\n this.frInterval = 1000 / this.fps / this.speed * this.skipDelta;\n this.frThen = Date.now() - this.frInterval;\n //this.sendQuery('renderFrame', 0);\n \n // Кешировать сразу не получится, рендер стикера (тайгер) занимает 519мс, \n // если рендерить 75% с получением каждого кадра из воркера, будет 475мс, т.е. при 100% было бы 593мс, потеря на передаче 84мс. \n\n /* console.time('cache' + this.reqId);\n for(let i = 0; i < frameCount; ++i) {\n //if(this.removed) return;\n \n if(i % 4) {\n await new Promise((resolve) => {\n delete this.listenerResults.enterFrame;\n this.addListener('enterFrame', resolve, true);\n this.requestFrame(i);\n }); \n }\n }\n \n console.timeEnd('cache' + this.reqId); */\n //console.log('cached');\n /* this.el.innerHTML = '';\n this.el.append(this.canvas);\n return; */\n\n !this.skipFirstFrameRendering && this.requestFrame(curFrame);\n this.dispatchEvent('ready');\n this.addEventListener('enterFrame', () => {\n this.dispatchEvent('firstFrame');\n\n if(!this.canvas.parentNode && this.el) {\n this.el.appendChild(this.canvas);\n }\n\n //console.log('enterFrame firstFrame');\n \n //let lastTime = this.frThen;\n this.frameListener = () => {\n if(this.paused) {\n return;\n }\n\n const time = Date.now();\n //console.log(`enterFrame handle${this.reqId}`, time, (time - lastTime), this.frInterval);\n /* if(Math.round(time - lastTime + this.frInterval * 0.25) < Math.round(this.frInterval)) {\n return;\n } */\n\n //lastTime = time;\n\n this.frThen = time + this.frInterval;\n const canContinue = this.currentMethod();\n if(!canContinue && !this.loop && this.autoplay) {\n this.autoplay = false;\n }\n };\n\n this.addEventListener('enterFrame', this.frameListener);\n\n // ! fix autoplaying since there will be no animationIntersector for it,\n if(this.group === 'none' && this.autoplay) {\n this.play();\n }\n }, {once: true});\n }\n}\n","export default function compareVersion(v1: string, v2: string): number {\n v1 = v1.split(' ', 1)[0];\n v2 = v2.split(' ', 1)[0];\n const s1 = v1.split('.');\n const s2 = v2.split('.');\n\n for(let i = 0; i < s1.length; ++i) {\n const v1 = +s1[i];\n const v2 = +s2[i];\n if(v1 > v2) return 1;\n else if(v1 < v2) return -1;\n }\n\n return 0;\n}\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 { Dialog } from './appMessagesManager';\nimport { NULL_PEER_ID, UserAuth } from '../mtproto/mtproto_config';\nimport type { MyTopPeer, TopPeerType, User } from './appUsersManager';\nimport type { AuthState } from '../../types';\nimport type FiltersStorage from '../storages/filters';\nimport type DialogsStorage from '../storages/dialogs';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport rootScope from '../rootScope';\nimport stateStorage from '../stateStorage';\nimport { logger } from '../logger';\nimport { copy, setDeepProperty, validateInitObject } from '../../helpers/object';\nimport App from '../../config/app';\nimport DEBUG, { MOUNT_CLASS_TO } from '../../config/debug';\nimport AppStorage from '../storage';\nimport { AutoDownloadSettings, Chat, NotifyPeer, PeerNotifySettings } from '../../layer';\nimport { IS_MOBILE } from '../../environment/userAgent';\nimport DATABASE_STATE from '../../config/databases/state';\nimport sessionStorage from '../sessionStorage';\nimport { nextRandomUint } from '../../helpers/random';\nimport compareVersion from '../../helpers/compareVersion';\nimport getTimeFormat from '../../helpers/getTimeFormat';\n\nconst REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day\n// const REFRESH_EVERY = 1e3;\n//const REFRESH_EVERY_WEEK = 24 * 60 * 60 * 1000 * 7; // 7 days\nconst STATE_VERSION = App.version;\nconst BUILD = App.build;\n\nexport type Background = {\n type?: 'color' | 'image' | 'default', // ! DEPRECATED\n blur: boolean,\n highlightningColor?: string,\n color?: string, \n slug?: string, // image slug\n intensity?: number, // pattern intensity\n id: string | number, // wallpaper id\n};\n\nexport type Theme = {\n name: 'day' | 'night' | 'system',\n background: Background\n};\n\nexport type AutoDownloadPeerTypeSettings = {\n contacts: boolean,\n private: boolean,\n groups: boolean,\n channels: boolean\n};\n\nexport type State = {\n allDialogsLoaded: DialogsStorage['allDialogsLoaded'],\n pinnedOrders: DialogsStorage['pinnedOrders'],\n contactsList: UserId[],\n updates: Partial<{\n seq: number,\n pts: number,\n date: number\n }>,\n filters: FiltersStorage['filters'],\n maxSeenMsgId: number,\n stateCreatedTime: number,\n recentEmoji: string[],\n topPeersCache: {\n [type in TopPeerType]?: {\n peers: MyTopPeer[],\n cachedTime: number\n }\n },\n recentSearch: PeerId[],\n version: typeof STATE_VERSION,\n build: typeof BUILD,\n authState: AuthState,\n hiddenPinnedMessages: {[peerId: PeerId]: number},\n settings: {\n messagesTextSize: number,\n distanceUnit: 'kilometers' | 'miles',\n sendShortcut: 'enter' | 'ctrlEnter',\n animationsEnabled: boolean,\n autoDownload: {\n contacts?: boolean, // ! DEPRECATED\n private?: boolean, // ! DEPRECATED\n groups?: boolean, // ! DEPRECATED\n channels?: boolean, // ! DEPRECATED\n photo: AutoDownloadPeerTypeSettings,\n video: AutoDownloadPeerTypeSettings,\n file: AutoDownloadPeerTypeSettings\n },\n autoDownloadNew: AutoDownloadSettings,\n autoPlay: {\n gifs: boolean,\n videos: boolean\n },\n stickers: {\n suggest: boolean,\n loop: boolean\n },\n emoji: {\n suggest: boolean,\n big: boolean\n },\n background?: Background, // ! DEPRECATED\n themes: Theme[],\n theme: Theme['name'],\n notifications: {\n sound: boolean\n },\n nightTheme?: boolean, // ! DEPRECATED\n timeFormat: 'h12' | 'h23'\n },\n keepSigned: boolean,\n chatContextMenuHintWasShown: boolean,\n stateId: number,\n notifySettings: {[k in Exclude<NotifyPeer['_'], 'notifyPeer'>]?: PeerNotifySettings.peerNotifySettings}\n};\n\nexport const STATE_INIT: State = {\n allDialogsLoaded: {},\n pinnedOrders: {},\n contactsList: [],\n updates: {},\n filters: {},\n maxSeenMsgId: 0,\n stateCreatedTime: Date.now(),\n recentEmoji: [],\n topPeersCache: {},\n recentSearch: [],\n version: STATE_VERSION,\n build: BUILD,\n authState: {\n _: IS_MOBILE ? 'authStateSignIn' : 'authStateSignQr'\n },\n hiddenPinnedMessages: {},\n settings: {\n messagesTextSize: 16,\n distanceUnit: 'kilometers',\n sendShortcut: 'enter',\n animationsEnabled: true,\n autoDownload: {\n photo: {\n contacts: true,\n private: true,\n groups: true,\n channels: true\n },\n video: {\n contacts: true,\n private: true,\n groups: true,\n channels: true\n },\n file: {\n contacts: true,\n private: true,\n groups: true,\n channels: true\n }\n },\n autoDownloadNew: {\n _: 'autoDownloadSettings',\n file_size_max: 3145728,\n pFlags: {\n video_preload_large: true,\n audio_preload_next: true\n },\n photo_size_max: 1048576,\n video_size_max: 15728640,\n video_upload_maxbitrate: 100\n },\n autoPlay: {\n gifs: true,\n videos: true\n },\n stickers: {\n suggest: true,\n loop: true\n },\n emoji: {\n suggest: true,\n big: true\n },\n themes: [{\n name: 'day',\n background: {\n blur: false,\n slug: 'pattern',\n color: '#dbddbb,#6ba587,#d5d88d,#88b884',\n highlightningColor: 'hsla(86.4, 43.846153%, 45.117647%, .4)',\n intensity: 50,\n id: '1'\n }\n }, {\n name: 'night',\n background: {\n blur: false,\n slug: 'pattern',\n // color: '#dbddbb,#6ba587,#d5d88d,#88b884',\n color: '#fec496,#dd6cb9,#962fbf,#4f5bd5',\n highlightningColor: 'hsla(299.142857, 44.166666%, 37.470588%, .4)',\n intensity: -50,\n id: '-1'\n }\n }],\n theme: 'system',\n notifications: {\n sound: false\n },\n timeFormat: getTimeFormat()\n },\n keepSigned: true,\n chatContextMenuHintWasShown: false,\n stateId: nextRandomUint(32),\n notifySettings: {}\n};\n\nconst ALL_KEYS = Object.keys(STATE_INIT) as any as Array<keyof State>;\n\nconst REFRESH_KEYS = ['contactsList', 'stateCreatedTime',\n 'maxSeenMsgId', 'filters', 'topPeers'] as any as Array<keyof State>;\n\nexport type StatePeerType = 'recentSearch' | 'topPeer' | 'dialog' | 'contact' | 'topMessage' | 'self';\n\n//const REFRESH_KEYS_WEEK = ['dialogs', 'allDialogsLoaded', 'updates', 'pinnedOrders'] as any as Array<keyof State>;\n\nexport class AppStateManager extends EventListenerBase<{\n save: (state: State) => Promise<void>,\n peerNeeded: (peerId: PeerId) => void,\n peerUnneeded: (peerId: PeerId) => void\n}> {\n public static STATE_INIT = STATE_INIT;\n private loaded: Promise<State>;\n private log = logger('STATE'/* , LogLevels.error */);\n\n private state: State;\n\n private neededPeers: Map<PeerId, Set<string>> = new Map();\n private singlePeerMap: Map<string, PeerId> = new Map();\n\n public storages = {\n users: new AppStorage<Record<UserId, User>, typeof DATABASE_STATE>(DATABASE_STATE, 'users'),\n chats: new AppStorage<Record<ChatId, Chat>, typeof DATABASE_STATE>(DATABASE_STATE, 'chats'),\n dialogs: new AppStorage<Record<PeerId, Dialog>, typeof DATABASE_STATE>(DATABASE_STATE, 'dialogs')\n };\n\n public storagesResults: {\n users: User[],\n chats: Chat[],\n dialogs: Dialog[]\n } = {} as any;\n\n public storage = stateStorage;\n\n public newVersion: string;\n\n constructor() {\n super();\n this.loadSavedState();\n\n rootScope.addEventListener('user_auth', () => {\n this.requestPeerSingle(rootScope.myId, 'self');\n });\n }\n\n public loadSavedState(): Promise<State> {\n if(this.loaded) return this.loaded;\n console.time('load state');\n this.loaded = new Promise((resolve) => {\n const storagesKeys = Object.keys(this.storages) as Array<keyof AppStateManager['storages']>;\n const storagesPromises: Promise<any>[] = storagesKeys.map(key => this.storages[key].getAll());\n\n const promises/* : Promise<any>[] */ = ALL_KEYS.map(key => stateStorage.get(key))\n .concat(sessionStorage.get('user_auth'), sessionStorage.get('state_id'))\n .concat(stateStorage.get('user_auth')) // support old webk format\n .concat(storagesPromises);\n\n Promise.all(promises).then(async(arr) => {\n // await new Promise((resolve) => setTimeout(resolve, 3e3));\n /* const self = this;\n const skipHandleKeys = new Set(['isProxy', 'filters', 'drafts']);\n const getHandler = (path?: string) => {\n return {\n get(target: any, key: any) {\n if(key === 'isProxy') {\n return true;\n }\n\n const prop = target[key];\n\n if(prop !== undefined && !skipHandleKeys.has(key) && !prop.isProxy && typeof(prop) === 'object') {\n target[key] = new Proxy(prop, getHandler(path || key));\n return target[key];\n }\n \n return prop;\n },\n set(target: any, key: any, value: any) {\n console.log('Setting', target, `.${key} to equal`, value, path);\n \n target[key] = value;\n\n // @ts-ignore\n self.pushToState(path || key, path ? self.state[path] : value, false);\n\n return true;\n }\n };\n }; */\n\n let state: State = this.state = {} as any;\n\n // ! then can't store false values\n for(let i = 0, length = ALL_KEYS.length; i < length; ++i) {\n const key = ALL_KEYS[i];\n const value = arr[i];\n if(value !== undefined) {\n // @ts-ignore\n state[key] = value;\n } else {\n this.pushToState(key, copy(STATE_INIT[key]));\n }\n }\n\n arr.splice(0, ALL_KEYS.length);\n\n // * Read auth\n let auth = arr.shift() as UserAuth | number;\n const stateId = arr.shift() as number;\n const shiftedWebKAuth = arr.shift() as UserAuth | number;\n if(!auth && shiftedWebKAuth) { // support old webk auth\n auth = shiftedWebKAuth;\n const keys: string[] = ['dc', 'server_time_offset', 'xt_instance'];\n for(let i = 1; i <= 5; ++i) {\n keys.push(`dc${i}_server_salt`);\n keys.push(`dc${i}_auth_key`);\n }\n\n const values = await Promise.all(keys.map(key => stateStorage.get(key as any)));\n keys.push('user_auth');\n values.push(typeof(auth) === 'number' || typeof(auth) === 'string' ? {dcID: values[0] || App.baseDcId, date: Date.now() / 1000 | 0, id: auth.toPeerId(false)} as UserAuth : auth);\n\n let obj: any = {};\n keys.forEach((key, idx) => {\n obj[key] = values[idx];\n });\n\n await sessionStorage.set(obj);\n }\n \n /* if(!auth) { // try to read Webogram's session from localStorage\n try {\n const keys = Object.keys(localStorage);\n for(let i = 0; i < keys.length; ++i) {\n const key = keys[i];\n let value: any;\n try {\n value = localStorage.getItem(key);\n value = JSON.parse(value);\n } catch(err) {\n //console.error(err);\n }\n\n sessionStorage.set({\n [key as any]: value\n });\n }\n\n auth = sessionStorage.getFromCache('user_auth');\n } catch(err) {\n this.log.error('localStorage import error', err);\n }\n } */\n\n if(auth) {\n // ! Warning ! DON'T delete this\n state.authState = {_: 'authStateSignedIn'};\n rootScope.dispatchEvent('user_auth', typeof(auth) === 'number' || typeof(auth) === 'string' ? \n {dcID: 0, date: Date.now() / 1000 | 0, id: auth.toPeerId(false)} : \n auth); // * support old version\n }\n\n // * Read storages\n for(let i = 0, length = storagesKeys.length; i < length; ++i) {\n this.storagesResults[storagesKeys[i]] = arr[i] as any;\n }\n\n arr.splice(0, storagesKeys.length);\n\n if(state.stateId !== stateId) {\n if(stateId !== undefined) {\n const preserve: Map<keyof State, State[keyof State]> = new Map([\n ['authState', undefined],\n ['stateId', undefined]\n ]);\n \n preserve.forEach((_, key) => {\n preserve.set(key, copy(state[key]));\n });\n \n state = this.state = copy(STATE_INIT);\n \n preserve.forEach((value, key) => {\n // @ts-ignore\n state[key] = value;\n });\n\n for(const key in this.storagesResults) {\n this.storagesResults[key as keyof AppStateManager['storagesResults']].length = 0;\n }\n\n this.storage.set(state);\n }\n\n await sessionStorage.set({\n state_id: state.stateId\n });\n }\n\n const time = Date.now();\n if((state.stateCreatedTime + REFRESH_EVERY) < time) {\n if(DEBUG) {\n this.log('will refresh state', state.stateCreatedTime, time);\n }\n\n const r = (keys: typeof REFRESH_KEYS) => {\n keys.forEach(key => {\n this.pushToState(key, copy(STATE_INIT[key]));\n \n // @ts-ignore\n const s = this.storagesResults[key];\n if(s && s.length) {\n s.length = 0;\n }\n });\n };\n \n r(REFRESH_KEYS);\n\n /* if((state.stateCreatedTime + REFRESH_EVERY_WEEK) < time) {\n if(DEBUG) {\n this.log('will refresh updates');\n }\n\n r(REFRESH_KEYS_WEEK);\n } */\n }\n \n //state = this.state = new Proxy(state, getHandler());\n\n // * support old version\n if(!state.settings.hasOwnProperty('theme') && state.settings.hasOwnProperty('nightTheme')) {\n state.settings.theme = state.settings.nightTheme ? 'night' : 'day';\n this.pushToState('settings', state.settings);\n }\n\n // * support old version\n if(!state.settings.hasOwnProperty('themes') && state.settings.background) {\n state.settings.themes = copy(STATE_INIT.settings.themes);\n const theme = state.settings.themes.find(t => t.name === state.settings.theme);\n if(theme) {\n theme.background = state.settings.background;\n this.pushToState('settings', state.settings);\n }\n }\n\n // * migrate auto download settings\n const autoDownloadSettings = state.settings.autoDownload;\n if(autoDownloadSettings?.private !== undefined) {\n const oldTypes = [\n 'contacts' as const, \n 'private' as const, \n 'groups' as const, \n 'channels' as const\n ];\n\n const mediaTypes = [\n 'photo' as const,\n 'video' as const,\n 'file' as const\n ];\n\n mediaTypes.forEach(mediaType => {\n const peerTypeSettings: AutoDownloadPeerTypeSettings = autoDownloadSettings[mediaType] = {} as any;\n oldTypes.forEach(peerType => {\n peerTypeSettings[peerType] = autoDownloadSettings[peerType];\n });\n });\n\n oldTypes.forEach(peerType => {\n delete autoDownloadSettings[peerType];\n });\n\n this.pushToState('settings', state.settings);\n }\n\n validateInitObject(STATE_INIT, state, (missingKey) => {\n // @ts-ignore\n this.pushToState(missingKey, state[missingKey]);\n });\n\n if(state.version !== STATE_VERSION || state.build !== BUILD/* || true */) {\n // reset filters and dialogs if version is older\n if(compareVersion(state.version, '0.8.7') === -1) {\n this.state.allDialogsLoaded = copy(STATE_INIT.allDialogsLoaded);\n this.state.filters = copy(STATE_INIT.filters);\n const result = this.storagesResults.dialogs;\n if(result?.length) {\n result.length = 0;\n }\n }\n\n // * migrate backgrounds (March 13, 2022; to version 1.3.0)\n if(compareVersion(state.version, '1.3.0') === -1) {\n let migrated = false;\n state.settings.themes.forEach((theme, idx, arr) => {\n if((\n theme.name === 'day' && \n theme.background.slug === 'ByxGo2lrMFAIAAAAmkJxZabh8eM' && \n theme.background.type === 'image' \n ) || (\n theme.name === 'night' && \n theme.background.color === '#0f0f0f' && \n theme.background.type === 'color' \n )) {\n const newTheme = STATE_INIT.settings.themes.find(newTheme => newTheme.name === theme.name);\n if(newTheme) {\n arr[idx] = copy(newTheme);\n migrated = true;\n }\n }\n });\n\n if(migrated) {\n this.pushToState('settings', state.settings);\n }\n }\n \n if(compareVersion(state.version, STATE_VERSION) !== 0) {\n this.newVersion = STATE_VERSION;\n }\n\n this.pushToState('version', STATE_VERSION);\n this.pushToState('build', BUILD);\n }\n\n // ! probably there is better place for it\n rootScope.settings = state.settings;\n\n if(DEBUG) {\n this.log('state res', state, copy(state));\n }\n \n //return resolve();\n\n console.timeEnd('load state');\n resolve(state);\n }).catch(resolve);\n });\n\n return this.loaded;\n }\n\n public getState() {\n return this.state === undefined ? this.loadSavedState() : Promise.resolve(this.state);\n }\n\n public setByKey(key: string, value: any) {\n setDeepProperty(this.state, key, value);\n rootScope.dispatchEvent('settings_updated', {key, value});\n\n const first = key.split('.')[0];\n // @ts-ignore\n this.pushToState(first, this.state[first]);\n }\n\n public pushToState<T extends keyof State>(key: T, value: State[T], direct = true) {\n if(direct) {\n this.state[key] = value;\n }\n\n this.setKeyValueToStorage(key, value);\n }\n\n public setKeyValueToStorage<T extends keyof State>(key: T, value: State[T] = this.state[key]) {\n this.storage.set({\n [key]: value\n });\n }\n\n public requestPeer(peerId: PeerId, type: StatePeerType, limit?: number) {\n let set = this.neededPeers.get(peerId);\n if(set && set.has(type)) {\n return;\n }\n\n if(!set) {\n set = new Set();\n this.neededPeers.set(peerId, set);\n }\n\n set.add(type);\n\n this.dispatchEvent('peerNeeded', peerId);\n\n if(limit !== undefined) {\n this.keepPeerSingle(peerId, type);\n }\n }\n\n public requestPeerSingle(peerId: PeerId, type: StatePeerType, keepPeerIdSingle: PeerId = peerId) {\n return this.requestPeer(peerId, type + '_' + keepPeerIdSingle as any, 1);\n }\n\n public releaseSinglePeer(peerId: PeerId, type: StatePeerType) {\n return this.keepPeerSingle(NULL_PEER_ID, type + '_' + peerId as any);\n }\n\n public isPeerNeeded(peerId: PeerId) {\n return this.neededPeers.has(peerId);\n }\n\n public keepPeerSingle(peerId: PeerId, type: StatePeerType) {\n const existsPeerId = this.singlePeerMap.get(type);\n if(existsPeerId && existsPeerId !== peerId && this.neededPeers.has(existsPeerId)) {\n const set = this.neededPeers.get(existsPeerId);\n set.delete(type);\n\n if(!set.size) {\n this.neededPeers.delete(existsPeerId);\n this.dispatchEvent('peerUnneeded', existsPeerId);\n }\n }\n\n if(peerId) {\n this.singlePeerMap.set(type, peerId);\n } else {\n this.singlePeerMap.delete(type);\n }\n }\n\n /* public resetState() {\n for(let i in this.state) {\n // @ts-ignore\n this.state[i] = false;\n }\n sessionStorage.set(this.state).then(() => {\n location.reload();\n });\n } */\n}\n\n//console.trace('appStateManager include');\n\nconst appStateManager = new AppStateManager();\nMOUNT_CLASS_TO.appStateManager = appStateManager;\nexport default appStateManager;\n","export default function getTimeFormat(): 'h12' | 'h23' {\n // try {\n // const resolvedOptions = Intl.DateTimeFormat(navigator.language, {hour: 'numeric'}).resolvedOptions();\n // if('hourCycle' in resolvedOptions) {\n // return (resolvedOptions as any).hourCycle === 'h12' ? 'h12' : 'h23';\n // } else {\n // return resolvedOptions.hour12 ? 'h12' : 'h23';\n // }\n // } catch(err) {\n return new Date().toLocaleString().match(/\\s(AM|PM)/) ? 'h12' : 'h23';\n // }\n}\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 { copy } from \"./object\";\r\n\r\nexport function listMergeSorted(list1: any[] = [], list2: any[] = []) {\r\n const result = copy(list1);\r\n\r\n const minId = list1.length ? list1[list1.length - 1] : 0xFFFFFFFF;\r\n for(let i = 0; i < list2.length; i++) {\r\n if(list2[i] < minId) {\r\n result.push(list2[i]);\r\n }\r\n }\r\n\r\n return result;\r\n} */\r\n\r\nexport const accumulate = (arr: number[], initialValue: number) => arr.reduce((acc, value) => acc + value, initialValue);\r\n\r\nexport function indexOfAndSplice<T>(array: Array<T>, item: T) {\r\n const idx = array.indexOf(item);\r\n const spliced = idx !== -1 && array.splice(idx, 1);\r\n return spliced && spliced[0];\r\n}\r\n\r\nexport function findAndSpliceAll<T>(array: Array<T>, verify: (value: T, index: number, arr: typeof array) => boolean) {\r\n const out: typeof array = [];\r\n let idx = -1;\r\n while((idx = array.findIndex(verify)) !== -1) {\r\n out.push(array.splice(idx, 1)[0]);\r\n }\r\n\r\n return out;\r\n}\r\n\r\nexport function forEachReverse<T>(array: Array<T>, callback: (value: T, index?: number, array?: Array<T>) => void) {\r\n for(let length = array.length, i = length - 1; i >= 0; --i) {\r\n callback(array[i], i, array);\r\n }\r\n};\r\n\r\nexport function insertInDescendSortedArray<T extends {[smth in K]?: number}, K extends keyof T>(array: Array<T>, element: T, property: K, pos?: number) {\r\n const sortProperty: number = element[property];\r\n\r\n if(pos === undefined) {\r\n pos = array.indexOf(element);\r\n }\r\n\r\n if(pos !== -1) {\r\n const prev = array[pos - 1];\r\n const next = array[pos + 1];\r\n if((!prev || prev[property] >= sortProperty) && (!next || next[property] <= sortProperty)) {\r\n // console.warn('same pos', pos, sortProperty, prev, next);\r\n return pos;\r\n }\r\n \r\n array.splice(pos, 1);\r\n }\r\n\r\n const len = array.length;\r\n if(!len || sortProperty <= array[len - 1][property]) {\r\n return array.push(element) - 1;\r\n } else if(sortProperty >= array[0][property]) {\r\n array.unshift(element);\r\n return 0;\r\n } else {\r\n for(let i = 0; i < len; i++) {\r\n if(sortProperty > array[i][property]) {\r\n array.splice(i, 0, element);\r\n return i;\r\n }\r\n }\r\n }\r\n\r\n console.error('wtf', array, element);\r\n return array.indexOf(element);\r\n}\r\n\r\nexport function filterUnique<T extends Array<any>>(arr: T): T {\r\n return [...new Set(arr)] as T;\r\n}\r\n\r\nexport function flatten<T>(arr: T[][]): T[] {\r\n return arr.reduce((acc, val) => (acc.push(...val), acc), []);\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// * Jolly Cobra's schedulers\r\nimport { NoneToVoidFunction } from \"../types\";\r\n\r\n/*\r\nexport function throttleWithTickEnd<F extends AnyToVoidFunction>(fn: F) {\r\n return throttleWith(onTickEnd, fn);\r\n}\r\n\r\nexport function throttleWithNow<F extends AnyToVoidFunction>(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<DOMHighResTimeStamp>;\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<void>((resolve) => {\r\n fastRaf(() => {\r\n fastRaf(resolve);\r\n });\r\n });\r\n}\r\n","export default function Worker_fn() {\n return new Worker(__webpack_public_path__ + \"rlottie.worker.474e00562ef6af8b4fb4.bundle.worker.js\");\n}\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 { IS_SAFARI } from \"../../environment/userAgent\";\nimport EventListenerBase from \"../../helpers/eventListenerBase\";\n\nexport default class QueryableWorker extends EventListenerBase<{\n ready: () => void,\n frame: (reqId: number, frameNo: number, frame: Uint8ClampedArray) => void,\n loaded: (reqId: number, frameCount: number, fps: number) => void,\n error: (reqId: number, error: Error) => void,\n workerError: (error: ErrorEvent) => void\n}> {\n constructor(private worker: Worker) {\n super();\n\n this.worker.onerror = (error) => {\n try {\n this.dispatchEvent('workerError', error);\n this.cleanup();\n this.terminate();\n } catch(err) {\n \n }\n };\n\n this.worker.onmessage = (event) => {\n this.dispatchEvent(event.data.queryMethodListener, ...event.data.queryMethodArguments);\n };\n }\n\n public postMessage(message: any) {\n this.worker.postMessage(message);\n }\n\n public terminate() {\n this.worker.terminate();\n }\n\n public sendQuery(queryMethod: string, ...args: any[]) {\n if(IS_SAFARI) {\n this.worker.postMessage({\n queryMethod: queryMethod,\n queryMethodArguments: args\n });\n } else {\n const transfer: (ArrayBuffer | OffscreenCanvas)[] = [];\n args.forEach(arg => {\n if(arg instanceof ArrayBuffer) {\n transfer.push(arg);\n }\n \n if(typeof(arg) === 'object' && arg.buffer instanceof ArrayBuffer) {\n transfer.push(arg.buffer);\n }\n });\n \n //console.log('transfer', transfer);\n this.worker.postMessage({\n queryMethod: queryMethod,\n queryMethodArguments: args\n }, transfer as PostMessageOptions);\n }\n }\n}\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 RLottieWorker from 'worker-loader!./rlottie.worker';\r\nimport animationIntersector from \"../../components/animationIntersector\";\r\nimport { MOUNT_CLASS_TO } from '../../config/debug';\r\nimport { pause } from '../../helpers/schedulers/pause';\r\nimport { logger, LogTypes } from \"../logger\";\r\nimport apiManager from \"../mtproto/mtprotoworker\";\r\nimport RLottiePlayer, { RLottieOptions } from './rlottiePlayer';\r\nimport QueryableWorker from './queryableWorker';\r\nimport blobConstruct from '../../helpers/blob/blobConstruct';\r\n\r\nexport type LottieAssetName = 'EmptyFolder' | 'Folders_1' | 'Folders_2' | \r\n 'TwoFactorSetupMonkeyClose' | 'TwoFactorSetupMonkeyCloseAndPeek' | \r\n 'TwoFactorSetupMonkeyCloseAndPeekToIdle' | 'TwoFactorSetupMonkeyIdle' | \r\n 'TwoFactorSetupMonkeyPeek' | 'TwoFactorSetupMonkeyTracking' | \r\n 'voice_outlined2' | 'voip_filled' | 'voice_mini';\r\n\r\nexport class LottieLoader {\r\n private isWebAssemblySupported = typeof(WebAssembly) !== 'undefined';\r\n private loadPromise: Promise<void> = !this.isWebAssemblySupported ? Promise.reject() : undefined;\r\n private loaded = false;\r\n\r\n private workersLimit = 4;\r\n private players: {[reqId: number]: RLottiePlayer} = {};\r\n\r\n private workers: QueryableWorker[] = [];\r\n private curWorkerNum = 0;\r\n\r\n private log = logger('LOTTIE', LogTypes.Error);\r\n\r\n public getAnimation(element: HTMLElement) {\r\n for(const i in this.players) {\r\n if(this.players[i].el === element) {\r\n return this.players[i];\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n public setLoop(loop: boolean) {\r\n for(const i in this.players) {\r\n const player = this.players[i];\r\n player.loop = loop;\r\n player.autoplay = player._autoplay;\r\n }\r\n }\r\n\r\n public loadLottieWorkers() {\r\n if(this.loadPromise) {\r\n return this.loadPromise;\r\n }\r\n\r\n return this.loadPromise = new Promise((resolve, reject) => {\r\n let remain = this.workersLimit;\r\n for(let i = 0; i < this.workersLimit; ++i) {\r\n const worker = this.workers[i] = new QueryableWorker(new RLottieWorker());\r\n\r\n worker.addEventListener('ready', () => {\r\n this.log('worker #' + i + ' ready');\r\n\r\n worker.addEventListener('frame', this.onFrame);\r\n worker.addEventListener('loaded', this.onPlayerLoaded);\r\n worker.addEventListener('error', this.onPlayerError);\r\n\r\n --remain;\r\n if(!remain) {\r\n this.log('workers ready');\r\n resolve();\r\n this.loaded = true;\r\n }\r\n }, {once: true});\r\n\r\n worker.addEventListener('workerError', (error) => {\r\n reject('rlottie load error: ' + error.message);\r\n this.loaded = false;\r\n }, {once: true});\r\n }\r\n });\r\n }\r\n\r\n public loadAnimationAsAsset(params: Omit<RLottieOptions, 'animationData' | 'name'>, name: LottieAssetName) {\r\n (params as RLottieOptions).name = name;\r\n return this.loadAnimationFromURL(params, 'assets/tgs/' + name + '.json');\r\n }\r\n\r\n public loadAnimationFromURL(params: Omit<RLottieOptions, 'animationData'>, url: string): Promise<RLottiePlayer> {\r\n if(!this.isWebAssemblySupported) {\r\n return this.loadPromise as any;\r\n }\r\n \r\n if(!this.loaded) {\r\n this.loadLottieWorkers();\r\n }\r\n\r\n return fetch(url)\r\n .then(res => {\r\n if(!res.headers || res.headers.get('content-type') === 'application/octet-stream') {\r\n return res.arrayBuffer().then(data => apiManager.invokeCrypto('gzipUncompress', data)).then(arr => blobConstruct([arr], ''))\r\n } else {\r\n return res.blob();\r\n }\r\n })\r\n /* .then(str => {\r\n return new Promise<string>((resolve) => setTimeout(() => resolve(str), 2e3));\r\n }) */\r\n .then(blob => {\r\n const newParams = Object.assign(params, {animationData: blob, needUpscale: true});\r\n if(!newParams.name) newParams.name = url;\r\n return this.loadAnimationWorker(newParams);\r\n });\r\n }\r\n\r\n public waitForFirstFrame(player: RLottiePlayer) {\r\n return Promise.race([\r\n /* new Promise<void>((resolve) => {\r\n player.addEventListener('firstFrame', () => {\r\n setTimeout(() => resolve(), 1500);\r\n }, true);\r\n }) */\r\n new Promise<void>((resolve) => {\r\n player.addEventListener('firstFrame', resolve, {once: true});\r\n }),\r\n pause(2500)\r\n ]).then(() => player);\r\n }\r\n\r\n public async loadAnimationWorker(params: RLottieOptions, group = params.group || '', middleware?: () => boolean): Promise<RLottiePlayer> {\r\n if(!this.isWebAssemblySupported) {\r\n return this.loadPromise as any;\r\n }\r\n //params.autoplay = true;\r\n\r\n if(!this.loaded) {\r\n await this.loadLottieWorkers();\r\n }\r\n\r\n if(middleware && !middleware()) {\r\n throw new Error('middleware');\r\n }\r\n\r\n if(!params.width || !params.height) {\r\n params.width = parseInt(params.container.style.width);\r\n params.height = parseInt(params.container.style.height);\r\n }\r\n\r\n if(!params.width || !params.height) {\r\n throw new Error('No size for sticker!');\r\n }\r\n\r\n params.group = group;\r\n\r\n const player = this.initPlayer(params.container, params);\r\n\r\n if(group !== 'none') {\r\n animationIntersector.addAnimation(player, group);\r\n }\r\n\r\n return player;\r\n }\r\n\r\n private onPlayerLoaded = (reqId: number, frameCount: number, fps: number) => {\r\n const rlPlayer = this.players[reqId];\r\n if(!rlPlayer) {\r\n this.log.warn('onPlayerLoaded on destroyed player:', reqId, frameCount);\r\n return;\r\n }\r\n\r\n this.log.debug('onPlayerLoaded');\r\n rlPlayer.onLoad(frameCount, fps);\r\n //rlPlayer.addListener('firstFrame', () => {\r\n //animationIntersector.addAnimation(player, group);\r\n //}, true);\r\n };\r\n\r\n private onFrame = (reqId: number, frameNo: number, frame: Uint8ClampedArray) => {\r\n const rlPlayer = this.players[reqId];\r\n if(!rlPlayer) {\r\n this.log.warn('onFrame on destroyed player:', reqId, frameNo);\r\n return;\r\n }\r\n\r\n if(rlPlayer.clamped !== undefined) {\r\n rlPlayer.clamped = frame;\r\n }\r\n \r\n rlPlayer.renderFrame(frame, frameNo);\r\n };\r\n\r\n private onPlayerError = (reqId: number, error: Error) => {\r\n const rlPlayer = this.players[reqId];\r\n if(rlPlayer) {\r\n // ! will need refactoring later, this is not the best way to remove the animation\r\n const animations = animationIntersector.getAnimations(rlPlayer.el);\r\n animations.forEach(animation => {\r\n animationIntersector.checkAnimation(animation, true, true);\r\n });\r\n }\r\n };\r\n\r\n public onDestroy(reqId: number) {\r\n delete this.players[reqId];\r\n }\r\n\r\n public destroyWorkers() {\r\n this.workers.forEach((worker, idx) => {\r\n worker.terminate();\r\n this.log('worker #' + idx + ' terminated');\r\n });\r\n\r\n this.log('workers destroyed');\r\n this.workers.length = 0;\r\n }\r\n\r\n private initPlayer(el: HTMLElement, options: RLottieOptions) {\r\n const rlPlayer = new RLottiePlayer({\r\n el, \r\n worker: this.workers[this.curWorkerNum++],\r\n options\r\n });\r\n\r\n this.players[rlPlayer.reqId] = rlPlayer;\r\n if(this.curWorkerNum >= this.workers.length) {\r\n this.curWorkerNum = 0;\r\n }\r\n\r\n rlPlayer.loadFromData(options.animationData);\r\n\r\n return rlPlayer;\r\n }\r\n}\r\n\r\nconst lottieLoader = new LottieLoader();\r\nMOUNT_CLASS_TO.lottieLoader = lottieLoader;\r\nexport default lottieLoader;\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 function numberThousandSplitter(x: number, joiner = ' ') {\r\n const parts = x.toString().split(\".\");\r\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, joiner);\r\n return parts.join(\".\");\r\n}\r\n\r\nexport function formatNumber(bytes: number, decimals = 2) {\r\n if(bytes === 0) return '0';\r\n\r\n const k = 1000;\r\n const dm = decimals < 0 ? 0 : decimals;\r\n const sizes = ['', 'K', 'M', 'B', 'T'];\r\n\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i];\r\n}\r\n\r\nexport function clamp(v: number, min: number, max: number): number {\r\n return v < min ? min : ((v > max) ? max : v);\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 rootScope from \"../lib/rootScope\";\r\nimport { IS_SAFARI } from \"../environment/userAgent\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"../helpers/dom/isInDOM\";\r\nimport { forEachReverse, indexOfAndSplice } from \"../helpers/array\";\r\nimport RLottiePlayer from \"../lib/rlottie/rlottiePlayer\";\r\n\r\nexport interface AnimationItem {\r\n el: HTMLElement,\r\n group: string,\r\n animation: RLottiePlayer | HTMLVideoElement\r\n};\r\n\r\nexport class AnimationIntersector {\r\n private observer: IntersectionObserver;\r\n private visible: Set<AnimationItem> = new Set();\r\n\r\n private overrideIdleGroups: Set<string>;\r\n private byGroups: {[group: string]: AnimationItem[]} = {};\r\n private lockedGroups: {[group: string]: true} = {};\r\n private onlyOnePlayableGroup: string = '';\r\n \r\n private intersectionLockedGroups: {[group: string]: true} = {};\r\n private videosLocked = false;\r\n\r\n constructor() {\r\n this.observer = new IntersectionObserver((entries) => {\r\n // if(rootScope.idle.isIDLE) return;\r\n\r\n for(const entry of entries) {\r\n const target = entry.target;\r\n\r\n for(const group in this.byGroups) {\r\n if(this.intersectionLockedGroups[group]) {\r\n continue;\r\n }\r\n\r\n const player = this.byGroups[group].find(p => p.el === target);\r\n if(player) {\r\n if(entry.isIntersecting) {\r\n this.visible.add(player);\r\n this.checkAnimation(player, false);\r\n } else {\r\n this.visible.delete(player);\r\n this.checkAnimation(player, true);\r\n\r\n if(player.animation instanceof RLottiePlayer/* && player.animation.cachingDelta === 2 */) {\r\n //console.warn('will clear cache', player);\r\n player.animation.clearCache();\r\n }\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n });\r\n\r\n this.overrideIdleGroups = new Set();\r\n\r\n rootScope.addEventListener('media_play', ({doc}) => {\r\n if(doc.type === 'round') {\r\n this.videosLocked = true;\r\n this.checkAnimations();\r\n }\r\n });\r\n\r\n rootScope.addEventListener('media_pause', () => {\r\n if(this.videosLocked) {\r\n this.videosLocked = false;\r\n this.checkAnimations();\r\n }\r\n });\r\n }\r\n\r\n public setOverrideIdleGroup(group: string, override: boolean) {\r\n if(override) this.overrideIdleGroups.add(group);\r\n else this.overrideIdleGroups.delete(group);\r\n }\r\n\r\n public getAnimations(element: HTMLElement) {\r\n const found: AnimationItem[] = [];\r\n for(const group in this.byGroups) {\r\n for(const player of this.byGroups[group]) {\r\n if(player.el === element) {\r\n found.push(player);\r\n }\r\n }\r\n }\r\n\r\n return found;\r\n }\r\n\r\n public removeAnimation(player: AnimationItem) {\r\n //console.log('destroy animation');\r\n const {el, animation} = player;\r\n animation.remove();\r\n\r\n if(animation instanceof HTMLVideoElement && IS_SAFARI) {\r\n setTimeout(() => { // TODO: очистка по очереди, а не все вместе с этим таймаутом\r\n animation.src = '';\r\n animation.load();\r\n }, 1e3);\r\n }\r\n\r\n const group = this.byGroups[player.group];\r\n if(group) {\r\n indexOfAndSplice(group, player);\r\n if(!group.length) {\r\n delete this.byGroups[player.group];\r\n }\r\n }\r\n \r\n this.observer.unobserve(el);\r\n this.visible.delete(player);\r\n }\r\n\r\n public addAnimation(animation: RLottiePlayer | HTMLVideoElement, group = '') {\r\n const player = {\r\n el: animation instanceof RLottiePlayer ? animation.el : animation, \r\n animation: animation, \r\n group\r\n };\r\n\r\n if(animation instanceof RLottiePlayer) {\r\n if(!rootScope.settings.stickers.loop && animation.loop) {\r\n animation.loop = rootScope.settings.stickers.loop;\r\n }\r\n }\r\n\r\n (this.byGroups[group] ?? (this.byGroups[group] = [])).push(player);\r\n this.observer.observe(player.el);\r\n }\r\n\r\n public checkAnimations(blurred?: boolean, group?: string, destroy = false) {\r\n // if(rootScope.idle.isIDLE) return;\r\n\r\n if(group !== undefined && !this.byGroups[group]) {\r\n //console.warn('no animation group:', group);\r\n return;\r\n }\r\n \r\n const groups = group !== undefined /* && false */ ? [group] : Object.keys(this.byGroups);\r\n\r\n for(const group of groups) {\r\n const animations = this.byGroups[group];\r\n\r\n forEachReverse(animations, (player) => {\r\n this.checkAnimation(player, blurred, destroy);\r\n });\r\n }\r\n }\r\n\r\n public checkAnimation(player: AnimationItem, blurred = false, destroy = false) {\r\n const {el, animation, group} = player;\r\n //return;\r\n if((destroy || (!isInDOM(el) && !this.lockedGroups[group]))/* && false */) {\r\n this.removeAnimation(player);\r\n return;\r\n }\r\n\r\n if(blurred || (this.onlyOnePlayableGroup && this.onlyOnePlayableGroup !== group) || (animation instanceof HTMLVideoElement && this.videosLocked)) {\r\n if(!animation.paused) {\r\n //console.warn('pause animation:', animation);\r\n animation.pause();\r\n }\r\n } else if(animation.paused && \r\n this.visible.has(player) && \r\n animation.autoplay && \r\n (!this.onlyOnePlayableGroup || this.onlyOnePlayableGroup === group) &&\r\n (!rootScope.idle.isIDLE || this.overrideIdleGroups.has(player.group))\r\n ) {\r\n //console.warn('play animation:', animation);\r\n animation.play();\r\n }\r\n }\r\n\r\n public setOnlyOnePlayableGroup(group: string) {\r\n this.onlyOnePlayableGroup = group;\r\n }\r\n\r\n public lockGroup(group: string) {\r\n this.lockedGroups[group] = true;\r\n }\r\n\r\n public unlockGroup(group: string) {\r\n delete this.lockedGroups[group];\r\n this.checkAnimations(undefined, group);\r\n }\r\n\r\n public refreshGroup(group: string) {\r\n const animations = this.byGroups[group];\r\n if(animations && animations.length) {\r\n animations.forEach(animation => {\r\n this.observer.unobserve(animation.el);\r\n });\r\n\r\n window.requestAnimationFrame(() => {\r\n animations.forEach(animation => {\r\n this.observer.observe(animation.el);\r\n });\r\n });\r\n }\r\n }\r\n\r\n public lockIntersectionGroup(group: string) {\r\n this.intersectionLockedGroups[group] = true;\r\n }\r\n\r\n public unlockIntersectionGroup(group: string) {\r\n delete this.intersectionLockedGroups[group];\r\n this.refreshGroup(group);\r\n }\r\n}\r\n\r\nconst animationIntersector = new AnimationIntersector();\r\nif(MOUNT_CLASS_TO) {\r\n MOUNT_CLASS_TO.animationIntersector = animationIntersector;\r\n}\r\nexport default animationIntersector;\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 Page from \"./page\";\r\nimport lottieLoader from \"../lib/rlottie/lottieLoader\";\r\nimport { horizontalMenu } from \"../components/horizontalMenu\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport whichChild from \"../helpers/dom/whichChild\";\r\n\r\nclass PagesManager {\r\n private pageId = -1;\r\n private page: Page;\r\n\r\n private selectTab: ReturnType<typeof horizontalMenu>;\r\n public pagesDiv: HTMLDivElement;\r\n public scrollableDiv: HTMLElement;\r\n\r\n constructor() {\r\n this.pagesDiv = document.getElementById('auth-pages') as HTMLDivElement;\r\n this.scrollableDiv = this.pagesDiv.querySelector('.scrollable') as HTMLElement;\r\n this.selectTab = horizontalMenu(null, this.scrollableDiv.querySelector('.tabs-container') as HTMLDivElement, null, () => {\r\n if(this.page?.onShown) {\r\n this.page.onShown();\r\n }\r\n });\r\n }\r\n\r\n public setPage(page: Page) {\r\n if(page.isAuthPage) {\r\n this.pagesDiv.style.display = '';\r\n\r\n let id = whichChild(page.pageEl);\r\n if(this.pageId === id) return;\r\n\r\n this.selectTab(id);\r\n\r\n if(this.pageId !== -1 && id > 1) {\r\n lottieLoader.loadLottieWorkers();\r\n }\r\n\r\n\r\n\r\n this.pageId = id;\r\n\r\n if(this.scrollableDiv) {\r\n fastSmoothScroll({\r\n container: this.scrollableDiv, \r\n element: this.scrollableDiv.firstElementChild as HTMLElement, \r\n position: 'start'\r\n });\r\n }\r\n } else {\r\n this.pagesDiv.style.display = 'none';\r\n page.pageEl.style.display = '';\r\n\r\n this.pageId = -1;\r\n }\r\n\r\n this.page = page;\r\n }\r\n}\r\n\r\nconst pagesManager = new PagesManager();\r\nMOUNT_CLASS_TO.pagesManager = pagesManager;\r\nexport default pagesManager;\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 pagesManager from \"./pagesManager\";\r\n\r\nexport default class Page {\r\n public pageEl: HTMLDivElement;\r\n private installed = false;\r\n\r\n constructor(className: string, public isAuthPage: boolean, private onFirstMount?: (...args: any[]) => Promise<any> | void, private onMount?: (...args: any[]) => void, public onShown?: () => void) {\r\n this.pageEl = document.body.querySelector('.' + className) as HTMLDivElement;\r\n }\r\n\r\n public async mount(...args: any[]) {\r\n //this.pageEl.style.display = '';\r\n\r\n if(this.onMount) {\r\n this.onMount(...args);\r\n }\r\n\r\n if(!this.installed) {\r\n if(this.onFirstMount) {\r\n try {\r\n const res = this.onFirstMount(...args);\r\n if(res instanceof Promise) {\r\n await res;\r\n }\r\n } catch(err) {\r\n console.error('PAGE MOUNT ERROR:', err);\r\n }\r\n }\r\n \r\n this.installed = true;\r\n }\r\n\r\n pagesManager.setPage(this);\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\n// * Jolly Cobra's useHeavyAnimationCheck.ts, patched\r\n\r\nimport { AnyToVoidFunction } from '../types';\r\nimport ListenerSetter from '../helpers/listenerSetter';\r\nimport { CancellablePromise, deferredPromise } from '../helpers/cancellablePromise';\r\nimport rootScope from '../lib/rootScope';\r\nimport DEBUG from '../config/debug';\r\nimport { pause } from '../helpers/schedulers/pause';\r\n\r\nconst ANIMATION_START_EVENT = 'event-heavy-animation-start';\r\nconst ANIMATION_END_EVENT = 'event-heavy-animation-end';\r\n\r\nlet isAnimating = false;\r\nlet heavyAnimationPromise: CancellablePromise<void> = deferredPromise<void>();\r\nlet promisesInQueue = 0;\r\n\r\nheavyAnimationPromise.resolve();\r\n\r\nconst log = console.log.bind(console.log, '[HEAVY-ANIMATION]:');\r\n\r\nexport function dispatchHeavyAnimationEvent(promise: Promise<any>, timeout?: number) {\r\n if(!isAnimating) {\r\n heavyAnimationPromise = deferredPromise<void>();\r\n rootScope.dispatchEvent(ANIMATION_START_EVENT);\r\n isAnimating = true;\r\n DEBUG && log('start');\r\n }\r\n \r\n ++promisesInQueue;\r\n DEBUG && log('attach promise, length:', promisesInQueue, timeout);\r\n\r\n const promises = [\r\n timeout !== undefined ? pause(timeout) : undefined,\r\n promise.finally(() => {})\r\n ].filter(Boolean);\r\n\r\n const perf = performance.now();\r\n const _heavyAnimationPromise = heavyAnimationPromise;\r\n Promise.race(promises).then(() => {\r\n if(heavyAnimationPromise !== _heavyAnimationPromise || heavyAnimationPromise.isFulfilled) { // interrupted\r\n return;\r\n }\r\n\r\n --promisesInQueue;\r\n DEBUG && log('promise end, length:', promisesInQueue, performance.now() - perf);\r\n if(promisesInQueue <= 0) {\r\n onHeavyAnimationEnd();\r\n }\r\n });\r\n\r\n return heavyAnimationPromise;\r\n}\r\n\r\nfunction onHeavyAnimationEnd() {\r\n if(heavyAnimationPromise.isFulfilled) {\r\n return;\r\n }\r\n\r\n isAnimating = false;\r\n promisesInQueue = 0;\r\n rootScope.dispatchEvent(ANIMATION_END_EVENT);\r\n heavyAnimationPromise.resolve();\r\n\r\n DEBUG && log('end');\r\n}\r\n\r\nexport function interruptHeavyAnimation() {\r\n onHeavyAnimationEnd();\r\n}\r\n\r\nexport function getHeavyAnimationPromise() {\r\n return heavyAnimationPromise;\r\n}\r\n\r\nexport default function(\r\n handleAnimationStart: AnyToVoidFunction,\r\n handleAnimationEnd: AnyToVoidFunction,\r\n listenerSetter?: ListenerSetter\r\n) {\r\n //useEffect(() => {\r\n if(isAnimating) {\r\n handleAnimationStart();\r\n }\r\n\r\n const add = listenerSetter ? listenerSetter.add(rootScope) : rootScope.addEventListener.bind(rootScope);\r\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, rootScope) : rootScope.removeEventListener.bind(rootScope);\r\n add(ANIMATION_START_EVENT, handleAnimationStart);\r\n add(ANIMATION_END_EVENT, handleAnimationEnd);\r\n\r\n return () => {\r\n remove(ANIMATION_END_EVENT, handleAnimationEnd);\r\n remove(ANIMATION_START_EVENT, handleAnimationStart);\r\n };\r\n //}, [handleAnimationEnd, handleAnimationStart]);\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// * Jolly Cobra's fastSmoothScroll slightly patched\r\n\r\nimport { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';\r\nimport { fastRaf } from './schedulers';\r\nimport { animateSingle, cancelAnimationByKey } from './animation';\r\nimport rootScope from '../lib/rootScope';\r\nimport isInDOM from './dom/isInDOM';\r\n\r\nconst MIN_JS_DURATION = 250;\r\nconst MAX_JS_DURATION = 600;\r\nconst LONG_TRANSITION_MAX_DISTANCE = 1500;\r\nconst SHORT_TRANSITION_MAX_DISTANCE = 500;\r\n\r\nexport enum FocusDirection {\r\n Up,\r\n Down,\r\n Static,\r\n};\r\n\r\nexport type ScrollGetNormalSizeCallback = (options: {rect: DOMRect}) => number;\r\n\r\nexport type ScrollOptions = {\r\n container: HTMLElement,\r\n element: HTMLElement,\r\n position: ScrollLogicalPosition,\r\n margin?: number,\r\n maxDistance?: number,\r\n forceDirection?: FocusDirection,\r\n forceDuration?: number,\r\n axis?: 'x' | 'y',\r\n getNormalSize?: ScrollGetNormalSizeCallback,\r\n fallbackToElementStartWhenCentering?: HTMLElement\r\n};\r\n\r\nexport default function fastSmoothScroll(options: ScrollOptions) {\r\n if(options.margin === undefined) {\r\n options.margin = 0;\r\n }\r\n\r\n if(options.maxDistance === undefined) {\r\n options.maxDistance = LONG_TRANSITION_MAX_DISTANCE;\r\n }\r\n\r\n if(options.axis === undefined) {\r\n options.axis = 'y';\r\n }\r\n //return;\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n options.forceDirection = FocusDirection.Static;\r\n }\r\n\r\n if(options.forceDirection === FocusDirection.Static) {\r\n options.forceDuration = 0;\r\n return scrollWithJs(options);\r\n /* return Promise.resolve();\r\n\r\n element.scrollIntoView({ block: position });\r\n\r\n cancelAnimationByKey(container);\r\n return Promise.resolve(); */\r\n }\r\n\r\n const promise = new Promise<void>((resolve) => {\r\n fastRaf(() => {\r\n scrollWithJs(options).then(resolve);\r\n });\r\n });\r\n\r\n return options.axis === 'y' ? dispatchHeavyAnimationEvent(promise) : promise;\r\n}\r\n\r\nfunction scrollWithJs(options: ScrollOptions): Promise<void> {\r\n const {element, container, getNormalSize, axis, margin, position, forceDirection, maxDistance, forceDuration} = options;\r\n if(!isInDOM(element)) {\r\n cancelAnimationByKey(container);\r\n return Promise.resolve();\r\n }\r\n \r\n const rectStartKey = axis === 'y' ? 'top' : 'left';\r\n const rectEndKey = axis === 'y' ? 'bottom' : 'right';\r\n const sizeKey = axis === 'y' ? 'height' : 'width';\r\n const scrollSizeKey = axis === 'y' ? 'scrollHeight' : 'scrollWidth';\r\n const scrollPositionKey = axis === 'y' ? 'scrollTop' : 'scrollLeft';\r\n\r\n //const { offsetTop: elementTop, offsetHeight: elementHeight } = element;\r\n const elementRect = element.getBoundingClientRect();\r\n const containerRect = container.getBoundingClientRect ? container.getBoundingClientRect() : document.body.getBoundingClientRect();\r\n\r\n //const transformable = container.firstElementChild as HTMLElement;\r\n\r\n const elementPosition = elementRect[rectStartKey] - containerRect[rectStartKey];\r\n const elementSize = element[scrollSizeKey]; // margin is exclusive in DOMRect\r\n\r\n const containerSize = getNormalSize ? getNormalSize({rect: containerRect}) : containerRect[sizeKey];\r\n\r\n let scrollPosition = container[scrollPositionKey];\r\n const scrollSize = container[scrollSizeKey];\r\n /* const elementPosition = element.offsetTop;\r\n const elementSize = element.offsetHeight;\r\n\r\n const scrollPosition = container[scrollPositionKey];\r\n const scrollSize = container[scrollSizeKey];\r\n const containerSize = container.offsetHeight; */\r\n\r\n let path!: number;\r\n\r\n switch(position) {\r\n case 'start':\r\n path = elementPosition - margin;\r\n break;\r\n case 'end':\r\n path = elementRect[rectEndKey] /* + (elementSize - elementRect[sizeKey]) */ - containerRect[rectEndKey] + margin;\r\n break;\r\n // 'nearest' is not supported yet\r\n case 'nearest':\r\n case 'center':\r\n if(elementSize < containerSize) {\r\n path = (elementPosition + elementSize / 2) - (containerSize / 2);\r\n } else {\r\n if(options.fallbackToElementStartWhenCentering && options.fallbackToElementStartWhenCentering !== element) {\r\n options.element = options.fallbackToElementStartWhenCentering;\r\n options.position = 'start';\r\n return scrollWithJs(options);\r\n }\r\n\r\n path = elementPosition - margin;\r\n }\r\n\r\n break;\r\n }\r\n /* switch (position) {\r\n case 'start':\r\n path = (elementPosition - margin) - scrollPosition;\r\n break;\r\n case 'end':\r\n path = (elementPosition + elementSize + margin) - (scrollPosition + containerSize);\r\n break;\r\n // 'nearest' is not supported yet\r\n case 'nearest':\r\n case 'center':\r\n path = elementSize < containerSize\r\n ? (elementPosition + elementSize / 2) - (scrollPosition + containerSize / 2)\r\n : (elementPosition - margin) - scrollPosition;\r\n break;\r\n } */\r\n\r\n if(Math.abs(path - (margin || 0)) < 1) {\r\n cancelAnimationByKey(container);\r\n return Promise.resolve();\r\n }\r\n\r\n if(axis === 'y') {\r\n if(forceDirection === undefined) {\r\n if(path > maxDistance) {\r\n scrollPosition = container.scrollTop += path - maxDistance;\r\n path = maxDistance;\r\n } else if(path < -maxDistance) {\r\n scrollPosition = container.scrollTop += path + maxDistance;\r\n path = -maxDistance;\r\n }\r\n }/* else if(forceDirection === FocusDirection.Up) { // * not tested yet\r\n container.scrollTop = offsetTop + container.scrollTop + maxDistance;\r\n } else if(forceDirection === FocusDirection.Down) { // * not tested yet\r\n container.scrollTop = Math.max(0, offsetTop + container.scrollTop - maxDistance);\r\n } */\r\n }\r\n\r\n // console.log('scrollWithJs: will scroll path:', path, element);\r\n\r\n /* let existsTransform = 0;\r\n const currentTransform = transformable.style.transform;\r\n if(currentTransform) {\r\n existsTransform = parseInt(currentTransform.match(/\\((.+?), (.+?), .+\\)/)[2]);\r\n //path += existsTransform;\r\n } */\r\n\r\n if(path < 0) {\r\n const remainingPath = -scrollPosition;\r\n path = Math.max(path, remainingPath);\r\n } else if(path > 0) {\r\n const remainingPath = scrollSize - (scrollPosition + containerSize);\r\n path = Math.min(path, remainingPath);\r\n }\r\n\r\n const target = container[scrollPositionKey] + path;\r\n const absPath = Math.abs(path);\r\n const duration = forceDuration ?? (\r\n MIN_JS_DURATION + (absPath / LONG_TRANSITION_MAX_DISTANCE) * (MAX_JS_DURATION - MIN_JS_DURATION)\r\n );\r\n const startAt = Date.now();\r\n\r\n /* transformable.classList.add('no-transition');\r\n\r\n const tickTransform = () => {\r\n const t = duration ? Math.min((Date.now() - startAt) / duration, 1) : 1;\r\n const currentPath = path * transition(t);\r\n\r\n transformable.style.transform = `translate3d(0, ${-currentPath}px, 0)`;\r\n container.dataset.translate = '' + -currentPath;\r\n\r\n const willContinue = t < 1;\r\n if(!willContinue) {\r\n fastRaf(() => {\r\n delete container.dataset.transform;\r\n container.dataset.transform = '';\r\n transformable.style.transform = '';\r\n void transformable.offsetLeft; // reflow\r\n transformable.classList.remove('no-transition');\r\n void transformable.offsetLeft; // reflow\r\n container[scrollPositionKey] = Math.round(target);\r\n });\r\n }\r\n\r\n return willContinue;\r\n };\r\n \r\n return animateSingle(tickTransform, container); */\r\n\r\n /* return new Promise((resolve) => {\r\n fastRaf(() => {\r\n transformable.style.transform = '';\r\n transformable.style.transition = '';\r\n\r\n setTimeout(resolve, duration);\r\n });\r\n });\r\n\r\n const transformableHeight = transformable.scrollHeight;\r\n //transformable.style.minHeight = `${transformableHeight}px`;\r\n */\r\n\r\n const transition = absPath < SHORT_TRANSITION_MAX_DISTANCE ? shortTransition : longTransition;\r\n const tick = () => {\r\n const t = duration ? Math.min((Date.now() - startAt) / duration, 1) : 1;\r\n\r\n const currentPath = path * (1 - transition(t));\r\n container[scrollPositionKey] = Math.round(target - currentPath);\r\n \r\n return t < 1;\r\n };\r\n\r\n if(!duration || !path) {\r\n cancelAnimationByKey(container);\r\n tick();\r\n return Promise.resolve();\r\n }\r\n\r\n /* return new Promise((resolve) => {\r\n setTimeout(resolve, duration);\r\n }).then(() => {\r\n transformable.classList.add('no-transition');\r\n void transformable.offsetLeft; // reflow\r\n transformable.style.transform = '';\r\n transformable.style.transition = '';\r\n void transformable.offsetLeft; // reflow\r\n transformable.classList.remove('no-transition');\r\n void transformable.offsetLeft; // reflow\r\n fastRaf(() => {\r\n \r\n container[scrollPositionKey] = Math.round(target);\r\n //transformable.style.minHeight = ``;\r\n });\r\n \r\n }); */\r\n\r\n return animateSingle(tick, container);\r\n}\r\n\r\nfunction longTransition(t: number) {\r\n return 1 - ((1 - t) ** 5);\r\n}\r\n\r\nfunction shortTransition(t: number) {\r\n return 1 - ((1 - t) ** 3.5);\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 <igor.beatle@gmail.com>\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\nexport default function whichChild(elem: Node) {\r\n if(!elem.parentNode) {\r\n return -1;\r\n }\r\n \r\n let i = 0;\r\n // @ts-ignore\r\n while((elem = elem.previousElementSibling) !== null) ++i;\r\n return i;\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\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"],"sourceRoot":""} |