1 line
142 KiB
Plaintext
1 line
142 KiB
Plaintext
{"version":3,"sources":["webpack:///./src/components/languageChangeButton.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/fixBase64String.ts","webpack:///./src/helpers/bytes/bytesCmp.ts","webpack:///./src/components/telInputField.ts","webpack:///./src/components/monkeys/tracking.ts","webpack:///./src/components/codeInputField.ts","webpack:///./src/helpers/bytes/bytesToBase64.ts","webpack:///./src/pages/pageSignQR.ts","webpack:///./src/pages/pageSignIn.ts","webpack:///./src/pages/pageAuthCode.ts","webpack:///./src/helpers/dom/replaceContent.ts","webpack:///./src/components/inputField.ts","webpack:///./src/helpers/dom/selectElementContents.ts","webpack:///./src/components/scrollable.ts","webpack:///./src/components/checkboxField.ts","webpack:///./src/components/singleTransition.ts","webpack:///./src/helpers/dom/toggleDisability.ts","webpack:///./src/helpers/dom/getRichValue.ts","webpack:///./src/helpers/dom/findUpTag.ts","webpack:///./src/helpers/dom/findUpAttribute.ts","webpack:///./src/helpers/dom/getRichElementValue.ts","webpack:///./src/helpers/dom/isInputEmpty.ts","webpack:///./src/lib/mtproto/serverTimeManager.ts","webpack:///./src/helpers/dom/placeCaretAtEnd.ts","webpack:///./src/helpers/formatPhoneNumber.ts","webpack:///./src/helpers/blob/readBlobAs.ts"],"names":["cachedPromise","set","getLanguageChangeButton","appendTo","getConfig","then","config","suggested_lang_code","lastRequestedLangCode","Promise","all","getStrings","getCacheLangPack","strings","backup","forEach","string","backupString","get","key","push","btnChangeLanguage","text","lastElementChild","classList","remove","window","requestAnimationFrame","append","addEventListener","once","e","disabled","getLangPack","readBlobAsUint8Array","blob","readBlobAs","readBlobAsArrayBuffer","buffer","Uint8Array","blobSupported","blobConstruct","this","fileWriter","bytes","Blob","arr","write","mimeType","saveFileCallback","blobParts","part","truncate","length","finalize","saveToStorage","dbName","useStorage","test","STORAGES","openDatabase","openDbPromise","caches","open","entryName","timeoutOperation","cache","delete","match","response","put","fileName","method","Response","headers","size","save","callback","resolve","reject","rejected","timeout","setTimeout","undefined","res","err","clearTimeout","fakeWriter","getFakeFileWriter","saveFile","catch","enabled","map","storage","deleteAll","fixBase64String","str","toUrl","replace","bytesCmp","bytes1","bytes2","len","i","TelInputField","options","super","label","name","pasted","lastValue","container","add","telEl","input","HTMLInputElement","type","autocomplete","inputMode","pixelRatio","devicePixelRatio","letterSpacing","style","setProperty","originalFunc","setValueSilently","bind","value","formattedPhoneNumber","Math","abs","setLabel","formatted","country","countryCode","leftPattern","code","dataset","onInput","metaKey","ctrlKey","shiftKey","preventDefault","TrackingMonkey","inputField","max","needFrame","document","createElement","playAnimation","animation","frame","min","round","idleAnimation","stop","canvas","display","direction","setDirection","setSpeed","play","loadPromise","loadAnimationAsAsset","loop","autoplay","width","height","waitForFirstFrame","_animation","currentFrame","pause","CodeInputField","plainText","setAttribute","lastLength","slice","onFill","uint6ToBase64","nUint6","onFirstMount","imageDiv","pageEl","querySelector","preloader","inputWrapper","btnBack","parentElement","h4","helpList","li","m","default","mount","QRCodeStyling","rootScope","prevToken","ignoreErrors","iterate","isLoop","loginToken","invokeApi","api_id","id","api_hash","hash","except_ids","_","dcId","dc_id","setBaseDcId","token","authorization","setUser","user","encoded","mod3","result","nLen","nUint24","nIdx","String","fromCharCode","bytesToBase64","url","getComputedStyle","documentElement","surfaceColor","getPropertyValue","trim","textColor","primaryColor","logoUrl","fetch","reader","FileReader","onload","target","readAsDataURL","qrCode","data","image","dotsOptions","color","cornersSquareOptions","imageOptions","imageSize","margin","backgroundOptions","qrOptions","errorCorrectionLevel","promise","lastChild","_drawingPromise","race","_canvas","_image","c","children","Array","from","el","timestamp","Date","now","diff","expires","serverTimeManager","serverTimeOffset","console","warn","handled","error","func","appStateManager","pushToState","btnQr","btnNext","page","setCountries","countries","countriesList","filter","pFlags","hidden","sort","a","b","default_name","localeCompare","liMap","Map","lastCountrySelected","lastCountryCodeSelected","countryInputField","countryInput","selectWrapper","arrowDown","selectList","appendChild","initSelect","emoji","iso2","liArr","country_codes","wrapped","wrapEmojiText","spanEmoji","innerHTML","defaultName","span","innerText","country_code","button","selectCountryByTarget","childNodes","phoneCode","find","_countryCode","telInputField","hidePicker","focus","hideTimeout","offsetWidth","select","element","position","mouseDownHandlerAttached","onMouseDown","capture","removeEventListener","_value","toLowerCase","matches","names","Boolean","abbr","split","word","join","good","indexOf","cancelBubble","blur","loadLottieWorkers","countryName","visibility","onSubmit","signedCheckboxField","withRipple","checked","keepSigned","toggleStorage","getState","state","isAvailable","toggle","phone_number","settings","Object","assign","setError","subtitle","nearestDcResult","langPack","getFromCache","lang_code","dcs","Set","done","this_dc","nearest_dc","getNetworker","_dcs","g","shift","dbKey","finally","removeAttribute","codeInput","authCode","headerElement","sentTypeElement","CODELENGTH","codeInputField","submitCode","cleanup","monkey","params","phone_code_hash","phone_code","isMobile","load","_authCode","evt","createEvent","initEvent","dispatchEvent","getElementsByClassName","args","sentCode","replaceContent","elem","node","firstChild","replaceWith","textContent","init","findUpAttribute","entities","originalEvent","clipboardData","getData","usePlainText","html","curChild","nextSibling","nodeType","nodeValue","richValue","getRichValue","entities2","parseEntities","mergeEntities","wrapDraftText","execCommand","InputState","required","validate","maxLength","showLengthOn","placeholder","canBeEdited","processInput","labelText","firstElementChild","observer","MutationObserver","isInputEmpty","inputFake","onFakeInput","observe","characterData","childList","subtree","animate","className","border","labelEl","showingLength","wasError","contains","inputLength","isError","range","createRange","selectNodeContents","sel","getSelection","removeAllRanges","addRange","selectElementContents","labelOptions","setHeight","scrollHeight","newHeight","currentHeight","transitionDuration","log","fireFakeInput","originalValue","isValid","isChanged","silent","setDraftValue","Error","Valid","setState","ScrollableBase","logPrefix","onScrollMeasure","lastScrollPosition","lastScrollDirection","isHeavyAnimationInProgress","needCheckAfterAnimation","onScroll","cancelAnimationFrame","onScrolledTop","onScrolledBottom","splitUp","onAdditionalScroll","scrollPosition","scrollProperty","checkForTriggers","removeHeavyAnimationListener","passive","Scrollable","onScrollOffset","withPaddingContainer","loadedAll","top","bottom","maxScrollTop","clientHeight","scrollTop","setListeners","elements","padding","prepend","offsetHeight","getDistanceToEnd","y","ScrollableX","splitCount","scrollHorizontally","deltaX","scrollWidth","clientWidth","scrollLeft","deltaY","CheckboxField","restriction","toggleDisability","stateKey","stateValue","stateValues","setByKey","textArgs","box","checkSvg","createElementNS","setAttributeNS","use","bg","withHover","event","Event","bubbles","cancelable","disable","SetTransition","forwards","duration","onTransitionEnd","useRafs","raf","animationsEnabled","afterTimeout","field","withEntities","lines","line","combineSameEntities","sortEntities","findUpTag","tag","closest","attribute","markdownTags","bold","entityName","underline","italic","monospace","strikethrough","link","mentionName","spoiler","BLOCK_TAG_NAMES","getRichElementValue","selNode","selOffset","offset","substr","parentNode","getAttribute","href","user_id","follow","toUserId","isSelected","isBlock","has","tagName","splice","HTMLImageElement","alt","isTableCell","wasEntitiesLength","wasLength","hasAttribute","to","addTaskListener","task","payload","placeCaretAtEnd","ignoreTouchCheck","activeElement","collapse","body","createTextRange","textRange","moveToElementText","prefixes","maxPrefixLength","setPrefix","prefix","formatPhoneNumber","originalStr","prefixCountry","patterns","searchForPattern","pattern","mostMatchedPatternMatches","mostMatchedPattern","_pattern","patternMatches","k","symbol","idx"],"mappings":"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","file":"12.80bb19e8233c326e70e4.chunk.js","sourcesContent":["/*\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 { cancelEvent } from \"../helpers/dom/cancelEvent\";\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\nimport loadFonts from \"../helpers/dom/loadFonts\";\nimport { Config, LangPackDifference, LangPackString } from \"../layer\";\nimport I18n, { LangPackKey } from \"../lib/langPack\";\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\nimport rootScope from \"../lib/rootScope\";\nimport Button from \"./button\";\nimport { putPreloader } from \"./misc\";\n\nlet set = false;\n\nfunction getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {\n if(cachedPromise) return cachedPromise;\n return cachedPromise = apiManager.getConfig().then(config => {\n if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {\n //I18n.loadLangPack(config.suggested_lang_code);\n\n return Promise.all([\n config,\n I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),\n I18n.getCacheLangPack()\n ]);\n } else {\n return [] as any;\n }\n });\n}\n\nlet cachedPromise: ReturnType<typeof getLang>;\n\nexport default function getLanguageChangeButton(appendTo: HTMLElement) {\n if(set) return;\n getLang().then(([config, strings]) => {\n if(!config) {\n return;\n }\n\n const backup: LangPackString[] = [];\n strings.forEach(string => {\n const backupString = I18n.strings.get(string.key as LangPackKey);\n if(!backupString) {\n return;\n }\n \n backup.push(backupString);\n I18n.strings.set(string.key as LangPackKey, string);\n });\n\n const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});\n btnChangeLanguage.lastElementChild.classList.remove('i18n'); // prevent changing language\n loadFonts().then(() => {\n window.requestAnimationFrame(() => {\n appendTo.append(btnChangeLanguage);\n });\n });\n\n rootScope.addEventListener('language_change', () => {\n btnChangeLanguage.remove();\n }, {once: true});\n\n backup.forEach(string => {\n I18n.strings.set(string.key as LangPackKey, string);\n });\n \n attachClickEvent(btnChangeLanguage, (e) => {\n cancelEvent(e);\n\n set = true;\n\n btnChangeLanguage.disabled = true;\n putPreloader(btnChangeLanguage);\n\n I18n.getLangPack(config.suggested_lang_code);\n });\n });\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 <igor.beatle@gmail.com>\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<FileManager['getFakeFileWriter']>, bytes: Uint8Array | Blob | string): Promise<void> {\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<Blob>) {\r\n const blobParts: Array<Uint8Array | string> = [];\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<Cache>;\r\n\r\n private useStorage = true;\r\n\r\n //private log: ReturnType<typeof logger> = 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<Cache> {\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<any> {\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<T>(callback: (cache: Cache) => Promise<T>) {\r\n if(!this.useStorage) {\r\n return Promise.reject('STORAGE_OFFLINE');\r\n }\r\n\r\n return new Promise<T>(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","export default function fixBase64String(str: string, toUrl: boolean) {\n if(toUrl) {\n return str.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/\\=+$/, '');\n } else {\n return str.replace(/-/g, '+').replace(/_/g, '/');\n }\n}\n","export default function bytesCmp(bytes1: number[] | Uint8Array, bytes2: number[] | Uint8Array) {\n const len = bytes1.length;\n if(len !== bytes2.length) {\n return false;\n }\n\n for(let i = 0; i < len; ++i) {\n if(bytes1[i] !== bytes2[i]) {\n return false;\n }\n }\n\n return true;\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 placeCaretAtEnd from \"../helpers/dom/placeCaretAtEnd\";\nimport { formatPhoneNumber } from \"../helpers/formatPhoneNumber\";\nimport { IS_APPLE, IS_ANDROID, IS_APPLE_MOBILE } from \"../environment/userAgent\";\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\nimport InputField, { InputFieldOptions } from \"./inputField\";\n\nexport default class TelInputField extends InputField {\n private pasted = false;\n public lastValue = '';\n \n constructor(options: InputFieldOptions & {\n onInput?: (formatted: ReturnType<typeof formatPhoneNumber>) => void\n } = {}) {\n super({\n label: 'Contacts.PhoneNumber.Placeholder',\n //plainText: true,\n name: 'phone',\n ...options\n });\n\n this.container.classList.add('input-field-phone');\n\n let telEl = this.input;\n if(telEl instanceof HTMLInputElement) {\n telEl.type = 'tel';\n telEl.autocomplete = 'rr55RandomRR55';\n } else {\n telEl.inputMode = 'decimal';\n\n const pixelRatio = window.devicePixelRatio;\n if(pixelRatio > 1) {\n let letterSpacing: number;\n if(IS_APPLE) {\n letterSpacing = pixelRatio * -.16;\n } else if(IS_ANDROID) {\n letterSpacing = 0;\n }\n\n telEl.style.setProperty('--letter-spacing', letterSpacing + 'px');\n }\n\n const originalFunc = this.setValueSilently.bind(this);\n this.setValueSilently = (value) => {\n originalFunc(value);\n placeCaretAtEnd(this.input, true);\n };\n }\n\n telEl.addEventListener('input', () => {\n //console.log('input', this.value);\n telEl.classList.remove('error');\n \n const value = this.value;\n const diff = Math.abs(value.length - this.lastValue.length);\n if(diff > 1 && !this.pasted && IS_APPLE_MOBILE) {\n this.setValueSilently(this.lastValue + value);\n }\n \n this.pasted = false;\n \n this.setLabel();\n \n let formattedPhoneNumber: ReturnType<typeof formatPhoneNumber>;\n let formatted: string, country: HelpCountry, countryCode: HelpCountryCode, leftPattern = '';\n if(this.value.replace(/\\++/, '+') === '+') {\n this.setValueSilently('+');\n } else {\n formattedPhoneNumber = formatPhoneNumber(this.value);\n formatted = formattedPhoneNumber.formatted;\n country = formattedPhoneNumber.country;\n leftPattern = formattedPhoneNumber.leftPattern;\n countryCode = formattedPhoneNumber.code;\n this.setValueSilently(this.lastValue = formatted ? '+' + formatted : '');\n }\n \n telEl.dataset.leftPattern = leftPattern/* .replace(/X/g, '0') */;\n \n //console.log(formatted, country);\n\n options.onInput && options.onInput(formattedPhoneNumber);\n });\n \n telEl.addEventListener('paste', () => {\n this.pasted = true;\n //console.log('paste', telEl.value);\n });\n \n /* telEl.addEventListener('change', (e) => {\n console.log('change', telEl.value);\n }); */\n \n telEl.addEventListener('keypress', (e) => {\n //console.log('keypress', this.value);\n const key = e.key;\n if(/\\D/.test(key) && !(e.metaKey || e.ctrlKey) && key !== 'Backspace' && !(key === '+' && e.shiftKey/* && !this.value */)) {\n e.preventDefault();\n return false;\n }\n });\n \n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\n this.removeAttribute('readonly'); // fix autocomplete\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 InputField from \"../inputField\";\r\nimport lottieLoader from \"../../lib/rlottie/lottieLoader\";\r\nimport RLottiePlayer from \"../../lib/rlottie/rlottiePlayer\";\r\n\r\nexport default class TrackingMonkey {\r\n public container: HTMLElement;\r\n\r\n protected max = 45;\r\n protected needFrame = 0;\r\n\r\n protected animation: RLottiePlayer;\r\n protected idleAnimation: RLottiePlayer;\r\n\r\n protected loadPromise: Promise<any>;\r\n\r\n constructor(protected inputField: InputField, protected size: number) {\r\n this.container = document.createElement('div');\r\n this.container.classList.add('media-sticker-wrapper');\r\n\r\n const input = inputField.input;\r\n\r\n input.addEventListener('blur', () => {\r\n this.playAnimation(0);\r\n });\r\n\r\n input.addEventListener('input', (e) => {\r\n this.playAnimation(inputField.value.length);\r\n });\r\n\r\n /* codeInput.addEventListener('focus', () => {\r\n playAnimation(Math.max(codeInput.value.length, 1));\r\n }); */\r\n }\r\n\r\n // 1st symbol = frame 15\r\n // end symbol = frame 165\r\n public playAnimation(length: number) {\r\n if(!this.animation) return;\r\n\r\n length = Math.min(length, 30);\r\n let frame: number;\r\n if(length) {\r\n frame = Math.round(Math.min(this.max, length) * (165 / this.max) + 11.33);\r\n\r\n if(this.idleAnimation) {\r\n this.idleAnimation.stop(true);\r\n this.idleAnimation.canvas.style.display = 'none';\r\n }\r\n \r\n this.animation.canvas.style.display = '';\r\n } else {\r\n /* const cb = (frameNo: number) => {\r\n if(frameNo <= 1) { */\r\n /* idleAnimation.play();\r\n idleAnimation.canvas.style.display = '';\r\n animation.canvas.style.display = 'none'; */\r\n /* animation.removeListener('enterFrame', cb);\r\n }\r\n };\r\n animation.addListener('enterFrame', cb); */\r\n \r\n frame = 0;\r\n }\r\n //animation.playSegments([1, 2]);\r\n\r\n const direction = this.needFrame > frame ? -1 : 1;\r\n //console.log('keydown', length, frame, direction);\r\n\r\n this.animation.setDirection(direction);\r\n if(this.needFrame !== 0 && frame === 0) {\r\n this.animation.setSpeed(7);\r\n }\r\n /* let diff = Math.abs(needFrame - frame * direction);\r\n if((diff / 20) > 1) animation.setSpeed(diff / 20 | 0); */\r\n this.needFrame = frame;\r\n \r\n this.animation.play();\r\n\r\n /* animation.goToAndStop(15, true); */\r\n //animation.goToAndStop(length / max * );\r\n }\r\n\r\n public load() {\r\n if(this.loadPromise) return this.loadPromise;\r\n return this.loadPromise = Promise.all([\r\n lottieLoader.loadAnimationAsAsset({\r\n container: this.container,\r\n loop: true,\r\n autoplay: true,\r\n width: this.size,\r\n height: this.size\r\n }, 'TwoFactorSetupMonkeyIdle').then(animation => {\r\n this.idleAnimation = animation;\r\n\r\n // ! animationIntersector will stop animation instantly\r\n if(!this.inputField.value.length) {\r\n animation.play();\r\n }\r\n\r\n return lottieLoader.waitForFirstFrame(animation);\r\n }),\r\n\r\n lottieLoader.loadAnimationAsAsset({\r\n container: this.container,\r\n loop: false,\r\n autoplay: false,\r\n width: this.size,\r\n height: this.size\r\n }, 'TwoFactorSetupMonkeyTracking').then(_animation => {\r\n this.animation = _animation;\r\n\r\n if(!this.inputField.value.length) {\r\n this.animation.canvas.style.display = 'none';\r\n }\r\n\r\n this.animation.addEventListener('enterFrame', currentFrame => {\r\n //console.log('enterFrame', currentFrame, needFrame);\r\n //let currentFrame = Math.round(e.currentTime);\r\n \r\n if((this.animation.direction === 1 && currentFrame >= this.needFrame) ||\r\n (this.animation.direction === -1 && currentFrame <= this.needFrame)) {\r\n this.animation.setSpeed(1);\r\n this.animation.pause();\r\n }\r\n\r\n if(currentFrame === 0 && this.needFrame === 0) {\r\n //animation.curFrame = 0;\r\n \r\n if(this.idleAnimation) {\r\n this.idleAnimation.canvas.style.display = '';\r\n this.idleAnimation.play();\r\n this.animation.canvas.style.display = 'none';\r\n }\r\n }\r\n });\r\n //console.log(animation.getDuration(), animation.getDuration(true));\r\n\r\n return lottieLoader.waitForFirstFrame(_animation);\r\n })\r\n ]);\r\n }\r\n\r\n public remove() {\r\n if(this.animation) this.animation.remove();\r\n if(this.idleAnimation) this.idleAnimation.remove();\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 InputField, { InputFieldOptions } from \"./inputField\";\r\n\r\nexport default class CodeInputField extends InputField {\r\n constructor(options: InputFieldOptions & {\r\n length: number,\r\n onFill: (code: string) => void\r\n }) {\r\n super({\r\n plainText: true,\r\n ...options\r\n });\r\n\r\n const input = this.input as HTMLInputElement;\r\n input.type = 'tel';\r\n input.setAttribute('required', '');\r\n input.autocomplete = 'off';\r\n\r\n let lastLength = 0;\r\n this.input.addEventListener('input', (e) => {\r\n this.input.classList.remove('error');\r\n this.setLabel();\r\n \r\n const value = this.value.replace(/\\D/g, '').slice(0, options.length);\r\n this.setValueSilently(value);\r\n \r\n const length = this.value.length;\r\n if(length === options.length) { // submit code\r\n options.onFill(this.value);\r\n } else if(length === lastLength) {\r\n return;\r\n }\r\n \r\n lastLength = length;\r\n });\r\n }\r\n}\r\n","export default function bytesToBase64(bytes: number[] | Uint8Array) {\n let mod3: number;\n let result = '';\n\n for(let nLen = bytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; ++nIdx) {\n mod3 = nIdx % 3;\n nUint24 |= bytes[nIdx] << (16 >>> mod3 & 24);\n if(mod3 === 2 || nLen - nIdx === 1) {\n result += String.fromCharCode(\n uint6ToBase64(nUint24 >>> 18 & 63),\n uint6ToBase64(nUint24 >>> 12 & 63),\n uint6ToBase64(nUint24 >>> 6 & 63),\n uint6ToBase64(nUint24 & 63)\n );\n nUint24 = 0;\n }\n }\n\n return result.replace(/A(?=A$|$)/g, '=');\n}\n\nexport function uint6ToBase64(nUint6: number) {\n return nUint6 < 26\n ? nUint6 + 65\n : nUint6 < 52\n ? nUint6 + 71\n : nUint6 < 62\n ? nUint6 - 4\n : nUint6 === 62\n ? 43\n : nUint6 === 63\n ? 47\n : 65;\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 { DcId } from '../types';\r\nimport type { ApiError } from '../lib/mtproto/apiManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport Page from './page';\r\nimport serverTimeManager from '../lib/mtproto/serverTimeManager';\r\nimport { AuthAuthorization, AuthLoginToken } from '../layer';\r\nimport App from '../config/app';\r\nimport Button from '../components/button';\r\nimport { _i18n, i18n, LangPackKey } from '../lib/langPack';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport rootScope from '../lib/rootScope';\r\nimport { putPreloader } from '../components/misc';\r\nimport getLanguageChangeButton from '../components/languageChangeButton';\r\nimport { pause } from '../helpers/schedulers/pause';\r\nimport fixBase64String from '../helpers/fixBase64String';\r\nimport bytesCmp from '../helpers/bytes/bytesCmp';\r\nimport bytesToBase64 from '../helpers/bytes/bytesToBase64';\r\n\r\nconst FETCH_INTERVAL = 3;\r\n\r\nlet onFirstMount = async() => {\r\n const pageElement = page.pageEl;\r\n const imageDiv = pageElement.querySelector('.auth-image') as HTMLDivElement;\r\n\r\n let preloader = putPreloader(imageDiv, true);\r\n\r\n const inputWrapper = document.createElement('div');\r\n inputWrapper.classList.add('input-wrapper');\r\n\r\n const btnBack = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Cancel'});\r\n inputWrapper.append(btnBack);\r\n\r\n getLanguageChangeButton(inputWrapper);\r\n\r\n const container = imageDiv.parentElement;\r\n\r\n const h4 = document.createElement('h4');\r\n _i18n(h4, 'Login.QR.Title');\r\n\r\n const helpList = document.createElement('ol');\r\n helpList.classList.add('qr-description');\r\n (['Login.QR.Help1', 'Login.QR.Help2', 'Login.QR.Help3'] as LangPackKey[]).forEach((key) => {\r\n const li = document.createElement('li');\r\n li.append(i18n(key));\r\n helpList.append(li);\r\n });\r\n\r\n container.append(h4, helpList, inputWrapper);\r\n\r\n btnBack.addEventListener('click', () => {\r\n import('./pageSignIn').then(m => m.default.mount());\r\n stop = true;\r\n });\r\n \r\n const results = await Promise.all([\r\n import('qr-code-styling' as any)\r\n ]);\r\n const QRCodeStyling = results[0].default;\r\n\r\n let stop = false;\r\n rootScope.addEventListener('user_auth', () => {\r\n stop = true;\r\n cachedPromise = null;\r\n }, {once: true});\r\n \r\n let options: {dcId?: DcId, ignoreErrors: true} = {ignoreErrors: true};\r\n let prevToken: Uint8Array | number[];\r\n\r\n const iterate = async(isLoop: boolean) => {\r\n try {\r\n let loginToken = await apiManager.invokeApi('auth.exportLoginToken', {\r\n api_id: App.id,\r\n api_hash: App.hash,\r\n except_ids: []\r\n }, {ignoreErrors: true});\r\n \r\n if(loginToken._ === 'auth.loginTokenMigrateTo') {\r\n if(!options.dcId) {\r\n options.dcId = loginToken.dc_id as DcId;\r\n apiManager.setBaseDcId(loginToken.dc_id);\r\n //continue;\r\n }\r\n \r\n loginToken = await apiManager.invokeApi('auth.importLoginToken', {\r\n token: loginToken.token\r\n }, options) as AuthLoginToken.authLoginToken;\r\n }\r\n\r\n if(loginToken._ === 'auth.loginTokenSuccess') {\r\n const authorization = loginToken.authorization as any as AuthAuthorization.authAuthorization;\r\n apiManager.setUser(authorization.user);\r\n import('./pageIm').then(m => m.default.mount());\r\n return true;\r\n }\r\n\r\n /* // to base64\r\n var decoder = new TextDecoder('utf8');\r\n var b64encoded = btoa(String.fromCharCode.apply(null, [...loginToken.token])); */\r\n\r\n if(!prevToken || !bytesCmp(prevToken, loginToken.token)) {\r\n prevToken = loginToken.token;\r\n\r\n let encoded = bytesToBase64(loginToken.token);\r\n let url = \"tg://login?token=\" + fixBase64String(encoded, true);\r\n\r\n const style = window.getComputedStyle(document.documentElement);\r\n const surfaceColor = style.getPropertyValue('--surface-color').trim();\r\n const textColor = style.getPropertyValue('--primary-text-color').trim();\r\n const primaryColor = style.getPropertyValue('--primary-color').trim();\r\n\r\n const logoUrl = await fetch('assets/img/logo_padded.svg')\r\n .then(res => res.text())\r\n .then(text => {\r\n text = text.replace(/(fill:).+?(;)/, `$1${primaryColor}$2`);\r\n const blob = new Blob([text], {type: 'image/svg+xml;charset=utf-8'});\r\n\r\n // * because iOS Safari doesn't want to eat objectURL\r\n return new Promise<string>((resolve) => {\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n resolve(e.target.result as string);\r\n };\r\n reader.readAsDataURL(blob);\r\n });\r\n //return URL.createObjectURL(blob);\r\n });\r\n\r\n const qrCode = new QRCodeStyling({\r\n width: 240 * window.devicePixelRatio,\r\n height: 240 * window.devicePixelRatio,\r\n data: url,\r\n image: logoUrl,\r\n dotsOptions: {\r\n color: textColor,\r\n type: 'rounded'\r\n },\r\n cornersSquareOptions: {\r\n type: 'extra-rounded'\r\n },\r\n imageOptions: {\r\n imageSize: 1,\r\n margin: 0\r\n },\r\n backgroundOptions: {\r\n color: surfaceColor\r\n },\r\n qrOptions: {\r\n errorCorrectionLevel: \"L\"\r\n }\r\n });\r\n\r\n qrCode.append(imageDiv);\r\n (imageDiv.lastChild as HTMLCanvasElement).classList.add('qr-canvas');\r\n\r\n let promise: Promise<void>;\r\n if(qrCode._drawingPromise) {\r\n promise = qrCode._drawingPromise;\r\n } else {\r\n promise = Promise.race([\r\n pause(1000),\r\n new Promise<void>((resolve) => {\r\n qrCode._canvas._image.addEventListener('load', () => {\r\n window.requestAnimationFrame(() => resolve());\r\n }, {once: true});\r\n })\r\n ]);\r\n }\r\n\r\n // * это костыль, но библиотека не предоставляет никаких событий\r\n await promise.then(() => {\r\n if(preloader) {\r\n preloader.style.animation = 'hide-icon .4s forwards';\r\n\r\n const c = imageDiv.children[1] as HTMLElement;\r\n c.style.display = 'none';\r\n c.style.animation = 'grow-icon .4s forwards';\r\n setTimeout(() => {\r\n c.style.display = '';\r\n }, 150);\r\n\r\n setTimeout(() => {\r\n c.style.animation = '';\r\n }, 500);\r\n preloader = undefined;\r\n } else {\r\n Array.from(imageDiv.children).slice(0, -1).forEach(el => {\r\n el.remove();\r\n });\r\n }\r\n });\r\n }\r\n\r\n if(isLoop) {\r\n let timestamp = Date.now() / 1000;\r\n let diff = loginToken.expires - timestamp - serverTimeManager.serverTimeOffset;\r\n \r\n await pause(diff > FETCH_INTERVAL ? 1e3 * FETCH_INTERVAL : 1e3 * diff | 0);\r\n }\r\n } catch(err) {\r\n switch((err as ApiError).type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n console.warn('pageSignQR: SESSION_PASSWORD_NEEDED');\r\n (err as ApiError).handled = true;\r\n import('./pagePassword').then(m => m.default.mount());\r\n stop = true;\r\n cachedPromise = null;\r\n break;\r\n default:\r\n console.error('pageSignQR: default error:', err);\r\n stop = true;\r\n break;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n //await iterate(false);\r\n\r\n return async() => {\r\n stop = false;\r\n\r\n do {\r\n if(stop) {\r\n break;\r\n }\r\n \r\n const needBreak = await iterate(true);\r\n if(needBreak) {\r\n break;\r\n }\r\n } while(true);\r\n };\r\n};\r\n\r\nlet cachedPromise: Promise<() => Promise<void>>;\r\nconst page = new Page('page-signQR', true, () => {\r\n return cachedPromise;\r\n}, () => {\r\n //console.log('onMount');\r\n if(!cachedPromise) cachedPromise = onFirstMount();\r\n cachedPromise.then(func => {\r\n func();\r\n });\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignQr'});\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\nimport { putPreloader } from \"../components/misc\";\r\nimport Scrollable from '../components/scrollable';\r\nimport appStateManager from \"../lib/appManagers/appStateManager\";\r\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\r\nimport { RichTextProcessor } from '../lib/richtextprocessor';\r\nimport Page from \"./page\";\r\nimport InputField from \"../components/inputField\";\r\nimport CheckboxField from \"../components/checkboxField\";\r\nimport Button from \"../components/button\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport App from \"../config/app\";\r\nimport I18n, { _i18n, i18n } from \"../lib/langPack\";\r\nimport lottieLoader from \"../lib/rlottie/lottieLoader\";\r\nimport { ripple } from \"../components/ripple\";\r\nimport findUpTag from \"../helpers/dom/findUpTag\";\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport { randomLong } from \"../helpers/random\";\r\nimport AppStorage from \"../lib/storage\";\r\nimport CacheStorageController from \"../lib/cacheStorage\";\r\nimport pageSignQR from \"./pageSignQR\";\r\nimport getLanguageChangeButton from \"../components/languageChangeButton\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\r\nimport replaceContent from \"../helpers/dom/replaceContent\";\r\nimport toggleDisability from \"../helpers/dom/toggleDisability\";\r\nimport sessionStorage from \"../lib/sessionStorage\";\r\nimport { DcAuthKey } from \"../types\";\r\nimport placeCaretAtEnd from \"../helpers/dom/placeCaretAtEnd\";\r\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\r\nimport { getCountryEmoji } from \"../vendor/emoji\";\r\nimport simulateEvent from \"../helpers/dom/dispatchEvent\";\r\nimport stateStorage from \"../lib/stateStorage\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport TelInputField from \"../components/telInputField\";\r\nimport IS_EMOJI_SUPPORTED from \"../environment/emojiSupport\";\r\n\r\n//import _countries from '../countries_pretty.json';\r\nlet btnNext: HTMLButtonElement = null, btnQr: HTMLButtonElement;\r\n\r\nlet onFirstMount = () => {\r\n /* if(Modes.test) {\r\n Countries.push({\r\n _: 'help.country',\r\n default_name: 'Test Country',\r\n country_codes: [{\r\n _: 'help.countryCode',\r\n country_code: '999 66',\r\n patterns: ['999 66 XXX XX']\r\n }],\r\n iso2: 'KK'\r\n });\r\n \r\n console.log('Added test country to list!');\r\n } */\r\n\r\n //const countries: Country[] = _countries.default.filter(c => c.emoji);\r\n // const countries: Country[] = Countries.filter(c => c.emoji).sort((a, b) => a.name.localeCompare(b.name));\r\n // const countries = I18n.countriesList.filter(country => !country.pFlags?.hidden);\r\n const setCountries = () => {\r\n countries = I18n.countriesList\r\n .filter(country => !country.pFlags?.hidden)\r\n .sort((a, b) => (a.name || a.default_name).localeCompare(b.name || b.default_name));\r\n };\r\n let countries: HelpCountry.helpCountry[]; \r\n\r\n setCountries();\r\n\r\n rootScope.addEventListener('language_change', () => {\r\n setCountries();\r\n });\r\n\r\n const liMap: Map<string, HTMLLIElement[]> = new Map();\r\n\r\n let lastCountrySelected: HelpCountry, lastCountryCodeSelected: HelpCountryCode;\r\n\r\n const inputWrapper = document.createElement('div');\r\n inputWrapper.classList.add('input-wrapper');\r\n\r\n const countryInputField = new InputField({\r\n label: 'Login.CountrySelectorLabel',\r\n name: randomLong()\r\n });\r\n\r\n countryInputField.container.classList.add('input-select');\r\n\r\n const countryInput = countryInputField.input;\r\n // countryInput.autocomplete = randomLong();\r\n\r\n const selectWrapper = document.createElement('div');\r\n selectWrapper.classList.add('select-wrapper', 'z-depth-3', 'hide');\r\n\r\n const arrowDown = document.createElement('span');\r\n arrowDown.classList.add('arrow', 'arrow-down');\r\n countryInputField.container.append(arrowDown);\r\n\r\n const selectList = document.createElement('ul');\r\n selectWrapper.appendChild(selectList);\r\n\r\n const scroll = new Scrollable(selectWrapper);\r\n\r\n let initSelect = () => {\r\n initSelect = null;\r\n\r\n countries.forEach((c) => {\r\n const emoji = getCountryEmoji(c.iso2);\r\n\r\n const liArr: Array<HTMLLIElement> = [];\r\n c.country_codes.forEach((countryCode) => {\r\n const li = document.createElement('li');\r\n\r\n let wrapped = RichTextProcessor.wrapEmojiText(emoji);\r\n if(IS_EMOJI_SUPPORTED) {\r\n const spanEmoji = document.createElement('span');\r\n spanEmoji.innerHTML = wrapped;\r\n li.append(spanEmoji);\r\n } else {\r\n li.innerHTML = wrapped;\r\n }\r\n \r\n const el = i18n(c.default_name as any);\r\n el.dataset.defaultName = c.default_name;\r\n li.append(el);\r\n\r\n const span = document.createElement('span');\r\n span.classList.add('phone-code');\r\n span.innerText = '+' + countryCode.country_code;\r\n li.appendChild(span);\r\n\r\n liArr.push(li);\r\n selectList.append(li);\r\n });\r\n\r\n liMap.set(c.iso2, liArr);\r\n });\r\n \r\n selectList.addEventListener('mousedown', (e) => {\r\n if(e.button !== 0) { // other buttons but left shall not pass\r\n return;\r\n }\r\n \r\n const target = findUpTag(e.target, 'LI')\r\n selectCountryByTarget(target);\r\n //console.log('clicked', e, countryName, phoneCode);\r\n });\r\n\r\n countryInputField.container.appendChild(selectWrapper);\r\n };\r\n\r\n const selectCountryByTarget = (target: HTMLElement) => {\r\n const defaultName = (target.childNodes[1] as HTMLElement).dataset.defaultName;\r\n const phoneCode = target.querySelector<HTMLElement>('.phone-code').innerText;\r\n const countryCode = phoneCode.replace(/\\D/g, '');\r\n\r\n replaceContent(countryInput, i18n(defaultName as any));\r\n simulateEvent(countryInput, 'input');\r\n lastCountrySelected = countries.find(c => c.default_name === defaultName);\r\n lastCountryCodeSelected = lastCountrySelected.country_codes.find(_countryCode => _countryCode.country_code === countryCode);\r\n \r\n telInputField.value = telInputField.lastValue = phoneCode;\r\n hidePicker();\r\n setTimeout(() => {\r\n telEl.focus();\r\n placeCaretAtEnd(telEl, true);\r\n }, 0);\r\n };\r\n \r\n initSelect();\r\n\r\n let hideTimeout: number;\r\n\r\n countryInput.addEventListener('focus', function(this: typeof countryInput, e) {\r\n if(initSelect) {\r\n initSelect();\r\n } else {\r\n countries.forEach((c) => {\r\n liMap.get(c.iso2).forEach(li => li.style.display = '');\r\n });\r\n }\r\n\r\n clearTimeout(hideTimeout);\r\n hideTimeout = undefined;\r\n\r\n selectWrapper.classList.remove('hide');\r\n void selectWrapper.offsetWidth; // reflow\r\n selectWrapper.classList.add('active');\r\n\r\n countryInputField.select();\r\n\r\n fastSmoothScroll({\r\n container: page.pageEl.parentElement.parentElement, \r\n element: countryInput, \r\n position: 'start', \r\n margin: 4\r\n });\r\n\r\n setTimeout(() => {\r\n if(!mouseDownHandlerAttached) {\r\n document.addEventListener('mousedown', onMouseDown, {capture: true});\r\n mouseDownHandlerAttached = true;\r\n }\r\n }, 0);\r\n });\r\n\r\n let mouseDownHandlerAttached = false;\r\n const onMouseDown = (e: MouseEvent) => {\r\n if(findUpClassName(e.target, 'input-select')) {\r\n return;\r\n }\r\n if(e.target === countryInput) {\r\n return;\r\n }\r\n\r\n hidePicker();\r\n document.removeEventListener('mousedown', onMouseDown, {capture: true});\r\n mouseDownHandlerAttached = false;\r\n };\r\n\r\n const hidePicker = () => {\r\n if(hideTimeout !== undefined) return;\r\n selectWrapper.classList.remove('active');\r\n hideTimeout = window.setTimeout(() => {\r\n selectWrapper.classList.add('hide');\r\n hideTimeout = undefined;\r\n }, 200);\r\n };\r\n /* false && countryInput.addEventListener('blur', function(this: typeof countryInput, e) {\r\n hidePicker();\r\n \r\n e.cancelBubble = true;\r\n }, {capture: true}); */\r\n\r\n countryInput.addEventListener('keyup', (e) => {\r\n const key = e.key;\r\n if(e.ctrlKey || key === 'Control') return false;\r\n\r\n //let i = new RegExp('^' + this.value, 'i');\r\n let _value = countryInputField.value.toLowerCase();\r\n let matches: HelpCountry[] = [];\r\n countries.forEach((c) => {\r\n const names = [\r\n c.name, \r\n c.default_name,\r\n c.iso2\r\n ];\r\n\r\n names.filter(Boolean).forEach(name => {\r\n const abbr = name.split(' ').filter(word => /\\w/.test(word)).map(word => word[0]).join('');\r\n if(abbr.length > 1) {\r\n names.push(abbr);\r\n }\r\n });\r\n\r\n let good = !!names.filter(Boolean).find(str => str.toLowerCase().indexOf(_value) !== -1)/* === 0 */;//i.test(c.name);\r\n\r\n liMap.get(c.iso2).forEach(li => li.style.display = good ? '' : 'none');\r\n if(good) matches.push(c);\r\n });\r\n\r\n // Код ниже автоматически выберет страну если она осталась одна при поиске\r\n /* if(matches.length === 1 && matches[0].li.length === 1) {\r\n if(matches[0].name === lastCountrySelected) return false;\r\n //console.log('clicking', matches[0]);\r\n\r\n var clickEvent = document.createEvent('MouseEvents');\r\n clickEvent.initEvent('mousedown', true, true);\r\n matches[0].li[0].dispatchEvent(clickEvent);\r\n return false;\r\n } else */if(matches.length === 0) {\r\n countries.forEach((c) => {\r\n liMap.get(c.iso2).forEach(li => li.style.display = '');\r\n });\r\n } else if(matches.length === 1 && key === 'Enter') {\r\n selectCountryByTarget(liMap.get(matches[0].iso2)[0]);\r\n }\r\n });\r\n\r\n arrowDown.addEventListener('mousedown', function(this: typeof arrowDown, e) {\r\n e.cancelBubble = true;\r\n e.preventDefault();\r\n if(countryInput.matches(':focus')) countryInput.blur();\r\n else countryInput.focus();\r\n });\r\n\r\n const telInputField = new TelInputField({\r\n onInput: (formatted) => {\r\n lottieLoader.loadLottieWorkers();\r\n\r\n const {country, code} = formatted || {};\r\n let countryName = country ? country.name || country.default_name : ''/* 'Unknown' */;\r\n if(countryName !== countryInputField.value && (\r\n !lastCountrySelected || \r\n !country ||\r\n !code || (\r\n lastCountrySelected !== country && \r\n lastCountryCodeSelected.country_code !== code.country_code\r\n )\r\n )\r\n ) {\r\n replaceContent(countryInput, country ? i18n(country.default_name as any) : countryName);\r\n lastCountrySelected = country;\r\n lastCountryCodeSelected = code;\r\n }\r\n \r\n //if(country && (telInputField.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {\r\n if(country || (telInputField.value.length - 1) > 1) {\r\n btnNext.style.visibility = '';\r\n } else {\r\n btnNext.style.visibility = 'hidden';\r\n }\r\n }\r\n });\r\n\r\n const telEl = telInputField.input;\r\n\r\n telEl.addEventListener('keypress', (e) => {\r\n //console.log('keypress', this.value);\r\n if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key === 'Enter') {\r\n return onSubmit();\r\n }\r\n });\r\n\r\n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\r\n this.removeAttribute('readonly'); // fix autocomplete\r\n });*/\r\n\r\n const signedCheckboxField = new CheckboxField({\r\n text: 'Login.KeepSigned', \r\n name: 'keepSession',\r\n withRipple: true,\r\n checked: true\r\n });\r\n\r\n signedCheckboxField.input.addEventListener('change', () => {\r\n const keepSigned = signedCheckboxField.checked;\r\n appStateManager.pushToState('keepSigned', keepSigned);\r\n \r\n AppStorage.toggleStorage(keepSigned);\r\n CacheStorageController.toggleStorage(keepSigned);\r\n apiManager.toggleStorage(keepSigned);\r\n sessionStorage.toggleStorage(keepSigned);\r\n });\r\n\r\n appStateManager.getState().then(state => {\r\n if(!appStateManager.storage.isAvailable()) {\r\n signedCheckboxField.checked = false;\r\n signedCheckboxField.label.classList.add('checkbox-disabled');\r\n } else {\r\n signedCheckboxField.checked = state.keepSigned;\r\n }\r\n });\r\n\r\n btnNext = Button('btn-primary btn-color-primary', {text: 'Login.Next'});\r\n btnNext.style.visibility = 'hidden';\r\n\r\n const onSubmit = (e?: Event) => {\r\n if(e) {\r\n cancelEvent(e);\r\n }\r\n\r\n const toggle = toggleDisability([/* telEl, countryInput, */btnNext, btnQr], true);\r\n\r\n replaceContent(btnNext, i18n('PleaseWait'));\r\n putPreloader(btnNext);\r\n\r\n //return;\r\n\r\n let phone_number = telInputField.value;\r\n apiManager.invokeApi('auth.sendCode', {\r\n phone_number: phone_number,\r\n api_id: App.id,\r\n api_hash: App.hash,\r\n settings: {\r\n _: 'codeSettings' // that's how we sending Type\r\n }\r\n //lang_code: navigator.language || 'en'\r\n }).then((code) => {\r\n //console.log('got code', code);\r\n\r\n import('./pageAuthCode').then(m => m.default.mount(Object.assign(code, {phone_number: phone_number})));\r\n }).catch(err => {\r\n toggle();\r\n\r\n switch(err.type) {\r\n case 'PHONE_NUMBER_INVALID':\r\n telInputField.setError();\r\n replaceContent(telInputField.label, i18n('Login.PhoneLabelInvalid'));\r\n telEl.classList.add('error');\r\n replaceContent(btnNext, i18n('Login.Next'));\r\n break;\r\n default:\r\n console.error('auth.sendCode error:', err);\r\n btnNext.innerText = err.type;\r\n break;\r\n }\r\n });\r\n };\r\n\r\n attachClickEvent(btnNext, onSubmit);\r\n\r\n btnQr = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Login'});\r\n\r\n let qrMounted = false;\r\n btnQr.addEventListener('click', () => {\r\n pageSignQR.mount();\r\n /* const promise = import('./pageSignQR');\r\n btnQr.disabled = true;\r\n\r\n let preloaderDiv: HTMLElement;\r\n if(!qrMounted) {\r\n preloaderDiv = putPreloader(btnQr);\r\n qrMounted = true;\r\n }\r\n\r\n promise.then(module => {\r\n module.default.mount();\r\n\r\n setTimeout(() => {\r\n btnQr.removeAttribute('disabled');\r\n if(preloaderDiv) {\r\n preloaderDiv.remove();\r\n }\r\n }, 200);\r\n }); */\r\n });\r\n\r\n inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);\r\n\r\n const h4 = document.createElement('h4');\r\n h4.classList.add('text-center');\r\n _i18n(h4, 'Login.Title');\r\n\r\n const subtitle = document.createElement('div');\r\n subtitle.classList.add('subtitle', 'text-center');\r\n _i18n(subtitle, 'Login.StartText');\r\n\r\n page.pageEl.querySelector('.container').append(h4, subtitle, inputWrapper);\r\n\r\n let tryAgain = () => {\r\n apiManager.invokeApi('help.getNearestDc').then((nearestDcResult) => {\r\n const langPack = stateStorage.getFromCache('langPack');\r\n if(langPack && !langPack.countries?.hash) {\r\n I18n.getLangPack(langPack.lang_code).then(() => {\r\n simulateEvent(telEl, 'input');\r\n });\r\n }\r\n\r\n const dcs = new Set([1, 2, 3, 4, 5]);\r\n const done: number[] = [nearestDcResult.this_dc];\r\n\r\n let promise: Promise<any>;\r\n if(nearestDcResult.nearest_dc !== nearestDcResult.this_dc) {\r\n promise = apiManager.getNetworker(nearestDcResult.nearest_dc).then(() => {\r\n done.push(nearestDcResult.nearest_dc);\r\n });\r\n }\r\n\r\n (promise || Promise.resolve()).then(() => {\r\n done.forEach(dcId => {\r\n dcs.delete(dcId);\r\n });\r\n\r\n const _dcs = [...dcs];\r\n const g = async(): Promise<void> => {\r\n const dcId = _dcs.shift();\r\n if(!dcId) return;\r\n\r\n const dbKey: DcAuthKey = `dc${dcId}_auth_key` as any;\r\n const key = await sessionStorage.get(dbKey);\r\n if(key) {\r\n return g();\r\n }\r\n\r\n setTimeout(() => { // * если одновременно запросить все нетворкеры, не будет проходить запрос на код\r\n apiManager.getNetworker(dcId/* , {fileDownload: true} */).finally(g);\r\n }, /* done.includes(dcId) ? 0 : */3000);\r\n };\r\n \r\n g();\r\n });\r\n \r\n return nearestDcResult;\r\n }).then((nearestDcResult) => {\r\n if(!countryInputField.value.length && !telInputField.value.length) {\r\n selectCountryByTarget(liMap.get(nearestDcResult.country)[0]);\r\n }\r\n \r\n //console.log('woohoo', nearestDcResult, country);\r\n })//.catch(tryAgain);\r\n };\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n setTimeout(() => {\r\n telEl.focus();\r\n }, 0);\r\n }\r\n\r\n getLanguageChangeButton(inputWrapper);\r\n\r\n tryAgain();\r\n};\r\n\r\nconst page = new Page('page-sign', true, onFirstMount, () => {\r\n if(btnNext) {\r\n replaceContent(btnNext, i18n('Login.Next'));\r\n ripple(btnNext, undefined, undefined, true);\r\n btnNext.removeAttribute('disabled');\r\n }\r\n\r\n if(btnQr) {\r\n btnQr.removeAttribute('disabled');\r\n }\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignIn'});\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\nimport mediaSizes from '../helpers/mediaSizes';\r\nimport { AuthSentCode, AuthSentCodeType, AuthSignIn } from '../layer';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport Page from './page';\r\nimport pageSignIn from './pageSignIn';\r\nimport TrackingMonkey from '../components/monkeys/tracking';\r\nimport CodeInputField from '../components/codeInputField';\r\nimport { i18n, LangPackKey } from '../lib/langPack';\r\nimport { randomLong } from '../helpers/random';\r\nimport replaceContent from '../helpers/dom/replaceContent';\r\n\r\nlet authCode: AuthSentCode.authSentCode = null;\r\n\r\nlet headerElement: HTMLHeadElement = null;\r\nlet sentTypeElement: HTMLParagraphElement = null;\r\nlet codeInput: HTMLInputElement;\r\n\r\nlet onFirstMount = (): Promise<any> => {\r\n const CODELENGTH = (authCode.type as AuthSentCodeType.authSentCodeTypeApp).length;\r\n\r\n const codeInputField = new CodeInputField({\r\n label: 'Code',\r\n name: randomLong(),\r\n length: CODELENGTH,\r\n onFill: (code) => {\r\n submitCode(code);\r\n }\r\n });\r\n\r\n codeInput = codeInputField.input as HTMLInputElement;\r\n\r\n page.pageEl.querySelector('.input-wrapper').append(codeInputField.container);\r\n\r\n const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;\r\n\r\n editButton.addEventListener('click', function() {\r\n return pageSignIn.mount();\r\n });\r\n\r\n const cleanup = () => {\r\n setTimeout(() => {\r\n monkey.remove();\r\n }, 300);\r\n };\r\n\r\n const submitCode = (code: string) => {\r\n codeInput.setAttribute('disabled', 'true');\r\n\r\n const params: AuthSignIn = {\r\n phone_number: authCode.phone_number,\r\n phone_code_hash: authCode.phone_code_hash,\r\n phone_code: code\r\n };\r\n\r\n //console.log('invoking auth.signIn with params:', params);\r\n\r\n apiManager.invokeApi('auth.signIn', params, {ignoreErrors: true})\r\n .then((response) => {\r\n //console.log('auth.signIn response:', response);\r\n \r\n switch(response._) {\r\n case 'auth.authorization':\r\n apiManager.setUser(response.user);\r\n\r\n import('./pageIm').then(m => {\r\n m.default.mount();\r\n });\r\n cleanup();\r\n break;\r\n case 'auth.authorizationSignUpRequired':\r\n //console.log('Registration needed!');\r\n\r\n import('./pageSignUp').then(m => {\r\n m.default.mount({\r\n 'phone_number': authCode.phone_number,\r\n 'phone_code_hash': authCode.phone_code_hash\r\n });\r\n });\r\n\r\n cleanup();\r\n break;\r\n /* default:\r\n codeInput.innerText = response._;\r\n break; */\r\n }\r\n }).catch(async(err) => {\r\n let good = false;\r\n switch(err.type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n //console.warn('pageAuthCode: SESSION_PASSWORD_NEEDED');\r\n good = true;\r\n err.handled = true;\r\n await (await import('./pagePassword')).default.mount(); // lol\r\n setTimeout(() => {\r\n codeInput.value = '';\r\n }, 300);\r\n break;\r\n case 'PHONE_CODE_EXPIRED':\r\n codeInput.classList.add('error');\r\n replaceContent(codeInputField.label, i18n('PHONE_CODE_EXPIRED'));\r\n break;\r\n case 'PHONE_CODE_EMPTY':\r\n case 'PHONE_CODE_INVALID':\r\n codeInput.classList.add('error');\r\n replaceContent(codeInputField.label, i18n('PHONE_CODE_INVALID'));\r\n break;\r\n default:\r\n codeInputField.label.innerText = err.type;\r\n break;\r\n }\r\n\r\n if(!good) {\r\n codeInputField.select();\r\n }\r\n\r\n codeInput.removeAttribute('disabled');\r\n });\r\n };\r\n\r\n const imageDiv = page.pageEl.querySelector('.auth-image') as HTMLDivElement;\r\n const size = mediaSizes.isMobile ? 100 : 166;\r\n const monkey = new TrackingMonkey(codeInputField, size);\r\n imageDiv.append(monkey.container);\r\n return monkey.load();\r\n};\r\n\r\nconst page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof authCode) => {\r\n authCode = _authCode;\r\n\r\n if(!headerElement) {\r\n headerElement = page.pageEl.getElementsByClassName('phone')[0] as HTMLHeadElement;\r\n sentTypeElement = page.pageEl.getElementsByClassName('sent-type')[0] as HTMLParagraphElement;\r\n } else {\r\n codeInput.value = '';\r\n\r\n const evt = document.createEvent('HTMLEvents');\r\n evt.initEvent('input', false, true);\r\n codeInput.dispatchEvent(evt);\r\n }\r\n\r\n headerElement.innerText = authCode.phone_number;\r\n let key: LangPackKey, args: any[];\r\n switch(authCode.type._) {\r\n case 'auth.sentCodeTypeSms':\r\n key = 'Login.Code.SentSms';\r\n break;\r\n case 'auth.sentCodeTypeApp': \r\n key = 'Login.Code.SentInApp';\r\n break;\r\n case 'auth.sentCodeTypeCall': \r\n key = 'Login.Code.SentCall';\r\n break;\r\n default:\r\n key = 'Login.Code.SentUnknown';\r\n args = [authCode.type._];\r\n break;\r\n }\r\n\r\n replaceContent(sentTypeElement, i18n(key, args));\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateAuthCode', sentCode: _authCode});\r\n}, () => {\r\n codeInput.focus();\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(/<style([\\s\\S]*)<\\/style>/, '');\r\n html = html.replace(/<!--([\\s\\S]*)-->/, '');\r\n\r\n const match = html.match(/<body>([\\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 <p>asd</p>\\n<p>zxc</p>\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 <div contenteditable=\"${String(!!canBeEdited)}\" class=\"input-field-input\"></div>\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 <input type=\"text\" ${name ? `name=\"${name}\"` : ''} autocomplete=\"off\" ${label ? 'required=\"\"' : ''} class=\"input-field-input\">\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 { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { logger, LogTypes } from \"../lib/logger\";\r\nimport fastSmoothScroll, { ScrollOptions } from \"../helpers/fastSmoothScroll\";\r\nimport useHeavyAnimationCheck from \"../hooks/useHeavyAnimationCheck\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\n/*\r\nvar el = $0;\r\nvar height = 0;\r\nvar checkUp = false;\r\n\r\ndo {\r\n height += el.scrollHeight;\r\n} while(el = (checkUp ? el.previousElementSibling : el.nextElementSibling));\r\nconsole.log(height);\r\n*/\r\n\r\n/*\r\nArray.from($0.querySelectorAll('.bubble-content')).forEach(_el => {\r\n\t//_el.style.display = '';\t\r\n\t//return;\r\n\r\n\tlet el = _el.parentElement;\r\n\tlet height = el.scrollHeight;\r\n\tlet width = el.scrollWidth;\r\n\tel.style.width = width + 'px';\r\n\tel.style.height = height + 'px';\r\n\t_el.style.display = 'none';\r\n});\r\n*/\r\n\r\n/* const scrollables: Map<HTMLElement, Scrollable> = new Map();\r\nconst scrollsIntersector = new IntersectionObserver(entries => {\r\n for(let entry of entries) {\r\n const scrollable = scrollables.get(entry.target as HTMLElement);\r\n\r\n if(entry.isIntersecting) {\r\n scrollable.isVisible = true;\r\n } else {\r\n scrollable.isVisible = false;\r\n\r\n if(!isInDOM(entry.target)) {\r\n scrollsIntersector.unobserve(scrollable.container);\r\n scrollables.delete(scrollable.container);\r\n }\r\n }\r\n }\r\n}); */\r\n\r\nexport class ScrollableBase {\r\n protected log: ReturnType<typeof logger>;\r\n\r\n public splitUp: HTMLElement;\r\n public onScrollMeasure: number = 0;\r\n\r\n public lastScrollPosition: number = 0;\r\n public lastScrollDirection: number = 0;\r\n\r\n public onAdditionalScroll: () => void;\r\n public onScrolledTop: () => void;\r\n public onScrolledBottom: () => void;\r\n\r\n public isHeavyAnimationInProgress = false;\r\n protected needCheckAfterAnimation = false;\r\n\r\n public checkForTriggers?: () => void;\r\n\r\n public scrollProperty: 'scrollTop' | 'scrollLeft';\r\n \r\n private removeHeavyAnimationListener: () => void;\r\n\r\n constructor(public el: HTMLElement, logPrefix = '', public container: HTMLElement = document.createElement('div')) {\r\n this.container.classList.add('scrollable');\r\n\r\n this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''), LogTypes.Error);\r\n\r\n if(el) {\r\n Array.from(el.children).forEach(c => this.container.append(c));\r\n\r\n el.append(this.container);\r\n }\r\n //this.onScroll();\r\n }\r\n\r\n public setListeners() {\r\n if(this.removeHeavyAnimationListener) {\r\n return;\r\n }\r\n\r\n window.addEventListener('resize', this.onScroll, {passive: true});\r\n this.container.addEventListener('scroll', this.onScroll, {passive: true, capture: true});\r\n\r\n this.removeHeavyAnimationListener = useHeavyAnimationCheck(() => {\r\n this.isHeavyAnimationInProgress = true;\r\n\r\n if(this.onScrollMeasure) {\r\n this.needCheckAfterAnimation = true;\r\n window.cancelAnimationFrame(this.onScrollMeasure);\r\n }\r\n }, () => {\r\n this.isHeavyAnimationInProgress = false;\r\n\r\n if(this.needCheckAfterAnimation) {\r\n this.onScroll();\r\n this.needCheckAfterAnimation = false;\r\n }\r\n });\r\n }\r\n\r\n public removeListeners() {\r\n if(!this.removeHeavyAnimationListener) {\r\n return;\r\n }\r\n\r\n window.removeEventListener('resize', this.onScroll);\r\n this.container.removeEventListener('scroll', this.onScroll, {capture: true});\r\n\r\n this.removeHeavyAnimationListener();\r\n }\r\n\r\n public append(element: HTMLElement) {\r\n this.container.append(element);\r\n }\r\n\r\n public scrollIntoViewNew(options: Omit<ScrollOptions, 'container'>) {\r\n //return Promise.resolve();\r\n return fastSmoothScroll({\r\n ...options,\r\n container: this.container\r\n });\r\n }\r\n\r\n public onScroll = () => {\r\n //if(this.debug) {\r\n //this.log('onScroll call', this.onScrollMeasure);\r\n //}\r\n\r\n //return;\r\n\r\n if(this.isHeavyAnimationInProgress) {\r\n if(this.onScrollMeasure) {\r\n window.cancelAnimationFrame(this.onScrollMeasure);\r\n }\r\n\r\n this.needCheckAfterAnimation = true;\r\n return;\r\n }\r\n\r\n //if(this.onScrollMeasure || ((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll)) return;\r\n if((!this.onScrolledTop && !this.onScrolledBottom) && !this.splitUp && !this.onAdditionalScroll) return;\r\n if(this.onScrollMeasure) window.cancelAnimationFrame(this.onScrollMeasure);\r\n this.onScrollMeasure = window.requestAnimationFrame(() => {\r\n this.onScrollMeasure = 0;\r\n\r\n const scrollPosition = this.container[this.scrollProperty];\r\n this.lastScrollDirection = this.lastScrollPosition === scrollPosition ? 0 : (this.lastScrollPosition < scrollPosition ? 1 : -1); // * 1 - bottom, -1 - top\r\n this.lastScrollPosition = scrollPosition;\r\n\r\n if(this.onAdditionalScroll && this.lastScrollDirection !== 0) {\r\n this.onAdditionalScroll();\r\n }\r\n \r\n if(this.checkForTriggers) {\r\n this.checkForTriggers();\r\n }\r\n });\r\n };\r\n}\r\n\r\nexport type SliceSides = 'top' | 'bottom';\r\nexport type SliceSidesContainer = {[k in SliceSides]: boolean};\r\n\r\nexport default class Scrollable extends ScrollableBase {\r\n public padding: HTMLElement;\r\n \r\n public loadedAll: SliceSidesContainer = {top: true, bottom: false};\r\n\r\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, withPaddingContainer?: boolean) {\r\n super(el, logPrefix);\r\n\r\n /* if(withPaddingContainer) {\r\n this.padding = document.createElement('div');\r\n this.padding.classList.add('scrollable-padding');\r\n Array.from(this.container.children).forEach(c => this.padding.append(c));\r\n this.container.append(this.padding);\r\n } */\r\n\r\n this.container.classList.add('scrollable-y');\r\n this.setListeners();\r\n this.scrollProperty = 'scrollTop';\r\n }\r\n\r\n public setVirtualContainer(el?: HTMLElement) {\r\n this.splitUp = el;\r\n this.log('setVirtualContainer:', el, this);\r\n }\r\n\r\n public checkForTriggers = () => {\r\n if((!this.onScrolledTop && !this.onScrolledBottom)) return;\r\n\r\n if(this.isHeavyAnimationInProgress) {\r\n this.onScroll();\r\n return;\r\n }\r\n\r\n const scrollHeight = this.container.scrollHeight;\r\n if(!scrollHeight) { // незачем вызывать триггеры если блок пустой или не виден\r\n return;\r\n }\r\n\r\n const clientHeight = this.container.clientHeight;\r\n const maxScrollTop = scrollHeight - clientHeight;\r\n const scrollTop = this.lastScrollPosition;\r\n\r\n //this.log('checkForTriggers:', scrollTop, maxScrollTop);\r\n\r\n if(this.onScrolledTop && scrollTop <= this.onScrollOffset && this.lastScrollDirection <= 0/* && direction === -1 */) {\r\n this.onScrolledTop();\r\n }\r\n\r\n if(this.onScrolledBottom && (maxScrollTop - scrollTop) <= this.onScrollOffset && this.lastScrollDirection >= 0/* && direction === 1 */) {\r\n this.onScrolledBottom();\r\n }\r\n };\r\n\r\n public prepend(...elements: (HTMLElement | DocumentFragment)[]) {\r\n (this.splitUp || this.padding || this.container).prepend(...elements);\r\n }\r\n\r\n public append(...elements: (HTMLElement | DocumentFragment)[]) {\r\n (this.splitUp || this.padding || this.container).append(...elements);\r\n }\r\n\r\n public getDistanceToEnd() {\r\n return this.scrollHeight - Math.round(this.scrollTop + this.container.offsetHeight);\r\n }\r\n\r\n get isScrolledDown() {\r\n return this.getDistanceToEnd() <= 1;\r\n }\r\n\r\n set scrollTop(y: number) {\r\n this.container.scrollTop = y;\r\n }\r\n \r\n get scrollTop() {\r\n //this.log.trace('get scrollTop');\r\n return this.container.scrollTop;\r\n }\r\n \r\n get scrollHeight() {\r\n return this.container.scrollHeight;\r\n }\r\n}\r\n\r\nexport class ScrollableX extends ScrollableBase {\r\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, public splitCount = 15, public container: HTMLElement = document.createElement('div')) {\r\n super(el, logPrefix, container);\r\n\r\n this.container.classList.add('scrollable-x');\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n const scrollHorizontally = (e: any) => {\r\n if(!e.deltaX && this.container.scrollWidth > this.container.clientWidth) {\r\n this.container.scrollLeft += e.deltaY / 4;\r\n cancelEvent(e);\r\n }\r\n };\r\n \r\n this.container.addEventListener('wheel', scrollHorizontally, {passive: false});\r\n }\r\n\r\n this.scrollProperty = 'scrollLeft';\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 appStateManager from \"../lib/appManagers/appStateManager\";\r\nimport { ripple } from \"./ripple\";\r\nimport { LangPackKey, _i18n } from \"../lib/langPack\";\r\nimport getDeepProperty from \"../helpers/object/getDeepProperty\";\r\n\r\nexport type CheckboxFieldOptions = {\r\n text?: LangPackKey,\r\n textArgs?: any[],\r\n name?: string, \r\n round?: boolean, \r\n toggle?: boolean,\r\n stateKey?: string,\r\n stateValues?: any[],\r\n disabled?: boolean,\r\n checked?: boolean,\r\n restriction?: boolean,\r\n withRipple?: boolean,\r\n withHover?: boolean,\r\n};\r\nexport default class CheckboxField {\r\n public input: HTMLInputElement;\r\n public label: HTMLLabelElement;\r\n public span: HTMLSpanElement;\r\n\r\n constructor(options: CheckboxFieldOptions = {}) {\r\n const label = this.label = document.createElement('label');\r\n label.classList.add('checkbox-field');\r\n\r\n if(options.restriction) {\r\n label.classList.add('checkbox-field-restriction');\r\n }\r\n\r\n if(options.round) {\r\n label.classList.add('checkbox-field-round');\r\n }\r\n\r\n if(options.disabled) {\r\n this.toggleDisability(true);\r\n }\r\n\r\n const input = this.input = document.createElement('input');\r\n input.classList.add('checkbox-field-input');\r\n input.type = 'checkbox';\r\n if(options.name) {\r\n input.id = 'input-' + options.name;\r\n }\r\n\r\n if(options.checked) {\r\n input.checked = true;\r\n }\r\n\r\n if(options.stateKey) {\r\n appStateManager.getState().then(state => {\r\n const stateValue = getDeepProperty(state, options.stateKey);\r\n let checked: boolean;\r\n if(options.stateValues) {\r\n checked = options.stateValues.indexOf(stateValue) === 1;\r\n } else {\r\n checked = stateValue;\r\n }\r\n\r\n this.setValueSilently(checked);\r\n\r\n input.addEventListener('change', () => {\r\n let value: any;\r\n if(options.stateValues) {\r\n value = options.stateValues[input.checked ? 1 : 0];\r\n } else {\r\n value = input.checked;\r\n }\r\n\r\n appStateManager.setByKey(options.stateKey, value);\r\n });\r\n });\r\n }\r\n\r\n let span: HTMLSpanElement;\r\n if(options.text) {\r\n span = this.span = document.createElement('span');\r\n span.classList.add('checkbox-caption');\r\n _i18n(span, options.text, options.textArgs);\r\n } else {\r\n label.classList.add('checkbox-without-caption');\r\n }\r\n\r\n label.append(input);\r\n\r\n if(options.toggle) {\r\n label.classList.add('checkbox-field-toggle');\r\n\r\n const toggle = document.createElement('div');\r\n toggle.classList.add('checkbox-toggle');\r\n label.append(toggle);\r\n } else {\r\n const box = document.createElement('div');\r\n box.classList.add('checkbox-box');\r\n \r\n const checkSvg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n checkSvg.classList.add('checkbox-box-check');\r\n checkSvg.setAttributeNS(null, 'viewBox', '0 0 24 24');\r\n const use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(null, 'href', '#check');\r\n use.setAttributeNS(null, 'x', '-1');\r\n checkSvg.append(use);\r\n \r\n const bg = document.createElement('div');\r\n bg.classList.add('checkbox-box-background');\r\n \r\n const border = document.createElement('div');\r\n border.classList.add('checkbox-box-border');\r\n \r\n box.append(border, bg, checkSvg);\r\n \r\n label.append(box);\r\n }\r\n\r\n if(span) {\r\n label.append(span);\r\n }\r\n\r\n if(options.withRipple) {\r\n label.classList.add('checkbox-ripple', 'hover-effect');\r\n ripple(label, undefined, undefined, true);\r\n //label.prepend(input);\r\n } else if(options.withHover) {\r\n label.classList.add('hover-effect');\r\n }\r\n }\r\n\r\n get checked() {\r\n return this.input.checked;\r\n }\r\n\r\n set checked(checked: boolean) {\r\n /* if(this.checked === checked) {\r\n return;\r\n } */\r\n \r\n this.setValueSilently(checked);\r\n\r\n const event = new Event('change', {bubbles: true, cancelable: true});\r\n this.input.dispatchEvent(event);\r\n }\r\n\r\n public setValueSilently(checked: boolean) {\r\n this.input.checked = checked;\r\n }\r\n\r\n public toggleDisability(disable: boolean) {\r\n this.label.classList.toggle('checkbox-disabled', disable);\r\n return () => this.toggleDisability(!disable);\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\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\nexport default function toggleDisability(elements: HTMLElement[], disable: boolean): () => void {\r\n if(disable) {\r\n elements.forEach(el => el.setAttribute('disabled', 'true'));\r\n } else {\r\n elements.forEach(el => el.removeAttribute('disabled'));\r\n }\r\n\r\n return () => toggleDisability(elements, !disable);\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\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\nexport default function findUpTag(el: any, tag: string): HTMLElement {\r\n return el.closest(tag);\r\n /* if(el.tagName === tag) return el; // 03.02.2020\r\n\r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.tagName === tag) \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\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 <igor.beatle@gmail.com>\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<MessageEntity['_'], 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityPre' | 'messageEntityStrike' | 'messageEntityTextUrl' | 'messageEntityMentionName' | 'messageEntitySpoiler'>;\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 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","/*\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\nimport type { ApplyServerTimeOffsetTask } from './timeManager';\r\nimport { MOUNT_CLASS_TO } from '../../config/debug';\r\n// import { tsNow } from '../../helpers/date';\r\nimport sessionStorage from '../sessionStorage';\r\nimport apiManager from './mtprotoworker';\r\n\r\nexport class ServerTimeManager {\r\n /* private midnightNoOffset: number;\r\n private midnightOffseted: Date;\r\n\r\n private midnightOffset: number; */\r\n\r\n public serverTimeOffset: number; // in seconds\r\n /* private timeParams: {\r\n midnightOffset: number,\r\n serverTimeOffset: number\r\n }; */\r\n\r\n constructor() {\r\n /* const timestampNow = tsNow(true);\r\n this.midnightNoOffset = timestampNow - (timestampNow % 86400);\r\n this.midnightOffseted = new Date();\r\n this.midnightOffseted.setHours(0, 0, 0, 0);\r\n \r\n this.midnightOffset = this.midnightNoOffset - (Math.floor(+this.midnightOffseted / 1000)); */\r\n\r\n this.serverTimeOffset = 0;\r\n /* this.timeParams = {\r\n midnightOffset: this.midnightOffset,\r\n serverTimeOffset: this.serverTimeOffset\r\n }; */\r\n\r\n sessionStorage.get('server_time_offset').then((to) => {\r\n if(to) {\r\n this.serverTimeOffset = to;\r\n // this.timeParams.serverTimeOffset = to;\r\n }\r\n });\r\n\r\n apiManager.addTaskListener('applyServerTimeOffset', (task: ApplyServerTimeOffsetTask) => {\r\n this.serverTimeOffset = task.payload;\r\n });\r\n }\r\n}\r\n\r\nconst serverTimeManager = new ServerTimeManager();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.serverTimeManager = serverTimeManager);\r\nexport default serverTimeManager;\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\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\n\r\nexport default function placeCaretAtEnd(el: HTMLElement, ignoreTouchCheck = false) {\r\n if(IS_TOUCH_SUPPORTED && (!ignoreTouchCheck || document.activeElement !== el)) {\r\n return;\r\n }\r\n \r\n el.focus();\r\n if(typeof window.getSelection !== \"undefined\" && typeof document.createRange !== \"undefined\") {\r\n var range = document.createRange();\r\n range.selectNodeContents(el);\r\n range.collapse(false);\r\n var sel = window.getSelection();\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n // @ts-ignore\r\n } else if(typeof document.body.createTextRange !== \"undefined\") {\r\n // @ts-ignore\r\n var textRange = document.body.createTextRange();\r\n textRange.moveToElementText(el);\r\n textRange.collapse(false);\r\n textRange.select();\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 { HelpCountry, HelpCountryCode } from \"../layer\";\nimport I18n from \"../lib/langPack\";\n\nlet sortedCountries: HelpCountry[];\ntype PrefixCountry = {country: HelpCountry, code: HelpCountryCode};\nconst prefixes: Map<string, PrefixCountry> = new Map();\nlet maxPrefixLength = 0;\nconst setPrefix = (country: HelpCountry, code: HelpCountryCode, prefix: string = '') => {\n prefix = code.country_code + prefix;\n /* if(prefixes.has(prefix)) {\n console.error('asdasdasd', prefixes.get(prefix), country, code);\n } */\n maxPrefixLength = Math.max(maxPrefixLength, prefix.length);\n prefixes.set(prefix, {country, code});\n};\n\nexport function formatPhoneNumber(originalStr: string): {\n formatted: string,\n country: HelpCountry,\n code: HelpCountryCode,\n leftPattern: string\n} {\n originalStr = originalStr || '';\n \n if(!prefixes.size) {\n I18n.countriesList.forEach(country => {\n country.country_codes.forEach(code => {\n if(code.prefixes) {\n code.prefixes.forEach(prefix => {\n setPrefix(country, code, prefix);\n });\n } else {\n setPrefix(country, code);\n }\n });\n });\n }\n\n // return {formatted: originalStr, country: undefined as any, leftPattern: ''};\n let str = originalStr.replace(/\\D/g, '');\n let phoneCode = str.slice(0, maxPrefixLength);\n \n ////console.log('str', str, phoneCode);\n // if(!sortedCountries) {\n // sortedCountries = I18n.countriesList.slice().sort((a, b) => b.country_codes[0].country_code.length - a.country_codes[0].country_code.length);\n // }\n \n // let country = sortedCountries.find((c) => {\n // return c.country_codes.find((c) => phoneCode.indexOf(c.replace(/\\D/g, '')) === 0);\n // });\n\n let prefixCountry: PrefixCountry;\n for(let i = phoneCode.length - 1; i >= 0; --i) { // lookup for country by prefix\n prefixCountry = prefixes.get(phoneCode.slice(0, i + 1));\n if(prefixCountry) {\n break;\n }\n }\n\n if(!prefixCountry) {\n return {\n formatted: str, \n country: undefined, \n code: undefined, \n leftPattern: ''\n };\n }\n\n // country = /* PhoneCodesMain[country.phoneCode] || */country;\n const country = prefixCountry.country;\n \n const patterns = prefixCountry.code.patterns || [];\n const searchForPattern = str.slice(prefixCountry.code.country_code.length); // splice country code\n let pattern = '', mostMatchedPatternMatches = 0, mostMatchedPattern = '';\n for(let i = patterns.length - 1; i >= 0; --i) {\n pattern = patterns[i];\n\n const _pattern = pattern.replace(/ /g, '');\n let patternMatches = 0;\n for(let k = 0, length = Math.min(searchForPattern.length, _pattern.length); k < length; ++k) {\n if(searchForPattern[k] === _pattern[k] || _pattern[k] === 'X') {\n ++patternMatches;\n } else {\n patternMatches = 0;\n break;\n }\n }\n\n if(patternMatches > mostMatchedPatternMatches) {\n mostMatchedPatternMatches = patternMatches;\n mostMatchedPattern = pattern;\n }\n }\n\n pattern = mostMatchedPattern || pattern;\n pattern = pattern.replace(/\\d/g, 'X');\n\n pattern = prefixCountry.code.country_code + ' ' + pattern;\n // let pattern = country.pattern || country.phoneCode;\n pattern.split('').forEach((symbol, idx) => {\n if(symbol === ' ' && str[idx] !== ' ' && str.length > idx) {\n str = str.slice(0, idx) + ' ' + str.slice(idx);\n }\n });\n \n /* if(country.pattern) {\n str = str.slice(0, country.pattern.length);\n } */\n\n let leftPattern = pattern && pattern.length > str.length ? pattern.slice(str.length) : '';\n if(leftPattern) {\n /* const length = str.length;\n leftPattern = leftPattern.split('').map((_, idx) => (length + idx).toString().slice(-1)).join(''); */\n leftPattern = leftPattern.replace(/X/g, '‒');\n // leftPattern = leftPattern.replace(/X/g, '0');\n }\n \n return {formatted: str, country, code: prefixCountry.code, leftPattern};\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\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<string>;\nexport default function readBlobAs(blob: Blob, method: 'readAsDataURL'): Promise<string>;\nexport default function readBlobAs(blob: Blob, method: 'readAsArrayBuffer'): Promise<ArrayBuffer>;\nexport default function readBlobAs(blob: Blob, method: 'readAsArrayBuffer' | 'readAsText' | 'readAsDataURL'): Promise<any> {\n // const perf = performance.now();\n return new Promise<any>((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":""} |