{"version":3,"sources":["webpack:///./src/pages/loginPage.ts","webpack:///./src/helpers/dom/fullScreen.ts","webpack:///./src/helpers/blob/readBlobAsUint8Array.ts","webpack:///./src/helpers/blob/readBlobAsArrayBuffer.ts","webpack:///./src/lib/fileManager.ts","webpack:///./src/lib/cacheStorage.ts","webpack:///./src/helpers/fileName.ts","webpack:///./src/lib/cropper.ts","webpack:///./src/components/popups/avatar.ts","webpack:///./src/helpers/dom/isSendShortcutPressed.ts","webpack:///./src/helpers/blob/readBlobAsDataURL.ts","webpack:///./src/pages/pageSignUp.ts","webpack:///./src/helpers/dom/replaceContent.ts","webpack:///./src/components/inputField.ts","webpack:///./src/helpers/dom/selectElementContents.ts","webpack:///./src/components/singleTransition.ts","webpack:///./src/components/popups/index.ts","webpack:///./src/helpers/dom/getRichValue.ts","webpack:///./src/helpers/listenerSetter.ts","webpack:///./src/helpers/dom/findUpAttribute.ts","webpack:///./src/helpers/dom/getRichElementValue.ts","webpack:///./src/lib/appManagers/appDownloadManager.ts","webpack:///./src/helpers/dom/isInputEmpty.ts","webpack:///./src/helpers/blob/readBlobAs.ts"],"names":["LoginPage","options","this","element","document","body","querySelector","className","container","createElement","imageDiv","title","titleLangKey","append","subtitle","subtitleLangKey","withInputWrapper","inputWrapper","requestFullScreen","requestFullscreen","mozRequestFullScreen","webkitRequestFullscreen","msRequestFullscreen","cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen","msExitFullscreen","addFullScreenListener","callback","listenerSetter","addListener","add","addEventListener","bind","split","forEach","eventName","getFullScreenElement","fullscreenElement","mozFullScreenElement","webkitFullscreenElement","msFullscreenElement","isFullScreen","readBlobAsUint8Array","blob","readBlobAs","readBlobAsArrayBuffer","then","buffer","Uint8Array","blobSupported","blobConstruct","e","fileWriter","bytes","Blob","arr","write","mimeType","saveFileCallback","blobParts","part","push","truncate","length","finalize","saveToStorage","dbName","useStorage","test","STORAGES","openDatabase","openDbPromise","caches","open","entryName","timeoutOperation","cache","delete","match","response","put","fileName","method","get","Response","headers","size","save","Promise","resolve","reject","rejected","timeout","setTimeout","undefined","res","err","clearTimeout","fakeWriter","getFakeFileWriter","saveFile","catch","enabled","all","map","storage","deleteAll","getFileNameByLocation","location","ext","str","_","id","thumb_size","filter","Boolean","join","photo_id","pFlags","big","stickerset","short_name","emoticon","thumb_version","volume_id","local_id","url","console","error","getFileURL","type","encodeURIComponent","JSON","stringify","originalImage","canvas","cropComponent","cropImage","event_state","cropLeft","cropTop","cropWidth","cropHeight","scaledRatio","init","classList","draggable","Image","src","overlayColor","appendChild","parentNode","style","maxWidth","width","naturalWidth","offsetWidth","left","CROPWIDTH","top","offsetHeight","CROPHEIGHT","updateCropSize","updateCropImage","updateContainer","startMoving","resizing","keyHandler","height","imgZoom","zoom","Math","PI","right","bottom","newWidth","floor","clientWidth","newHeight","clientHeight","w","h","offsetLeft","offsetTop","preventDefault","String","fromCharCode","charCode","deltaY","stopPropagation","container_width","container_height","container_left","container_top","mouse_x","clientX","pageX","touches","window","scrollX","mouse_y","clientY","pageY","scrollY","saveEventState","moving","endMoving","removeEventListener","currentTouch","x","y","complete","onload","crop","getContext","drawImage","removeHandlers","remove","super","closable","withConfirm","image","cropper","h6","btnClose","header","cropContainer","input","display","file","target","files","readBlobAsDataURL","contents","show","value","btnConfirm","hide","toBlob","darkenCanvas","onCrop","appDownloadManager","upload","postCanvas","click","ctx","fillStyle","fillRect","isSendShortcutPressed","key","isComposing","settings","sendShortcut","shiftKey","ctrlKey","metaKey","secondaryKey","authCode","page","imported","avatarPreview","addIco","appProfileManager","default","uploadAvatar","_uploadAvatar","handleInput","name","nameInputField","lastName","lastNameInputField","fullName","trim","wrapEmojiText","label","maxLength","btnSignUp","btnI18n","IntlElement","contains","disabled","params","phone_number","phone_code_hash","first_name","last_name","update","preloader","invokeApi","setUser","user","inputFile","uploadProfilePhoto","finally","m","mount","removeAttribute","requestAnimationFrame","_authCode","pushToState","replaceContent","elem","node","innerHTML","firstChild","lastChild","replaceWith","textContent","findUpAttribute","text","entities","plainText","originalEvent","clipboardData","getData","usePlainText","html","replace","span","curChild","nextSibling","nodeType","nodeValue","richValue","getRichValue","entities2","parseEntities","mergeEntities","wrapDraftText","execCommand","InputState","required","validate","showLengthOn","min","round","placeholder","canBeEdited","processInput","labelText","firstElementChild","observer","MutationObserver","isInputEmpty","inputFake","onFakeInput","observe","characterData","childList","subtree","animate","setAttribute","border","setLabel","labelEl","lastElementChild","showingLength","wasError","inputLength","diff","isError","toggle","select","el","range","createRange","selectNodeContents","sel","getSelection","removeAllRanges","addRange","selectElementContents","labelOptions","setHeight","scrollHeight","currentHeight","transitionDuration","log","abs","setValueSilently","fireFakeInput","originalValue","isValid","isChanged","silent","setDraftValue","state","Error","Valid","setState","SetTransition","forwards","duration","onTransitionEnd","useRafs","raf","dataset","cancelAnimationFrame","animationsEnabled","afterTimeout","DEFAULT_APPEND_TO","appendPopupTo","onFullScreenChange","PopupElement","reAppend","buttons","onEscape","backByItem","navigationItem","confirmShortcutIsSendShortcut","prepend","once","withoutOverlay","overlayClosable","btnConfirmOnEnter","buttonsDiv","buttonsEl","buttonsElements","b","button","isDanger","langKey","langArgs","destroy","find","isCancel","POPUPS","onPop","pushItem","isOverlayActive","checkAnimations","dispatchEvent","removeAll","removeItem","cleanup","popup","parentElement","popupConstructor","addCancelButton","field","withEntities","lines","line","combineSameEntities","sortEntities","ListenerSetter","listeners","Set","event","listener","addManual","onceCallback","onceFired","_listener","attribute","closest","markdownTags","bold","entityName","underline","italic","monospace","strikethrough","link","mentionName","spoiler","BLOCK_TAG_NAMES","getRichElementValue","selNode","selOffset","offset","substr","tag","getAttribute","href","user_id","follow","toUserId","isSelected","isBlock","has","tagName","splice","HTMLImageElement","alt","isTableCell","matches","wasEntitiesLength","i","wasLength","cacheStorage","downloads","progress","progressCallbacks","uploadId","thumbsCache","photo","details","callbacks","download","notifyAll","deferred","cancel","cancelDownload","clearDownload","getNewDeferred","fetch","hasOwnProperty","onError","worker","onlyCache","promise","getFile","downloadFile","tryDownload","indexOf","uploadFile","onRemove","a","position","clickEvent","createEvent","initMouseEvent","discFileName","objectURL","URL","createObjectURL","createDownloadAnchor","revokeObjectURL","media","thumbSize","downloaded","hasAttribute","reader","FileReader","result"],"mappings":"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","file":"14.c002dd02cdb9afb66e64.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\nimport { LangPackKey, i18n } from \"../lib/langPack\";\r\n\r\nexport default class LoginPage {\r\n public element: HTMLElement;\r\n public container: HTMLElement;\r\n public imageDiv: HTMLElement;\r\n public inputWrapper: HTMLElement;\r\n public title: HTMLElement;\r\n public subtitle: HTMLParagraphElement;\r\n\r\n constructor(options: {\r\n className: string,\r\n withInputWrapper?: boolean,\r\n titleLangKey?: LangPackKey,\r\n subtitleLangKey?: LangPackKey,\r\n }) {\r\n this.element = document.body.querySelector('.' + options.className) as HTMLDivElement;\r\n //this.element = document.createElement('div');\r\n //this.element.className = 'page-' + options.className;\r\n\r\n this.container = document.createElement('div');\r\n this.container.className = 'container center-align';\r\n\r\n this.imageDiv = document.createElement('div');\r\n this.imageDiv.className = 'auth-image';\r\n\r\n this.title = document.createElement('h4');\r\n if(options.titleLangKey) {\r\n this.title.append(i18n(options.titleLangKey));\r\n }\r\n\r\n this.subtitle = document.createElement('p');\r\n this.subtitle.className = 'subtitle';\r\n if(options.subtitleLangKey) {\r\n this.subtitle.append(i18n(options.subtitleLangKey));\r\n }\r\n \r\n this.container.append(this.imageDiv, this.title, this.subtitle);\r\n\r\n if(options.withInputWrapper) {\r\n this.inputWrapper = document.createElement('div');\r\n this.inputWrapper.className = 'input-wrapper';\r\n this.container.append(this.inputWrapper);\r\n }\r\n\r\n this.element.append(this.container);\r\n }\r\n}\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ListenerSetter from \"../listenerSetter\";\n\nexport function requestFullScreen(element: HTMLElement) {\n if(element.requestFullscreen) {\n element.requestFullscreen();\n // @ts-ignore\n } else if(element.mozRequestFullScreen) {\n // @ts-ignore\n element.mozRequestFullScreen(); // Firefox\n // @ts-ignore\n } else if(element.webkitRequestFullscreen) {\n // @ts-ignore\n element.webkitRequestFullscreen(); // Chrome and Safari\n // @ts-ignore\n } else if(element.msRequestFullscreen) {\n // @ts-ignore\n element.msRequestFullscreen();\n }\n}\n\nexport function cancelFullScreen() {\n // @ts-ignore\n if(document.cancelFullScreen) {\n // @ts-ignore\n document.cancelFullScreen();\n // @ts-ignore\n } else if(document.mozCancelFullScreen) {\n // @ts-ignore\n document.mozCancelFullScreen();\n // @ts-ignore\n } else if(document.webkitCancelFullScreen) {\n // @ts-ignore\n document.webkitCancelFullScreen();\n // @ts-ignore\n } else if(document.msExitFullscreen) {\n // @ts-ignore\n document.msExitFullscreen();\n }\n}\n\nexport function addFullScreenListener(element: HTMLElement, callback: (e: Event) => any, listenerSetter?: ListenerSetter) {\n const addListener = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\n 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'.split(' ').forEach(eventName => {\n addListener(eventName, callback, false);\n });\n}\n\nexport function getFullScreenElement(): HTMLElement {\n // @ts-ignore\n return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;\n}\n\nexport function isFullScreen() {\n return !!getFullScreenElement();\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 readBlobAsArrayBuffer from \"./readBlobAsArrayBuffer\";\n\nexport default function readBlobAsUint8Array(blob: Blob) {\n return readBlobAsArrayBuffer(blob).then(buffer => new Uint8Array(buffer));\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 readBlobAs from \"./readBlobAs\";\n\nexport default function readBlobAsArrayBuffer(blob: Blob) {\n return readBlobAs(blob, 'readAsArrayBuffer');\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 * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov \r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport blobConstruct from \"../helpers/blob/blobConstruct\";\r\nimport readBlobAsUint8Array from \"../helpers/blob/readBlobAsUint8Array\";\r\n\r\nexport class FileManager {\r\n private blobSupported = true;\r\n \r\n constructor() {\r\n try {\r\n blobConstruct([], '');\r\n } catch(e) {\r\n this.blobSupported = false;\r\n }\r\n }\r\n \r\n public isAvailable() {\r\n return this.blobSupported;\r\n }\r\n \r\n public write(fileWriter: ReturnType, bytes: Uint8Array | Blob | string): Promise {\r\n if(bytes instanceof Blob) { // is file bytes\r\n return readBlobAsUint8Array(bytes).then(arr => {\r\n return fileWriter.write(arr);\r\n });\r\n } else {\r\n return fileWriter.write(bytes);\r\n }\r\n }\r\n\r\n public getFakeFileWriter(mimeType: string, saveFileCallback?: (blob: Blob) => Promise) {\r\n const blobParts: Array = [];\r\n const fakeFileWriter = {\r\n write: async(part: Uint8Array | string) => {\r\n if(!this.blobSupported) {\r\n throw false;\r\n }\r\n \r\n blobParts.push(part);\r\n },\r\n truncate: () => {\r\n blobParts.length = 0;\r\n },\r\n finalize: (saveToStorage = true) => {\r\n const blob = blobConstruct(blobParts, mimeType);\r\n\r\n if(saveToStorage && saveFileCallback) {\r\n saveFileCallback(blob);\r\n }\r\n \r\n return blob;\r\n }\r\n };\r\n \r\n return fakeFileWriter;\r\n }\r\n}\r\n\r\nexport default new FileManager();\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport Modes from '../config/modes';\r\nimport blobConstruct from '../helpers/blob/blobConstruct';\r\nimport FileManager from './fileManager';\r\n//import { MOUNT_CLASS_TO } from './mtproto/mtproto_config';\r\n//import { logger } from './polyfill';\r\n\r\nexport type CacheStorageDbName = 'cachedFiles' | 'cachedStreamChunks' | 'cachedAssets';\r\n\r\nexport default class CacheStorageController {\r\n private static STORAGES: CacheStorageController[] = [];\r\n private openDbPromise: Promise;\r\n\r\n private useStorage = true;\r\n\r\n //private log: ReturnType = logger('CS');\r\n\r\n constructor(private dbName: CacheStorageDbName) {\r\n if(Modes.test) {\r\n this.dbName += '_test';\r\n }\r\n\r\n if(CacheStorageController.STORAGES.length) {\r\n this.useStorage = CacheStorageController.STORAGES[0].useStorage;\r\n }\r\n \r\n this.openDatabase();\r\n CacheStorageController.STORAGES.push(this);\r\n }\r\n\r\n private openDatabase(): Promise {\r\n return this.openDbPromise ?? (this.openDbPromise = caches.open(this.dbName));\r\n }\r\n\r\n public delete(entryName: string) {\r\n return this.timeoutOperation((cache) => cache.delete('/' + entryName));\r\n }\r\n\r\n public deleteAll() {\r\n return caches.delete(this.dbName);\r\n }\r\n\r\n public get(entryName: string) {\r\n return this.timeoutOperation((cache) => cache.match('/' + entryName));\r\n }\r\n\r\n public save(entryName: string, response: Response) {\r\n // return new Promise((resolve) => {}); // DEBUG\r\n return this.timeoutOperation((cache) => cache.put('/' + entryName, response));\r\n }\r\n\r\n public getFile(fileName: string, method: 'blob' | 'json' | 'text' = 'blob'): Promise {\r\n /* if(method === 'blob') {\r\n return Promise.reject();\r\n } */\r\n\r\n // const str = `get fileName: ${fileName}`;\r\n // console.time(str);\r\n return this.get(fileName).then((response) => {\r\n if(!response) {\r\n //console.warn('getFile:', response, fileName);\r\n throw 'NO_ENTRY_FOUND';\r\n }\r\n\r\n const promise = response[method]();\r\n // promise.then(() => {\r\n // console.timeEnd(str);\r\n // });\r\n return promise;\r\n });\r\n }\r\n\r\n public saveFile(fileName: string, blob: Blob | Uint8Array) {\r\n //return Promise.resolve(blobConstruct([blob]));\r\n if(!(blob instanceof Blob)) {\r\n blob = blobConstruct(blob) as Blob;\r\n }\r\n\r\n const response = new Response(blob, {\r\n headers: {\r\n 'Content-Length': '' + blob.size\r\n }\r\n });\r\n \r\n return this.save(fileName, response).then(() => blob as Blob);\r\n }\r\n\r\n public timeoutOperation(callback: (cache: Cache) => Promise) {\r\n if(!this.useStorage) {\r\n return Promise.reject('STORAGE_OFFLINE');\r\n }\r\n\r\n return new Promise(async(resolve, reject) => {\r\n let rejected = false;\r\n const timeout = setTimeout(() => {\r\n reject();\r\n //console.warn('CACHESTORAGE TIMEOUT');\r\n rejected = true;\r\n }, 15e3);\r\n\r\n try {\r\n const cache = await this.openDatabase();\r\n if(!cache) {\r\n this.useStorage = false;\r\n this.openDbPromise = undefined;\r\n throw 'no cache?';\r\n }\r\n\r\n const res = await callback(cache);\r\n\r\n if(rejected) return;\r\n resolve(res);\r\n } catch(err) {\r\n reject(err);\r\n }\r\n\r\n clearTimeout(timeout);\r\n });\r\n }\r\n\r\n public getFileWriter(fileName: string, mimeType: string) {\r\n const fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => {\r\n return this.saveFile(fileName, blob).catch(() => blob);\r\n });\r\n\r\n return Promise.resolve(fakeWriter);\r\n }\r\n\r\n public static toggleStorage(enabled: boolean) {\r\n return Promise.all(this.STORAGES.map(storage => {\r\n storage.useStorage = enabled;\r\n \r\n if(!enabled) {\r\n return storage.deleteAll();\r\n }\r\n }));\r\n }\r\n}\r\n\r\n//const cacheStorage = new CacheStorageController(); \r\n//MOUNT_CLASS_TO.cacheStorage = cacheStorage;\r\n//export default cacheStorage;\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 type { InputFileLocation, InputStickerSet, InputWebFileLocation } from \"../layer\";\r\nimport type { DownloadOptions } from \"../lib/mtproto/apiFileManager\";\r\n\r\nconst FILENAME_JOINER = '_';\r\n\r\nexport function getFileNameByLocation(location: InputFileLocation | InputWebFileLocation, options?: Partial<{\r\n fileName: string\r\n}>) {\r\n const fileName = '';//(options?.fileName || '').split('.');\r\n const ext = fileName[fileName.length - 1] || '';\r\n\r\n let str: string;\r\n switch(location._) {\r\n case 'inputPhotoFileLocation': {\r\n str = ['photo', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n case 'inputDocumentFileLocation': {\r\n str = ['document', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n case 'inputPeerPhotoFileLocation':\r\n str = ['peerPhoto', location.photo_id, location.pFlags.big ? 'big' : 'small'].join(FILENAME_JOINER);\r\n break;\r\n \r\n case 'inputStickerSetThumb': {\r\n const id = (location.stickerset as InputStickerSet.inputStickerSetID).id || \r\n (location.stickerset as InputStickerSet.inputStickerSetShortName).short_name || \r\n (location.stickerset as InputStickerSet.inputStickerSetDice).emoticon || \r\n location.stickerset._;\r\n str = ['stickerSetThumb', id, location.thumb_version].join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n case 'inputFileLocation': {\r\n str = location.volume_id + '_' + location.local_id;\r\n break;\r\n }\r\n\r\n case 'inputWebFileLocation': {\r\n str = ['webFile', location.url].join(FILENAME_JOINER);\r\n break;\r\n }\r\n\r\n default: {\r\n console.error('Unrecognized location:', location);\r\n str = '';\r\n break;\r\n }\r\n }\r\n\r\n return str + (ext ? '.' + ext : ext);\r\n}\r\n\r\nexport type FileURLType = 'photo' | 'thumb' | 'document' | 'stream' | 'download';\r\nexport function getFileURL(type: FileURLType, options: DownloadOptions) {\r\n //console.log('getFileURL', location);\r\n //const perf = performance.now();\r\n const encoded = encodeURIComponent(JSON.stringify(options));\r\n //console.log('getFileURL encode:', performance.now() - perf, encoded);\r\n\r\n return '/' + type + '/' + encoded;\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\nfunction resizeableImage(originalImage: HTMLImageElement, canvas?: HTMLCanvasElement) {\r\n let cropComponent: HTMLDivElement, \r\n container: HTMLDivElement, \r\n cropImage: HTMLImageElement, \r\n event_state: Partial<{ \r\n mouse_x: number, \r\n mouse_y: number, \r\n container_width: number, \r\n container_height: number, \r\n container_left: number, \r\n container_top: number\r\n }> = {}, \r\n keyZoomValue = 4.0, \r\n MINWIDTH = 50, \r\n MINHEIGHT = 50, \r\n CROPWIDTH = 200, \r\n CROPHEIGHT = 200, \r\n cropLeft = 0, \r\n cropTop = 0, \r\n cropWidth = 0, \r\n cropHeight = 0,\r\n scaledRatio = 0;\r\n \r\n if(originalImage.complete) init();\r\n else originalImage.onload = init;\r\n \r\n function removeHandlers() {\r\n container.removeEventListener('mousedown', startMoving);\r\n container.removeEventListener('touchstart', startMoving);\r\n container.removeEventListener('wheel', resizing);\r\n \r\n document.removeEventListener('mouseup', endMoving);\r\n document.removeEventListener('touchend', endMoving);\r\n document.removeEventListener('mousemove', moving);\r\n document.removeEventListener('touchmove', moving);\r\n document.removeEventListener('keypress', keyHandler);\r\n\r\n cropComponent.remove();\r\n container.remove();\r\n cropImage.remove();\r\n }\r\n \r\n function addHandlers() {\r\n container.addEventListener('mousedown', startMoving, false);\r\n container.addEventListener('touchstart', startMoving, false);\r\n container.addEventListener('wheel', resizing, false);\r\n \r\n document.addEventListener('keypress', keyHandler, false);\r\n //document.querySelector('.btn-crop').addEventListener('click', openCropCanvasImg);\r\n }\r\n \r\n function init() {\r\n originalImage.classList.add('crop-blur');\r\n originalImage.draggable = false;\r\n \r\n cropImage = new Image();\r\n cropImage.src = originalImage.src;\r\n cropImage.draggable = false;\r\n cropImage.classList.add('crop-overlay-image');\r\n \r\n if(!canvas) {\r\n canvas = document.createElement('canvas');\r\n }\r\n \r\n cropComponent = document.createElement('div');\r\n cropComponent.classList.add('crop-component');\r\n \r\n container = document.createElement('div');\r\n container.classList.add('crop-overlay');\r\n \r\n const overlayColor = document.createElement('div');\r\n overlayColor.classList.add('crop-overlay-color');\r\n \r\n cropComponent.appendChild(container);\r\n const wrapper = originalImage.parentNode as HTMLElement;\r\n wrapper.appendChild(cropComponent);\r\n cropComponent.appendChild(cropImage);\r\n cropComponent.appendChild(originalImage);\r\n cropComponent.appendChild(overlayColor);\r\n container.appendChild(cropImage);\r\n\r\n cropImage.style.maxWidth = originalImage.width + 'px';\r\n\r\n scaledRatio = originalImage.naturalWidth / originalImage.offsetWidth;\r\n \r\n const left = originalImage.offsetWidth / 2 - CROPWIDTH / 2;\r\n const top = originalImage.offsetHeight / 2 - CROPHEIGHT / 2;\r\n \r\n updateCropSize(CROPWIDTH, CROPHEIGHT);\r\n updateCropImage(left, top);\r\n updateContainer(left, top);\r\n addHandlers();\r\n //crop();\r\n }\r\n \r\n function updateCropSize(width: number, height: number) {\r\n cropWidth = width * scaledRatio;\r\n cropHeight = height * scaledRatio;\r\n\r\n container.style.width = width + 'px';\r\n container.style.height = height + 'px';\r\n }\r\n \r\n function updateCropImage(left: number, top: number) {\r\n cropTop = top * scaledRatio;\r\n cropLeft = left * scaledRatio;\r\n\r\n cropImage.style.top = -top + 'px';\r\n cropImage.style.left = -left + 'px';\r\n }\r\n \r\n function updateContainer(left: number, top: number) {\r\n container.style.top = top + 'px';\r\n container.style.left = left + 'px';\r\n }\r\n \r\n // Save the initial event details and container state\r\n function saveEventState(e: any) {\r\n event_state.container_width = container.offsetWidth;\r\n event_state.container_height = container.offsetHeight;\r\n \r\n event_state.container_left = container.offsetLeft;\r\n event_state.container_top = container.offsetTop;\r\n \r\n event_state.mouse_x = (e.clientX || e.pageX || e.touches && e.touches[0].clientX) + window.scrollX;\r\n event_state.mouse_y = (e.clientY || e.pageY || e.touches && e.touches[0].clientY) + window.scrollY;\r\n }\r\n \r\n function imgZoom(zoom: number) {\r\n zoom = zoom * Math.PI * 2\r\n let newWidth = Math.floor(container.clientWidth + zoom), \r\n newHeight = Math.floor(container.clientHeight + zoom), \r\n w = cropImage.clientWidth, \r\n h = cropImage.clientHeight, \r\n left: number, \r\n top: number, \r\n right: number, \r\n bottom: number;\r\n \r\n if(newWidth < MINWIDTH) {\r\n return;\r\n } else if(newWidth > w) {\r\n return;\r\n }\r\n \r\n left = container.offsetLeft - (zoom / 2);\r\n top = container.offsetTop - (zoom / 2);\r\n right = left + newWidth;\r\n bottom = top + newHeight;\r\n \r\n if(left < 0) left = 0;\r\n if(top < 0) top = 0;\r\n\r\n if(right > w) return;\r\n if(bottom > h) return;\r\n\r\n updateCropSize(newWidth, newWidth);\r\n updateCropImage(left, top);\r\n updateContainer(left, top);\r\n //crop();\r\n }\r\n \r\n function keyHandler(e: KeyboardEvent) {\r\n e.preventDefault();\r\n \r\n switch (String.fromCharCode(e.charCode)) {\r\n case '+' :\r\n imgZoom(keyZoomValue);\r\n break;\r\n case '-' :\r\n imgZoom(-keyZoomValue);\r\n break;\r\n }\r\n }\r\n \r\n function resizing(e: any) {\r\n e.preventDefault();\r\n imgZoom(e.deltaY > 0 ? 1 : -1);\r\n }\r\n \r\n function startMoving(e: MouseEvent | TouchEvent) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n saveEventState(e);\r\n \r\n document.addEventListener('mousemove', moving);\r\n document.addEventListener('touchmove', moving);\r\n document.addEventListener('mouseup', endMoving);\r\n document.addEventListener('touchend', endMoving);\r\n }\r\n \r\n function endMoving(e: MouseEvent | TouchEvent) {\r\n e.preventDefault();\r\n \r\n document.removeEventListener('mouseup', endMoving);\r\n document.removeEventListener('touchend', endMoving);\r\n document.removeEventListener('mousemove', moving);\r\n document.removeEventListener('touchmove', moving);\r\n }\r\n \r\n function moving(e: any) {\r\n let currentTouch = {x: 0, y: 0}, \r\n left: number, \r\n top: number, \r\n w: number, \r\n h: number;\r\n \r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n currentTouch.x = e.pageX || e.touches && e.touches[0].pageX;\r\n currentTouch.y = e.pageY || e.touches && e.touches[0].pageY;\r\n \r\n left = currentTouch.x - (event_state.mouse_x - event_state.container_left);\r\n top = currentTouch.y - (event_state.mouse_y - event_state.container_top);\r\n w = container.offsetWidth;\r\n h = container.offsetHeight;\r\n \r\n if(left < 0) left = 0;\r\n else if(left > cropImage.offsetWidth - w) left = cropImage.offsetWidth - w;\r\n\r\n if(top < 0) top = 0;\r\n else if(top > cropImage.offsetHeight - h) top = cropImage.offsetHeight - h;\r\n \r\n updateCropImage(left, top);\r\n updateContainer(left, top);\r\n //crop();\r\n }\r\n\r\n function crop() {\r\n canvas.width = cropWidth;\r\n canvas.height = cropHeight;\r\n \r\n const ctx = canvas.getContext('2d');\r\n ctx.drawImage(originalImage,\r\n cropLeft, cropTop,\r\n cropWidth, cropHeight,\r\n 0, 0,\r\n cropWidth, cropHeight\r\n );\r\n }\r\n \r\n return {crop, removeHandlers};\r\n}\r\n\r\nexport default resizeableImage;\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 appDownloadManager from \"../../lib/appManagers/appDownloadManager\";\r\nimport resizeableImage from \"../../lib/cropper\";\r\nimport PopupElement from \".\";\r\nimport { _i18n } from \"../../lib/langPack\";\r\nimport { attachClickEvent } from \"../../helpers/dom/clickEvent\";\r\nimport readBlobAsDataURL from \"../../helpers/blob/readBlobAsDataURL\";\r\n\r\nexport default class PopupAvatar extends PopupElement {\r\n private cropContainer: HTMLElement;\r\n private input: HTMLInputElement;\r\n private h6: HTMLElement;\r\n\r\n private image = new Image();\r\n\r\n private canvas: HTMLCanvasElement;\r\n private blob: Blob;\r\n private cropper = {\r\n crop: () => {},\r\n removeHandlers: () => {}\r\n };\r\n\r\n private onCrop: (upload: () => ReturnType) => void;\r\n\r\n constructor() {\r\n super('popup-avatar', null, {closable: true, withConfirm: true});\r\n\r\n this.h6 = document.createElement('h6');\r\n _i18n(this.h6, 'Popup.Avatar.Title');\r\n\r\n this.btnClose.classList.remove('btn-icon');\r\n\r\n this.header.append(this.h6);\r\n\r\n this.cropContainer = document.createElement('div');\r\n this.cropContainer.classList.add('crop');\r\n this.cropContainer.append(this.image);\r\n\r\n this.input = document.createElement('input');\r\n this.input.type = 'file';\r\n this.input.style.display = 'none';\r\n this.listenerSetter.add(this.input)('change', (e: any) => {\r\n const file = e.target.files[0];\r\n if(!file) {\r\n return;\r\n }\r\n\r\n readBlobAsDataURL(file).then(contents => {\r\n this.image = new Image();\r\n this.cropContainer.append(this.image);\r\n this.image.src = contents;\r\n \r\n this.image.onload = () => {\r\n /* let {w, h} = calcImageInBox(this.image.naturalWidth, this.image.naturalHeight, 460, 554);\r\n cropContainer.style.width = w + 'px';\r\n cropContainer.style.height = h + 'px'; */\r\n this.show();\r\n \r\n this.cropper = resizeableImage(this.image, this.canvas);\r\n this.input.value = '';\r\n };\r\n });\r\n }, false);\r\n\r\n this.btnConfirm.className = 'btn-primary btn-color-primary btn-circle btn-crop btn-icon tgico-check z-depth-1';\r\n attachClickEvent(this.btnConfirm, () => {\r\n this.cropper.crop();\r\n this.hide();\r\n\r\n this.canvas.toBlob(blob => {\r\n this.blob = blob; // save blob to send after reg\r\n this.darkenCanvas();\r\n this.resolve();\r\n }, 'image/jpeg', 1);\r\n }, {listenerSetter: this.listenerSetter});\r\n\r\n this.container.append(this.cropContainer, this.btnConfirm, this.input);\r\n\r\n this.addEventListener('closeAfterTimeout', () => {\r\n this.cropper.removeHandlers();\r\n if(this.image) {\r\n this.image.remove();\r\n }\r\n });\r\n }\r\n\r\n private resolve() {\r\n this.onCrop(() => {\r\n return appDownloadManager.upload(this.blob);\r\n });\r\n }\r\n\r\n public open(postCanvas: HTMLCanvasElement, onCrop: PopupAvatar['onCrop']) {\r\n this.canvas = postCanvas;\r\n this.onCrop = onCrop;\r\n\r\n this.input.click();\r\n }\r\n\r\n public darkenCanvas() {\r\n let ctx = this.canvas.getContext('2d');\r\n ctx.fillStyle = \"rgba(0, 0, 0, 0.3)\";\r\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\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_MOBILE, IS_APPLE } from \"../../environment/userAgent\";\r\n\r\nexport default function isSendShortcutPressed(e: KeyboardEvent) {\r\n if(e.key === 'Enter' && !IS_MOBILE && !e.isComposing) {\r\n /* if(e.ctrlKey || e.metaKey) {\r\n this.messageInput.innerHTML += '
';\r\n placeCaretAtEnd(this.message)\r\n return;\r\n } */\r\n\r\n if(rootScope.settings.sendShortcut === 'enter') {\r\n if(e.shiftKey || e.ctrlKey || e.metaKey) {\r\n return;\r\n }\r\n\r\n return true;\r\n } else {\r\n const secondaryKey = IS_APPLE ? e.metaKey : e.ctrlKey;\r\n if(e.shiftKey || (IS_APPLE ? e.ctrlKey : e.metaKey)) {\r\n return;\r\n }\r\n\r\n if(secondaryKey) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport readBlobAs from \"./readBlobAs\";\n\nexport default function readBlobAsDataURL(blob: Blob) {\n return readBlobAs(blob, 'readAsDataURL');\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 type { CancellablePromise } from '../helpers/cancellablePromise';\r\nimport type { InputFile } from '../layer';\r\nimport type { AuthState } from '../types';\r\nimport Button from '../components/button';\r\nimport InputField from '../components/inputField';\r\nimport { putPreloader } from '../components/misc';\r\nimport PopupAvatar from '../components/popups/avatar';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport I18n, { i18n } from '../lib/langPack';\r\n//import apiManager from '../lib/mtproto/apiManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport RichTextProcessor from '../lib/richtextprocessor';\r\nimport LoginPage from './loginPage';\r\nimport Page from './page';\r\nimport blurActiveElement from '../helpers/dom/blurActiveElement';\r\nimport replaceContent from '../helpers/dom/replaceContent';\r\n\r\nlet authCode: AuthState.signUp['authCode'] = null;\r\n\r\nconst onFirstMount = () => import('../lib/appManagers/appProfileManager').then(imported => {\r\n const page = new LoginPage({\r\n className: 'page-signUp',\r\n withInputWrapper: true,\r\n titleLangKey: 'YourName',\r\n subtitleLangKey: 'Login.Register.Subtitle'\r\n });\r\n\r\n page.imageDiv.classList.add('avatar-edit');\r\n\r\n page.title.classList.add('fullName');\r\n\r\n const avatarPreview = document.createElement('canvas');\r\n avatarPreview.id = 'canvas-avatar';\r\n avatarPreview.className = 'avatar-edit-canvas';\r\n\r\n const addIco = document.createElement('span');\r\n addIco.className = 'tgico tgico-cameraadd';\r\n\r\n page.imageDiv.append(avatarPreview, addIco);\r\n \r\n const appProfileManager = imported.default;\r\n\r\n let uploadAvatar: () => CancellablePromise;\r\n page.imageDiv.addEventListener('click', () => {\r\n new PopupAvatar().open(avatarPreview, (_uploadAvatar) => {\r\n uploadAvatar = _uploadAvatar;\r\n });\r\n });\r\n\r\n const handleInput = (e: Event) => {\r\n const name = nameInputField.value || '';\r\n const lastName = lastNameInputField.value || '';\r\n\r\n const fullName = name || lastName \r\n ? (name + ' ' + lastName).trim() \r\n : '';\r\n \r\n if(fullName) replaceContent(page.title, RichTextProcessor.wrapEmojiText(fullName));\r\n else replaceContent(page.title, i18n('YourName'));\r\n };\r\n\r\n let sendAvatar = () => new Promise((resolve, reject) => {\r\n if(!uploadAvatar) {\r\n //console.log('User has not selected avatar');\r\n return resolve();\r\n }\r\n\r\n //console.log('invoking uploadFile...');\r\n uploadAvatar().then((inputFile) => {\r\n //console.log('uploaded smthn', inputFile);\r\n \r\n appProfileManager.uploadProfilePhoto(inputFile).then(resolve, reject);\r\n }, reject);\r\n });\r\n\r\n const nameInputField = new InputField({\r\n label: 'FirstName',\r\n maxLength: 70\r\n });\r\n\r\n const lastNameInputField = new InputField({\r\n label: 'LastName',\r\n maxLength: 64\r\n });\r\n\r\n const btnSignUp = Button('btn-primary btn-color-primary');\r\n const btnI18n = new I18n.IntlElement({key: 'StartMessaging'});\r\n btnSignUp.append(btnI18n.element);\r\n\r\n page.inputWrapper.append(nameInputField.container, lastNameInputField.container, btnSignUp);\r\n\r\n nameInputField.input.addEventListener('input', handleInput);\r\n lastNameInputField.input.addEventListener('input', handleInput);\r\n\r\n btnSignUp.addEventListener('click', function(this: typeof btnSignUp, e) {\r\n if(nameInputField.input.classList.contains('error') || lastNameInputField.input.classList.contains('error')) {\r\n return false;\r\n }\r\n\r\n if(!nameInputField.value.length) {\r\n nameInputField.input.classList.add('error');\r\n return false;\r\n }\r\n\r\n this.disabled = true;\r\n\r\n const name = nameInputField.value.trim();\r\n const lastName = lastNameInputField.value.trim();\r\n\r\n const params = {\r\n phone_number: authCode.phone_number,\r\n phone_code_hash: authCode.phone_code_hash,\r\n first_name: name,\r\n last_name: lastName\r\n };\r\n\r\n //console.log('invoking auth.signUp with params:', params);\r\n\r\n btnI18n.update({key: 'PleaseWait'});\r\n const preloader = putPreloader(this);\r\n\r\n apiManager.invokeApi('auth.signUp', params)\r\n .then((response) => {\r\n //console.log('auth.signUp response:', response);\r\n \r\n switch(response._) {\r\n case 'auth.authorization': // success\r\n apiManager.setUser(response.user);\r\n\r\n sendAvatar().finally(() => {\r\n import('./pageIm').then(m => {\r\n m.default.mount();\r\n });\r\n });\r\n \r\n break;\r\n default:\r\n btnI18n.update({key: response._ as any});\r\n this.removeAttribute('disabled');\r\n preloader.remove();\r\n break;\r\n }\r\n\r\n /* (document.body.getElementsByClassName('page-sign')[0] as HTMLDivElement).style.display = 'none';\r\n pageAuthCode(Object.assign(code, {phoneNumber})); */\r\n }).catch(err => {\r\n this.removeAttribute('disabled');\r\n preloader.remove();\r\n\r\n switch(err.type) {\r\n default:\r\n btnI18n.update({key: err.type});\r\n break;\r\n }\r\n });\r\n });\r\n\r\n blurActiveElement();\r\n return new Promise((resolve) => {\r\n window.requestAnimationFrame(resolve);\r\n });\r\n});\r\n\r\nconst page = new Page('page-signUp', true, onFirstMount, (_authCode: typeof authCode) => {\r\n authCode = _authCode;\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignUp', authCode: _authCode});\r\n});\r\n\r\nexport default page;\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 replaceContent(elem: HTMLElement, node: string | Node) {\r\n if(typeof(node) === 'string') {\r\n elem.innerHTML = node;\r\n return;\r\n }\r\n\r\n // * children.length doesn't count text nodes\r\n const firstChild = elem.firstChild;\r\n if(firstChild) {\r\n if(elem.lastChild === firstChild) {\r\n firstChild.replaceWith(node);\r\n } else {\r\n elem.textContent = '';\r\n elem.append(node);\r\n }\r\n } else {\r\n elem.append(node);\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 simulateEvent from \"../helpers/dom/dispatchEvent\";\r\nimport findUpAttribute from \"../helpers/dom/findUpAttribute\";\r\nimport getRichValue from \"../helpers/dom/getRichValue\";\r\nimport isInputEmpty from \"../helpers/dom/isInputEmpty\";\r\nimport selectElementContents from \"../helpers/dom/selectElementContents\";\r\nimport { MessageEntity } from \"../layer\";\r\nimport { i18n, LangPackKey, _i18n } from \"../lib/langPack\";\r\nimport RichTextProcessor from \"../lib/richtextprocessor\";\r\nimport SetTransition from \"./singleTransition\";\r\n\r\nlet init = () => {\r\n document.addEventListener('paste', (e) => {\r\n if(!findUpAttribute(e.target, 'contenteditable=\"true\"')) {\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n let text: string, entities: MessageEntity[];\r\n\r\n // @ts-ignore\r\n let plainText: string = (e.originalEvent || e).clipboardData.getData('text/plain');\r\n let usePlainText = true;\r\n\r\n // @ts-ignore\r\n let html: string = (e.originalEvent || e).clipboardData.getData('text/html');\r\n if(html.trim()) {\r\n html = html.replace(//, '');\r\n html = html.replace(//, '');\r\n\r\n const match = html.match(/([\\s\\S]*)<\\/body>/);\r\n if(match) {\r\n html = match[1].trim();\r\n }\r\n\r\n let span: HTMLElement = document.createElement('span');\r\n span.innerHTML = html;\r\n\r\n let curChild = span.firstChild;\r\n while(curChild) { // * fix whitespace between elements like

asd

\\n

zxc

\r\n let nextSibling = curChild.nextSibling;\r\n if(curChild.nodeType === 3) {\r\n if(!curChild.nodeValue.trim()) {\r\n curChild.remove();\r\n }\r\n }\r\n\r\n curChild = nextSibling;\r\n }\r\n\r\n const richValue = getRichValue(span, true);\r\n if(richValue.value.replace(/\\s/g, '').length === plainText.replace(/\\s/g, '').length) {\r\n text = richValue.value;\r\n entities = richValue.entities;\r\n usePlainText = false;\r\n \r\n let entities2 = RichTextProcessor.parseEntities(text);\r\n entities2 = entities2.filter(e => e._ === 'messageEntityEmoji' || e._ === 'messageEntityLinebreak');\r\n RichTextProcessor.mergeEntities(entities, entities2);\r\n }\r\n }\r\n \r\n if(usePlainText) {\r\n text = plainText;\r\n entities = RichTextProcessor.parseEntities(text);\r\n entities = entities.filter(e => e._ === 'messageEntityEmoji' || e._ === 'messageEntityLinebreak');\r\n }\r\n\r\n text = RichTextProcessor.wrapDraftText(text, {entities});\r\n \r\n window.document.execCommand('insertHTML', false, text);\r\n });\r\n\r\n init = null;\r\n};\r\n\r\n// ! it doesn't respect symbols other than strongs\r\n/* const checkAndSetRTL = (input: HTMLElement) => {\r\n //const isEmpty = isInputEmpty(input);\r\n //console.log('input', isEmpty);\r\n\r\n //const char = [...getRichValue(input)][0];\r\n const char = (input instanceof HTMLInputElement ? input.value : input.innerText)[0];\r\n let direction = 'ltr';\r\n if(char && checkRTL(char)) {\r\n direction = 'rtl';\r\n }\r\n\r\n //console.log('RTL', direction, char);\r\n\r\n input.style.direction = direction;\r\n}; */\r\n\r\nexport enum InputState {\r\n Neutral = 0,\r\n Valid = 1,\r\n Error = 2\r\n};\r\n\r\nexport type InputFieldOptions = {\r\n placeholder?: LangPackKey, \r\n label?: LangPackKey, \r\n labelOptions?: any[],\r\n labelText?: string,\r\n name?: string, \r\n maxLength?: number, \r\n showLengthOn?: number,\r\n plainText?: true,\r\n animate?: boolean,\r\n required?: boolean,\r\n canBeEdited?: boolean,\r\n validate?: () => boolean\r\n};\r\n\r\nclass InputField {\r\n public container: HTMLElement;\r\n public input: HTMLElement;\r\n public inputFake: HTMLElement;\r\n public label: HTMLLabelElement;\r\n\r\n public originalValue: string;\r\n\r\n public required: boolean;\r\n public validate: () => boolean;\r\n\r\n //public onLengthChange: (length: number, isOverflow: boolean) => void;\r\n // protected wasInputFakeClientHeight: number;\r\n // protected showScrollDebounced: () => void;\r\n\r\n constructor(public options: InputFieldOptions = {}) {\r\n this.container = document.createElement('div');\r\n this.container.classList.add('input-field');\r\n\r\n this.required = options.required;\r\n this.validate = options.validate;\r\n\r\n if(options.maxLength !== undefined && options.showLengthOn === undefined) {\r\n options.showLengthOn = Math.min(40, Math.round(options.maxLength / 3));\r\n }\r\n\r\n const {placeholder, maxLength, showLengthOn, name, plainText, canBeEdited = true} = options;\r\n\r\n let label = options.label || options.labelText;\r\n\r\n let input: HTMLElement;\r\n if(!plainText) {\r\n if(init) {\r\n init();\r\n }\r\n\r\n this.container.innerHTML = `\r\n
\r\n `;\r\n\r\n input = this.container.firstElementChild as HTMLElement;\r\n const observer = new MutationObserver(() => {\r\n //checkAndSetRTL(input);\r\n\r\n if(processInput) {\r\n processInput();\r\n }\r\n });\r\n\r\n // * because if delete all characters there will br left\r\n input.addEventListener('input', () => {\r\n if(isInputEmpty(input)) {\r\n input.innerHTML = '';\r\n }\r\n\r\n if(this.inputFake) {\r\n this.inputFake.innerHTML = input.innerHTML;\r\n this.onFakeInput();\r\n }\r\n });\r\n \r\n // ! childList for paste first symbol\r\n observer.observe(input, {characterData: true, childList: true, subtree: true});\r\n\r\n if(options.animate) {\r\n input.classList.add('scrollable', 'scrollable-y');\r\n // this.wasInputFakeClientHeight = 0;\r\n // this.showScrollDebounced = debounce(() => this.input.classList.remove('no-scrollbar'), 150, false, true);\r\n this.inputFake = document.createElement('div');\r\n this.inputFake.setAttribute('contenteditable', 'true');\r\n this.inputFake.className = input.className + ' input-field-input-fake';\r\n }\r\n } else {\r\n this.container.innerHTML = `\r\n \r\n `;\r\n\r\n input = this.container.firstElementChild as HTMLElement;\r\n //input.addEventListener('input', () => checkAndSetRTL(input));\r\n }\r\n\r\n input.setAttribute('dir', 'auto');\r\n\r\n if(placeholder) {\r\n _i18n(input, placeholder, undefined, 'placeholder');\r\n\r\n if(this.inputFake) {\r\n _i18n(this.inputFake, placeholder, undefined, 'placeholder');\r\n }\r\n }\r\n\r\n if(label || placeholder) {\r\n const border = document.createElement('div');\r\n border.classList.add('input-field-border');\r\n this.container.append(border);\r\n }\r\n\r\n if(label) {\r\n this.label = document.createElement('label');\r\n this.setLabel();\r\n this.container.append(this.label);\r\n }\r\n\r\n let processInput: () => void;\r\n if(maxLength) {\r\n const labelEl = this.container.lastElementChild as HTMLLabelElement;\r\n let showingLength = false;\r\n\r\n processInput = () => {\r\n const wasError = input.classList.contains('error');\r\n // * https://stackoverflow.com/a/54369605 #2 to count emoji as 1 symbol\r\n const inputLength = plainText ? (input as HTMLInputElement).value.length : [...getRichValue(input, false).value].length;\r\n const diff = maxLength - inputLength;\r\n const isError = diff < 0;\r\n input.classList.toggle('error', isError);\r\n\r\n //this.onLengthChange && this.onLengthChange(inputLength, isError);\r\n\r\n if(isError || diff <= showLengthOn) {\r\n this.setLabel();\r\n labelEl.append(` (${maxLength - inputLength})`);\r\n if(!showingLength) showingLength = true;\r\n } else if((wasError && !isError) || showingLength) {\r\n this.setLabel();\r\n showingLength = false;\r\n }\r\n };\r\n\r\n input.addEventListener('input', processInput);\r\n }\r\n\r\n this.input = input;\r\n }\r\n\r\n public select() {\r\n if(!this.value) { // * avoid selecting whole empty field on iOS devices\r\n return;\r\n }\r\n\r\n if(this.options.plainText) {\r\n (this.input as HTMLInputElement).select(); // * select text\r\n } else {\r\n selectElementContents(this.input);\r\n }\r\n }\r\n\r\n public setLabel() {\r\n this.label.textContent = '';\r\n if(this.options.labelText) {\r\n this.label.innerHTML = this.options.labelText;\r\n } else {\r\n this.label.append(i18n(this.options.label, this.options.labelOptions));\r\n }\r\n }\r\n\r\n public onFakeInput(setHeight = true) {\r\n const {scrollHeight: newHeight/* , clientHeight */} = this.inputFake;\r\n /* if(this.wasInputFakeClientHeight && this.wasInputFakeClientHeight !== clientHeight) {\r\n this.input.classList.add('no-scrollbar'); // ! в сафари может вообще не появиться скролл после анимации, так как ему нужен полный reflow блока с overflow.\r\n this.showScrollDebounced();\r\n } */\r\n\r\n const currentHeight = +this.input.style.height.replace('px', '');\r\n if(currentHeight === newHeight) {\r\n return;\r\n }\r\n\r\n const TRANSITION_DURATION_FACTOR = 50;\r\n const transitionDuration = Math.round(\r\n TRANSITION_DURATION_FACTOR * Math.log(Math.abs(newHeight - currentHeight)),\r\n );\r\n\r\n // this.wasInputFakeClientHeight = clientHeight;\r\n this.input.style.transitionDuration = `${transitionDuration}ms`;\r\n\r\n if(setHeight) {\r\n this.input.style.height = newHeight ? newHeight + 'px' : '';\r\n }\r\n\r\n const className = 'is-changing-height';\r\n SetTransition(this.input, className, true, transitionDuration, () => {\r\n this.input.classList.remove(className);\r\n });\r\n }\r\n\r\n get value() {\r\n return this.options.plainText ? (this.input as HTMLInputElement).value : getRichValue(this.input, false).value;\r\n //return getRichValue(this.input);\r\n }\r\n\r\n set value(value: string) {\r\n this.setValueSilently(value, false);\r\n\r\n simulateEvent(this.input, 'input');\r\n }\r\n\r\n public setValueSilently(value: string, fireFakeInput = true) {\r\n if(this.options.plainText) {\r\n (this.input as HTMLInputElement).value = value;\r\n } else {\r\n this.input.innerHTML = value;\r\n \r\n if(this.inputFake) {\r\n this.inputFake.innerHTML = value;\r\n\r\n if(fireFakeInput) {\r\n this.onFakeInput();\r\n }\r\n }\r\n }\r\n }\r\n\r\n public isChanged() {\r\n return this.value !== this.originalValue;\r\n }\r\n\r\n public isValid() {\r\n return !this.input.classList.contains('error') && \r\n (!this.validate || this.validate()) && \r\n (!this.required || !isInputEmpty(this.input));\r\n }\r\n\r\n public isValidToChange() {\r\n return this.isValid() && this.isChanged();\r\n }\r\n\r\n public setDraftValue(value = '', silent = false) {\r\n if(!this.options.plainText) {\r\n value = RichTextProcessor.wrapDraftText(value);\r\n }\r\n\r\n if(silent) {\r\n this.setValueSilently(value, false); \r\n } else {\r\n this.value = value;\r\n }\r\n }\r\n\r\n public setOriginalValue(value: InputField['originalValue'] = '', silent = false) {\r\n this.originalValue = value;\r\n this.setDraftValue(value, silent);\r\n }\r\n\r\n public setState(state: InputState, label?: LangPackKey) {\r\n if(label) {\r\n this.label.textContent = '';\r\n this.label.append(i18n(label, this.options.labelOptions));\r\n }\r\n\r\n this.input.classList.toggle('error', !!(state & InputState.Error));\r\n this.input.classList.toggle('valid', !!(state & InputState.Valid));\r\n }\r\n\r\n public setError(label?: LangPackKey) {\r\n this.setState(InputState.Error, label);\r\n }\r\n}\r\n\r\nexport default InputField;\r\n","// https://stackoverflow.com/a/6150060\nexport default function selectElementContents(el: HTMLElement) {\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\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 rootScope from \"../lib/rootScope\";\r\n\r\nconst SetTransition = (\r\n element: HTMLElement, \r\n className: string, \r\n forwards: boolean, \r\n duration: number, \r\n onTransitionEnd?: () => void, \r\n useRafs?: number\r\n) => {\r\n const {timeout, raf} = element.dataset;\r\n if(timeout !== undefined) {\r\n clearTimeout(+timeout);\r\n }\r\n\r\n if(raf !== undefined) {\r\n window.cancelAnimationFrame(+raf);\r\n if(!useRafs) {\r\n delete element.dataset.raf;\r\n }\r\n }\r\n\r\n // if(forwards && className && element.classList.contains(className) && !element.classList.contains('animating')) {\r\n // return;\r\n // }\r\n\r\n if(useRafs && rootScope.settings.animationsEnabled && duration) {\r\n element.dataset.raf = '' + window.requestAnimationFrame(() => {\r\n delete element.dataset.raf;\r\n SetTransition(element, className, forwards, duration, onTransitionEnd, useRafs - 1);\r\n });\r\n\r\n return;\r\n }\r\n\r\n if(forwards && className) {\r\n element.classList.add(className);\r\n }\r\n\r\n const afterTimeout = () => {\r\n delete element.dataset.timeout;\r\n if(!forwards && className) {\r\n element.classList.remove('backwards', className);\r\n }\r\n\r\n element.classList.remove('animating');\r\n \r\n onTransitionEnd && onTransitionEnd();\r\n };\r\n\r\n if(!rootScope.settings.animationsEnabled || !duration) {\r\n element.classList.remove('animating', 'backwards');\r\n afterTimeout();\r\n return;\r\n }\r\n\r\n element.classList.add('animating');\r\n\r\n element.classList.toggle('backwards', !forwards);\r\n element.dataset.timeout = '' + setTimeout(afterTimeout, duration);\r\n};\r\n\r\nexport default SetTransition;\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 { ripple } from \"../ripple\";\r\nimport animationIntersector from \"../animationIntersector\";\r\nimport appNavigationController, { NavigationItem } from \"../appNavigationController\";\r\nimport { i18n, LangPackKey } from \"../../lib/langPack\";\r\nimport findUpClassName from \"../../helpers/dom/findUpClassName\";\r\nimport blurActiveElement from \"../../helpers/dom/blurActiveElement\";\r\nimport ListenerSetter from \"../../helpers/listenerSetter\";\r\nimport { attachClickEvent, simulateClickEvent } from \"../../helpers/dom/clickEvent\";\r\nimport isSendShortcutPressed from \"../../helpers/dom/isSendShortcutPressed\";\r\nimport { cancelEvent } from \"../../helpers/dom/cancelEvent\";\r\nimport EventListenerBase, { EventListenerListeners } from \"../../helpers/eventListenerBase\";\r\nimport { addFullScreenListener, getFullScreenElement } from \"../../helpers/dom/fullScreen\";\r\nimport indexOfAndSplice from \"../../helpers/array/indexOfAndSplice\";\r\n\r\nexport type PopupButton = {\r\n text?: string,\r\n callback?: () => void,\r\n langKey?: LangPackKey,\r\n langArgs?: any[],\r\n isDanger?: true,\r\n isCancel?: true,\r\n element?: HTMLButtonElement\r\n};\r\n\r\nexport type PopupOptions = Partial<{\r\n closable: true, \r\n overlayClosable: true, \r\n withConfirm: LangPackKey | true, \r\n body: true,\r\n confirmShortcutIsSendShortcut: boolean,\r\n withoutOverlay: boolean\r\n}>;\r\n\r\nexport interface PopupElementConstructable {\r\n new(...args: any[]): PopupElement;\r\n}\r\n\r\nconst DEFAULT_APPEND_TO = document.body;\r\nlet appendPopupTo = DEFAULT_APPEND_TO;\r\n\r\nconst onFullScreenChange = () => {\r\n appendPopupTo = getFullScreenElement() || DEFAULT_APPEND_TO;\r\n PopupElement.reAppend();\r\n};\r\n\r\naddFullScreenListener(DEFAULT_APPEND_TO, onFullScreenChange);\r\n\r\ntype PopupListeners = {\r\n close: () => void,\r\n closeAfterTimeout: () => void\r\n};\r\n\r\nexport default class PopupElement extends EventListenerBase {\r\n private static POPUPS: PopupElement[] = [];\r\n protected element = document.createElement('div');\r\n protected container = document.createElement('div');\r\n protected header = document.createElement('div');\r\n protected title = document.createElement('div');\r\n protected btnClose: HTMLElement;\r\n protected btnConfirm: HTMLButtonElement;\r\n protected body: HTMLElement;\r\n protected buttonsEl: HTMLElement;\r\n\r\n protected onEscape: () => boolean = () => true;\r\n\r\n protected navigationItem: NavigationItem;\r\n\r\n protected listenerSetter: ListenerSetter;\r\n\r\n protected confirmShortcutIsSendShortcut: boolean;\r\n protected btnConfirmOnEnter: HTMLButtonElement;\r\n\r\n protected withoutOverlay: boolean;\r\n\r\n constructor(className: string, protected buttons?: Array, options: PopupOptions = {}) {\r\n super(false);\r\n this.element.classList.add('popup');\r\n this.element.className = 'popup' + (className ? ' ' + className : '');\r\n this.container.classList.add('popup-container', 'z-depth-1');\r\n\r\n this.header.classList.add('popup-header');\r\n this.title.classList.add('popup-title');\r\n\r\n this.header.append(this.title);\r\n\r\n this.listenerSetter = new ListenerSetter();\r\n\r\n this.confirmShortcutIsSendShortcut = options.confirmShortcutIsSendShortcut;\r\n\r\n if(options.closable) {\r\n this.btnClose = document.createElement('span');\r\n this.btnClose.classList.add('btn-icon', 'popup-close', 'tgico-close');\r\n //ripple(this.closeBtn);\r\n this.header.prepend(this.btnClose);\r\n\r\n attachClickEvent(this.btnClose, this.hide, {listenerSetter: this.listenerSetter, once: true});\r\n }\r\n\r\n this.withoutOverlay = options.withoutOverlay;\r\n if(this.withoutOverlay) {\r\n this.element.classList.add('no-overlay');\r\n }\r\n\r\n if(options.overlayClosable) {\r\n attachClickEvent(this.element, (e: MouseEvent) => {\r\n if(!findUpClassName(e.target, 'popup-container')) {\r\n this.hide();\r\n }\r\n }, {listenerSetter: this.listenerSetter});\r\n }\r\n\r\n if(options.withConfirm) {\r\n this.btnConfirm = document.createElement('button');\r\n this.btnConfirm.classList.add('btn-primary', 'btn-color-primary');\r\n if(options.withConfirm !== true) {\r\n this.btnConfirm.append(i18n(options.withConfirm));\r\n }\r\n this.header.append(this.btnConfirm);\r\n ripple(this.btnConfirm);\r\n }\r\n\r\n this.container.append(this.header);\r\n if(options.body) {\r\n this.body = document.createElement('div');\r\n this.body.classList.add('popup-body');\r\n this.container.append(this.body);\r\n }\r\n\r\n let btnConfirmOnEnter = this.btnConfirm;\r\n if(buttons?.length) {\r\n const buttonsDiv = this.buttonsEl = document.createElement('div');\r\n buttonsDiv.classList.add('popup-buttons');\r\n\r\n if(buttons.length === 2) {\r\n buttonsDiv.classList.add('popup-buttons-row');\r\n }\r\n \r\n const buttonsElements = buttons.map(b => {\r\n const button = document.createElement('button');\r\n button.className = 'btn' + (b.isDanger ? ' danger' : ' primary');\r\n \r\n ripple(button);\r\n \r\n if(b.text) {\r\n button.innerHTML = b.text;\r\n } else {\r\n button.append(i18n(b.langKey, b.langArgs));\r\n }\r\n \r\n attachClickEvent(button, () => {\r\n b.callback && b.callback();\r\n this.destroy();\r\n }, {listenerSetter: this.listenerSetter, once: true});\r\n \r\n return b.element = button;\r\n });\r\n \r\n if(!btnConfirmOnEnter && buttons.length === 2) {\r\n const button = buttons.find(button => !button.isCancel);\r\n if(button) {\r\n btnConfirmOnEnter = button.element;\r\n }\r\n }\r\n\r\n buttonsDiv.append(...buttonsElements);\r\n this.container.append(buttonsDiv);\r\n }\r\n\r\n this.btnConfirmOnEnter = btnConfirmOnEnter;\r\n\r\n this.element.append(this.container);\r\n\r\n PopupElement.POPUPS.push(this);\r\n }\r\n\r\n public show() {\r\n this.navigationItem = {\r\n type: 'popup',\r\n onPop: () => this.destroy(),\r\n onEscape: this.onEscape\r\n };\r\n\r\n appNavigationController.pushItem(this.navigationItem);\r\n\r\n blurActiveElement(); // * hide mobile keyboard\r\n appendPopupTo.append(this.element);\r\n void this.element.offsetWidth; // reflow\r\n this.element.classList.add('active');\r\n\r\n if(!this.withoutOverlay) {\r\n rootScope.isOverlayActive = true;\r\n animationIntersector.checkAnimations(true);\r\n }\r\n\r\n // cannot add event instantly because keydown propagation will fire it\r\n if(this.btnConfirmOnEnter) {\r\n setTimeout(() => {\r\n this.listenerSetter.add(document.body)('keydown', (e) => {\r\n if(this.confirmShortcutIsSendShortcut ? isSendShortcutPressed(e) : e.key === 'Enter') {\r\n simulateClickEvent(this.btnConfirmOnEnter);\r\n cancelEvent(e);\r\n }\r\n });\r\n }, 0);\r\n }\r\n }\r\n\r\n public hide = () => {\r\n appNavigationController.backByItem(this.navigationItem);\r\n };\r\n\r\n protected destroy() {\r\n this.dispatchEvent('close');\r\n this.element.classList.add('hiding');\r\n this.element.classList.remove('active');\r\n this.listenerSetter.removeAll();\r\n\r\n if(!this.withoutOverlay) {\r\n rootScope.isOverlayActive = false;\r\n }\r\n\r\n appNavigationController.removeItem(this.navigationItem);\r\n this.navigationItem = undefined;\r\n\r\n indexOfAndSplice(PopupElement.POPUPS, this);\r\n\r\n // ! calm\r\n onFullScreenChange();\r\n\r\n setTimeout(() => {\r\n this.element.remove();\r\n this.dispatchEvent('closeAfterTimeout');\r\n this.cleanup();\r\n\r\n if(!this.withoutOverlay) {\r\n animationIntersector.checkAnimations(false);\r\n }\r\n }, 150);\r\n }\r\n\r\n public static reAppend() {\r\n this.POPUPS.forEach(popup => {\r\n const {element, container} = popup;\r\n const parentElement = element.parentElement;\r\n if(parentElement && parentElement !== appendPopupTo && appendPopupTo !== container) {\r\n appendPopupTo.append(element);\r\n }\r\n });\r\n }\r\n\r\n public static getPopups(popupConstructor: PopupElementConstructable) {\r\n return this.POPUPS.filter(element => element instanceof popupConstructor);\r\n }\r\n}\r\n\r\nexport const addCancelButton = (buttons: PopupButton[]) => {\r\n const button = buttons.find(b => b.isCancel);\r\n if(!button) {\r\n buttons.push({\r\n langKey: 'Cancel',\r\n isCancel: true\r\n });\r\n }\r\n\r\n return buttons;\r\n};\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov \r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport { MOUNT_CLASS_TO } from \"../../config/debug\";\r\nimport { MessageEntity } from \"../../layer\";\r\nimport RichTextProcessor from \"../../lib/richtextprocessor\";\r\nimport getRichElementValue from \"./getRichElementValue\";\r\n\r\nexport default function getRichValue(field: HTMLElement, withEntities = true) {\r\n const lines: string[] = [];\r\n const line: string[] = [];\r\n\r\n const entities: MessageEntity[] = withEntities ? [] : undefined;\r\n getRichElementValue(field, lines, line, undefined, undefined, entities);\r\n if(line.length) {\r\n lines.push(line.join(''));\r\n }\r\n\r\n let value = lines.join('\\n');\r\n value = value.replace(/\\u00A0/g, ' ');\r\n\r\n if(entities?.length) {\r\n // ! cannot do that here because have the same check before the sending in RichTextProcessor.parseMarkdown\r\n /* const entity = entities[entities.length - 1];\r\n const length = value.length;\r\n const trimmedLength = value.trimRight().length;\r\n if(length !== trimmedLength) {\r\n entity.length -= length - trimmedLength;\r\n } */\r\n\r\n RichTextProcessor.combineSameEntities(entities);\r\n RichTextProcessor.sortEntities(entities);\r\n }\r\n\r\n //console.log('getRichValue:', value, entities);\r\n\r\n return {value, entities};\r\n}\r\n\r\nMOUNT_CLASS_TO.getRichValue = getRichValue;\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 type EventListenerBase from \"./eventListenerBase\";\r\n\r\nexport type Listener = {\r\n element: ListenerElement, \r\n event: ListenerEvent, \r\n callback: ListenerCallback, \r\n options?: ListenerOptions,\r\n\r\n onceFired?: true, // will be set only when options.once is set\r\n onceCallback?: () => void,\r\n};\r\n\r\nexport type ListenerElement = Window | Document | HTMLElement | Element | EventListenerBase;\r\nexport type ListenerEvent = string;\r\nexport type ListenerCallback = Function;\r\nexport type ListenerOptions = AddEventListenerOptions;\r\n\r\n/* const originalAddEventListener = HTMLElement.prototype.addEventListener;\r\nHTMLElement.prototype.addEventListener = function(this, name: string, callback: EventListenerOrEventListenerObject, options: AddEventListenerOptions) {\r\n console.log('nu zdarova', name);\r\n originalAddEventListener.call(this, name, callback, options);\r\n\r\n if(options?.ls) {\r\n return options.ls.addFromElement(this, name, callback as any, options);\r\n }\r\n}; */\r\n\r\nexport default class ListenerSetter {\r\n private listeners: Set = new Set();\r\n\r\n public add(element: T): T['addEventListener'] {\r\n return ((event: string, callback: Function, options: ListenerOptions) => {\r\n const listener: Listener = {element, event, callback, options};\r\n this.addManual(listener);\r\n return listener;\r\n }) as any;\r\n }\r\n\r\n /* public addFromElement(element: T, event: ListenerEvent, callback: ListenerCallback, options: ListenerOptions) {\r\n const listener: Listener = {element, event, callback, options};\r\n this.addManual(listener);\r\n return listener;\r\n } */\r\n\r\n public addManual(listener: Listener) {\r\n // @ts-ignore\r\n listener.element.addEventListener(listener.event, listener.callback, listener.options);\r\n\r\n if(listener.options?.once) { // remove listener when its called\r\n listener.onceCallback = () => {\r\n this.remove(listener);\r\n listener.onceFired = true;\r\n };\r\n \r\n // @ts-ignore\r\n listener.element.addEventListener(listener.event, listener.onceCallback, listener.options);\r\n }\r\n\r\n this.listeners.add(listener);\r\n }\r\n\r\n public remove(listener: Listener) {\r\n if(!listener.onceFired) {\r\n // @ts-ignore\r\n listener.element.removeEventListener(listener.event, listener.callback, listener.options);\r\n\r\n if(listener.onceCallback) {\r\n // @ts-ignore\r\n listener.element.removeEventListener(listener.event, listener.onceCallback, listener.options);\r\n }\r\n }\r\n\r\n this.listeners.delete(listener);\r\n }\r\n\r\n public removeManual(\r\n element: T, \r\n event: ListenerEvent, \r\n callback: ListenerCallback, \r\n options?: ListenerOptions\r\n ) {\r\n let listener: Listener;\r\n for(const _listener of this.listeners) {\r\n if(_listener.element === element && \r\n _listener.event === event && \r\n _listener.callback === callback && \r\n _listener.options === options) {\r\n listener = _listener;\r\n break;\r\n }\r\n }\r\n\r\n if(listener) {\r\n this.remove(listener);\r\n }\r\n }\r\n\r\n public removeAll() {\r\n this.listeners.forEach(listener => {\r\n this.remove(listener);\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\nexport default function findUpAttribute(el: any, attribute: string): HTMLElement {\r\n return el.closest(`[${attribute}]`);\r\n /* if(el.getAttribute(attribute) !== null) return el; // 03.02.2020\r\n\r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.getAttribute(attribute) !== null) \r\n return el;\r\n }\r\n return null; */\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov \r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport { MessageEntity } from \"../../layer\";\r\n\r\nexport type MarkdownType = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'monospace' | 'link' | 'mentionName' | 'spoiler';\r\nexport type MarkdownTag = {\r\n match: string,\r\n entityName: Extract;\r\n};\r\n\r\n// https://core.telegram.org/bots/api#html-style\r\nexport const markdownTags: {[type in MarkdownType]: MarkdownTag} = {\r\n bold: {\r\n match: '[style*=\"bold\"], [style*=\"font-weight: 700\"], [style*=\"font-weight: 600\"], [style*=\"font-weight:700\"], [style*=\"font-weight:600\"], b, strong',\r\n entityName: 'messageEntityBold'\r\n },\r\n underline: {\r\n match: '[style*=\"underline\"], u, ins',\r\n entityName: 'messageEntityUnderline'\r\n },\r\n italic: {\r\n match: '[style*=\"italic\"], i, em',\r\n entityName: 'messageEntityItalic'\r\n },\r\n monospace: {\r\n match: '[style*=\"monospace\"], [face=\"monospace\"], pre',\r\n entityName: 'messageEntityPre'\r\n },\r\n strikethrough: {\r\n match: '[style*=\"line-through\"], strike, del, s',\r\n entityName: 'messageEntityStrike'\r\n },\r\n link: {\r\n match: 'A:not(.follow)',\r\n entityName: 'messageEntityTextUrl'\r\n },\r\n mentionName: {\r\n match: 'A.follow',\r\n entityName: 'messageEntityMentionName'\r\n },\r\n spoiler: {\r\n match: '[style*=\"spoiler\"]',\r\n entityName: 'messageEntitySpoiler'\r\n }\r\n};\r\n\r\nconst tabulationMatch = '[style*=\"table-cell\"], th, td';\r\n\r\n/* export function getDepth(child: Node, container?: Node) {\r\n let depth = 0;\r\n\r\n do {\r\n if(child === container) {\r\n return depth;\r\n }\r\n\r\n ++depth;\r\n } while((child = child.parentNode) !== null);\r\n\r\n return depth;\r\n} */\r\n\r\nconst BLOCK_TAG_NAMES = new Set([\r\n 'DIV',\r\n 'P',\r\n 'BR',\r\n 'LI',\r\n 'SECTION',\r\n 'H6',\r\n 'H5',\r\n 'H4',\r\n 'H3',\r\n 'H2',\r\n 'H1',\r\n 'TR'\r\n]);\r\n\r\nexport default function getRichElementValue(node: HTMLElement, lines: string[], line: string[], selNode?: Node, selOffset?: number, entities?: MessageEntity[], offset = {offset: 0}) {\r\n if(node.nodeType === 3) { // TEXT\r\n let nodeValue = node.nodeValue;\r\n\r\n /* const tabulation = node.parentElement?.closest(tabulationMatch + ', [contenteditable]');\r\n if(tabulation?.getAttribute('contenteditable') === null) {\r\n nodeValue += ' ';\r\n // line.push('\\t');\r\n // ++offset.offset;\r\n } */\r\n\r\n if(selNode === node) {\r\n line.push(nodeValue.substr(0, selOffset) + '\\x01' + nodeValue.substr(selOffset));\r\n } else {\r\n line.push(nodeValue);\r\n }\r\n\r\n if(entities && nodeValue.length) {\r\n if(node.parentNode) {\r\n const parentElement = node.parentElement;\r\n \r\n // let closestTag: MarkdownTag, closestElementByTag: Element, closestDepth = Infinity;\r\n for(const type in markdownTags) {\r\n const tag = markdownTags[type as MarkdownType];\r\n const closest = parentElement.closest(tag.match + ', [contenteditable]');\r\n if(closest?.getAttribute('contenteditable') !== null) {\r\n /* const depth = getDepth(closest, parentElement.closest('[contenteditable]'));\r\n if(closestDepth > depth) {\r\n closestDepth = depth;\r\n closestTag = tag;\r\n closestElementByTag = closest;\r\n } */\r\n continue;\r\n }\r\n\r\n if(tag.entityName === 'messageEntityTextUrl') {\r\n entities.push({\r\n _: tag.entityName,\r\n url: (closest as HTMLAnchorElement).href,\r\n offset: offset.offset,\r\n length: nodeValue.length\r\n });\r\n } else if(tag.entityName === 'messageEntityMentionName') {\r\n entities.push({\r\n _: tag.entityName,\r\n offset: offset.offset,\r\n length: nodeValue.length,\r\n user_id: (closest as HTMLElement).dataset.follow.toUserId()\r\n });\r\n } else {\r\n entities.push({\r\n _: tag.entityName as any,\r\n offset: offset.offset,\r\n length: nodeValue.length\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n offset.offset += nodeValue.length;\r\n return;\r\n }\r\n\r\n if(node.nodeType !== 1) { // NON-ELEMENT\r\n return;\r\n }\r\n\r\n const isSelected = selNode === node;\r\n const isBlock = BLOCK_TAG_NAMES.has(node.tagName);\r\n if(isBlock && line.length) {\r\n lines.push(line.join(''));\r\n line.splice(0, line.length);\r\n ++offset.offset;\r\n } else if(node instanceof HTMLImageElement) {\r\n const alt = node.alt;\r\n if(alt) {\r\n line.push(alt);\r\n offset.offset += alt.length;\r\n }\r\n }\r\n\r\n if(isSelected && !selOffset) {\r\n line.push('\\x01');\r\n }\r\n\r\n const isTableCell = node.matches(tabulationMatch);\r\n const wasEntitiesLength = entities?.length;\r\n\r\n let curChild = node.firstChild as HTMLElement;\r\n while(curChild) {\r\n getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);\r\n curChild = curChild.nextSibling as any;\r\n }\r\n\r\n if(isSelected && selOffset) {\r\n line.push('\\x01');\r\n }\r\n\r\n if(isTableCell && node.nextSibling) {\r\n line.push(' ');\r\n ++offset.offset;\r\n\r\n // * combine entities such as url after adding space\r\n if(wasEntitiesLength !== undefined) {\r\n for(let i = wasEntitiesLength, length = entities.length; i < length; ++i) {\r\n ++entities[i].length;\r\n }\r\n }\r\n }\r\n\r\n const wasLength = line.length;\r\n if(isBlock && wasLength) {\r\n lines.push(line.join(''));\r\n line.splice(0, wasLength);\r\n ++offset.offset;\r\n }\r\n\r\n if(wasLength && node.tagName === 'P' && node.nextSibling) {\r\n lines.push('');\r\n ++offset.offset;\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 type { DownloadOptions } from \"../mtproto/apiFileManager\";\r\nimport type { ApiError } from \"../mtproto/apiManager\";\r\nimport type { MyDocument } from \"./appDocsManager\";\r\nimport type { MyPhoto } from \"./appPhotosManager\";\r\nimport rootScope from \"../rootScope\";\r\nimport apiManager from \"../mtproto/mtprotoworker\";\r\nimport { deferredPromise, CancellablePromise } from \"../../helpers/cancellablePromise\";\r\nimport { InputFile } from \"../../layer\";\r\nimport { getFileNameByLocation } from \"../../helpers/fileName\";\r\nimport CacheStorageController from \"../cacheStorage\";\r\nimport { MOUNT_CLASS_TO } from \"../../config/debug\";\r\n\r\nexport type ResponseMethodBlob = 'blob';\r\nexport type ResponseMethodJson = 'json';\r\nexport type ResponseMethod = ResponseMethodBlob | ResponseMethodJson;\r\n\r\n/* export type DownloadBlob = {promise: Promise, controller: AbortController};\r\nexport type DownloadJson = {promise: Promise, controller: AbortController}; */\r\nexport type DownloadBlob = CancellablePromise;\r\nexport type DownloadJson = CancellablePromise;\r\n//export type Download = DownloadBlob/* | DownloadJson */;\r\nexport type Download = DownloadBlob/* | DownloadJson */;\r\n\r\nexport type Progress = {done: number, fileName: string, total: number, offset: number};\r\nexport type ProgressCallback = (details: Progress) => void;\r\n\r\nexport type ThumbCache = {\r\n downloaded: number, \r\n url: string\r\n};\r\n\r\nexport type ThumbsCache = {\r\n [id: string]: {\r\n [size: string]: ThumbCache\r\n }\r\n};\r\n\r\nexport class AppDownloadManager {\r\n public cacheStorage = new CacheStorageController('cachedFiles');\r\n private downloads: {[fileName: string]: Download} = {};\r\n private progress: {[fileName: string]: Progress} = {};\r\n private progressCallbacks: {[fileName: string]: Array} = {};\r\n\r\n private uploadId = 0;\r\n\r\n private thumbsCache: {\r\n photo: ThumbsCache,\r\n document: ThumbsCache\r\n } = {\r\n photo: {},\r\n document: {}\r\n };\r\n\r\n constructor() {\r\n rootScope.addEventListener('download_progress', (e) => {\r\n const details = e as {done: number, fileName: string, total: number, offset: number};\r\n this.progress[details.fileName] = details;\r\n\r\n const callbacks = this.progressCallbacks[details.fileName];\r\n if(callbacks) {\r\n callbacks.forEach(callback => callback(details));\r\n }\r\n\r\n const download = this.downloads[details.fileName];\r\n if(download) {\r\n download.notifyAll(details);\r\n }\r\n });\r\n }\r\n\r\n private getNewDeferred(fileName: string) {\r\n const deferred = deferredPromise();\r\n\r\n deferred.cancel = () => {\r\n //try {\r\n const error = new Error('Download canceled');\r\n error.name = 'AbortError';\r\n \r\n apiManager.cancelDownload(fileName);\r\n \r\n deferred.reject(error);\r\n deferred.cancel = () => {};\r\n /* } catch(err) {\r\n\r\n } */\r\n };\r\n\r\n deferred.finally(() => {\r\n delete this.progress[fileName];\r\n delete this.progressCallbacks[fileName];\r\n });\r\n\r\n deferred.catch(() => {\r\n this.clearDownload(fileName);\r\n });\r\n\r\n return this.downloads[fileName] = deferred as any;\r\n }\r\n\r\n private clearDownload(fileName: string) {\r\n delete this.downloads[fileName];\r\n }\r\n\r\n public fakeDownload(fileName: string, value: Blob | string) {\r\n const deferred = this.getNewDeferred(fileName);\r\n if(typeof(value) === 'string') {\r\n fetch(value)\r\n .then(response => response.blob())\r\n .then(blob => deferred.resolve(blob));\r\n } else {\r\n deferred.resolve(value);\r\n }\r\n\r\n return deferred;\r\n }\r\n\r\n public download(options: DownloadOptions): DownloadBlob {\r\n const fileName = getFileNameByLocation(options.location, {fileName: options.fileName});\r\n if(this.downloads.hasOwnProperty(fileName)) return this.downloads[fileName];\r\n\r\n const deferred = this.getNewDeferred(fileName);\r\n\r\n const onError = (err: ApiError) => {\r\n deferred.reject(err);\r\n };\r\n\r\n const tryDownload = (): Promise => {\r\n //return Promise.resolve();\r\n\r\n if(!apiManager.worker || options.onlyCache) {\r\n const promise = this.cacheStorage.getFile(fileName).then((blob) => {\r\n if(blob.size < options.size) throw 'wrong size';\r\n else deferred.resolve(blob);\r\n });\r\n \r\n if(options.onlyCache) return promise.catch(onError);\r\n return promise.catch(() => {\r\n return apiManager.downloadFile(options).then(deferred.resolve, onError);\r\n });\r\n } else {\r\n /* return apiManager.downloadFile(options).then(res => {\r\n setTimeout(() => deferred.resolve(res), 5e3);\r\n }, onError); */\r\n\r\n return apiManager.downloadFile(options).then(deferred.resolve, onError);\r\n }\r\n };\r\n\r\n tryDownload();\r\n\r\n //console.log('Will download file:', fileName, url);\r\n return deferred;\r\n }\r\n\r\n public upload(file: File | Blob, fileName?: string) {\r\n if(!fileName) {\r\n const mimeType = file?.type;\r\n if(mimeType) { // the same like apiFileName in appMessagesManager for upload!\r\n const ext = this.uploadId++ + '.' + mimeType.split('/')[1];\r\n \r\n if(['image/jpeg', 'image/png', 'image/bmp'].indexOf(mimeType) >= 0) {\r\n fileName = 'photo' + ext;\r\n } else if(mimeType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(mimeType) >= 0) {\r\n fileName = 'audio' + ext;\r\n } else if(mimeType.indexOf('video/') === 0) {\r\n fileName = 'video' + ext;\r\n } else {\r\n fileName = 'document' + ext;\r\n }\r\n \r\n } else {\r\n fileName = 'upload-' + this.uploadId++;\r\n }\r\n }\r\n\r\n const deferred = this.getNewDeferred(fileName);\r\n apiManager.uploadFile({file, fileName}).then(deferred.resolve, deferred.reject);\r\n\r\n deferred.finally(() => {\r\n this.clearDownload(fileName);\r\n });\r\n\r\n return deferred as any as CancellablePromise;\r\n }\r\n\r\n public getDownload(fileName: string) {\r\n return this.downloads[fileName];\r\n }\r\n\r\n public addProgressCallback(fileName: string, callback: ProgressCallback) {\r\n const progress = this.progress[fileName];\r\n (this.progressCallbacks[fileName] ?? (this.progressCallbacks[fileName] = [])).push(callback);\r\n\r\n if(progress) {\r\n callback(progress);\r\n }\r\n }\r\n\r\n public createDownloadAnchor(url: string, fileName: string, onRemove?: () => void) {\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = fileName;\r\n a.target = '_blank';\r\n \r\n a.style.position = 'absolute';\r\n a.style.top = '1px';\r\n a.style.left = '1px';\r\n \r\n document.body.append(a);\r\n \r\n try {\r\n var clickEvent = document.createEvent('MouseEvents');\r\n clickEvent.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\r\n a.dispatchEvent(clickEvent);\r\n } catch (e) {\r\n console.error('Download click error', e);\r\n try {\r\n a.click();\r\n } catch (e) {\r\n window.open(url as string, '_blank');\r\n }\r\n }\r\n \r\n setTimeout(() => {\r\n a.remove();\r\n onRemove && onRemove();\r\n }, 100);\r\n }\r\n\r\n /* public downloadToDisc(fileName: string, url: string) {\r\n this.createDownloadAnchor(url);\r\n \r\n return this.download(fileName, url);\r\n } */\r\n\r\n public downloadToDisc(options: DownloadOptions, discFileName: string) {\r\n const download = this.download(options);\r\n download/* .promise */.then(blob => {\r\n const objectURL = URL.createObjectURL(blob);\r\n this.createDownloadAnchor(objectURL, discFileName, () => {\r\n URL.revokeObjectURL(objectURL);\r\n });\r\n });\r\n \r\n return download;\r\n }\r\n\r\n public getCacheContext(media: MyPhoto | MyDocument, thumbSize: string = 'full'): ThumbCache {\r\n /* if(media._ === 'photo' && thumbSize !== 'i') {\r\n thumbSize = 'full';\r\n } */\r\n\r\n const cache = this.thumbsCache[media._][media.id] ?? (this.thumbsCache[media._][media.id] = {});\r\n return cache[thumbSize] ?? (cache[thumbSize] = {downloaded: 0, url: ''});\r\n }\r\n}\r\n\r\nconst appDownloadManager = new AppDownloadManager();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.appDownloadManager = appDownloadManager);\r\nexport default appDownloadManager;\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 getRichValue from \"./getRichValue\";\r\n\r\nexport default function isInputEmpty(element: HTMLElement) {\r\n if(element.hasAttribute('contenteditable') || element.tagName !== 'INPUT') {\r\n /* const value = element.innerText;\r\n\r\n return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */\r\n return !getRichValue(element, false).value.trim();\r\n } else {\r\n return !(element as HTMLInputElement).value.trim();\r\n }\r\n}\r\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// import { IS_WEB_WORKER } from \"../context\";\n\n// const id = IS_WEB_WORKER ? Math.random() * 0x1000 | 0 : 0;\nexport default function readBlobAs(blob: Blob, method: 'readAsText'): Promise;\nexport default function readBlobAs(blob: Blob, method: 'readAsDataURL'): Promise;\nexport default function readBlobAs(blob: Blob, method: 'readAsArrayBuffer'): Promise;\nexport default function readBlobAs(blob: Blob, method: 'readAsArrayBuffer' | 'readAsText' | 'readAsDataURL'): Promise {\n // const perf = performance.now();\n return new Promise((resolve) => {\n const reader = new FileReader();\n reader.addEventListener('loadend', (e) => {\n // console.log(`readBlobAs [${id}] ${method} time ${performance.now() - perf}`);\n resolve(e.target.result);\n });\n reader[method](blob);\n });\n}\n"],"sourceRoot":""}