浏览代码

port the contest version

painor 4 年之前
父节点
当前提交
9260e391f3
共有 41 个文件被更改,包括 0 次插入8074 次删除
  1. 0 2
      .idea/.gitignore
  2. 0 1
      browser/LAYER
  3. 0 96
      browser/gramjs.js
  4. 0 80
      gramjs/crypto/AES.js
  5. 0 23
      gramjs/crypto/AESCTR.js
  6. 0 12
      gramjs/crypto/index.js
  7. 0 273
      gramjs/extensions/HTML.js
  8. 0 166
      gramjs/extensions/Markdown.js
  9. 0 58
      gramjs/extensions/Scanner.js
  10. 0 320
      gramjs/sessions/JSONSession.js
  11. 0 258
      gramjs/sessions/SQLiteSession.js
  12. 0 0
      gramjs/tl/custom/index.js
  13. 0 81
      gramjs/tl/tlobject.js
  14. 0 1418
      gramjs_generator/data/api.tl
  15. 0 290
      gramjs_generator/data/errors.csv
  16. 0 27
      gramjs_generator/data/friendly.csv
  17. 0 50
      gramjs_generator/data/html/404.html
  18. 0 236
      gramjs_generator/data/html/core.html
  19. 0 185
      gramjs_generator/data/html/css/docs.dark.css
  20. 0 229
      gramjs_generator/data/html/css/docs.h4x0r.css
  21. 0 182
      gramjs_generator/data/html/css/docs.light.css
  22. 0 35
      gramjs_generator/data/html/img/arrow.svg
  23. 0 244
      gramjs_generator/data/html/js/search.js
  24. 0 300
      gramjs_generator/data/methods.csv
  25. 0 113
      gramjs_generator/data/mtproto.tl
  26. 0 390
      gramjs_generator/docswriter.js
  27. 0 827
      gramjs_generator/generators/docs.js
  28. 0 95
      gramjs_generator/generators/errors.js
  29. 0 10
      gramjs_generator/generators/index.js
  30. 0 916
      gramjs_generator/generators/tlobject.js
  31. 0 92
      gramjs_generator/parsers/errors.js
  32. 0 14
      gramjs_generator/parsers/index.js
  33. 0 65
      gramjs_generator/parsers/methods.js
  34. 0 10
      gramjs_generator/parsers/tlobject/index.js
  35. 0 188
      gramjs_generator/parsers/tlobject/parser.js
  36. 0 287
      gramjs_generator/parsers/tlobject/tlarg.js
  37. 0 191
      gramjs_generator/parsers/tlobject/tlobject.js
  38. 0 77
      gramjs_generator/sourcebuilder.js
  39. 0 16
      gramjs_generator/utils.js
  40. 0 186
      index.js
  41. 0 31
      webpack.config.babel.js

+ 0 - 2
.idea/.gitignore

@@ -1,2 +0,0 @@
-# Default ignored files
-/workspace.xml

+ 0 - 1
browser/LAYER

@@ -1 +0,0 @@
-105

文件差异内容过多而无法显示
+ 0 - 96
browser/gramjs.js


+ 0 - 80
gramjs/crypto/AES.js

@@ -1,80 +0,0 @@
-const aesjs = require('aes-js')
-const { generateRandomBytes } = require('../Helpers')
-
-class AES {
-    /**
-     * Decrypts the given text in 16-bytes blocks by using the given key and 32-bytes initialization vector
-     * @param cipherText {Buffer}
-     * @param key {Buffer}
-     * @param iv {Buffer}
-     * @returns {Buffer}
-     */
-    static decryptIge(cipherText, key, iv) {
-        let iv1 = iv.slice(0, Math.floor(iv.length / 2))
-        let iv2 = iv.slice(Math.floor(iv.length / 2))
-        let plainText = new Array(cipherText.length).fill(0)
-        const aes = new aesjs.AES(key)
-        const blocksCount = Math.floor(plainText.length / 16)
-        const cipherTextBlock = new Array(16).fill(0)
-
-        for (let blockIndex = 0; blockIndex < blocksCount; blockIndex++) {
-            for (let i = 0; i < 16; i++) {
-                cipherTextBlock[i] = cipherText[blockIndex * 16 + i] ^ iv2[i]
-            }
-            const plainTextBlock = aes.decrypt(cipherTextBlock)
-            for (let i = 0; i < 16; i++) {
-                plainTextBlock[i] ^= iv1[i]
-            }
-
-            iv1 = cipherText.slice(blockIndex * 16, blockIndex * 16 + 16)
-            iv2 = plainTextBlock.slice(0, 16)
-            plainText = new Uint8Array([
-                ...plainText.slice(0, blockIndex * 16),
-                ...plainTextBlock.slice(0, 16),
-                ...plainText.slice(blockIndex * 16 + 16),
-            ])
-        }
-        return Buffer.from(plainText)
-    }
-
-    /**
-     * Encrypts the given text in 16-bytes blocks by using the given key and 32-bytes initialization vector
-     * @param plainText {Buffer}
-     * @param key {Buffer}
-     * @param iv {Buffer}
-     * @returns {Buffer}
-     */
-    static encryptIge(plainText, key, iv) {
-        const padding = plainText.length % 16
-        if (padding) {
-            plainText = Buffer.concat([plainText, generateRandomBytes(16 - padding)])
-        }
-
-        let iv1 = iv.slice(0, Math.floor(iv.length / 2))
-        let iv2 = iv.slice(Math.floor(iv.length / 2))
-
-        const aes = new aesjs.AES(key)
-        let cipherText = Buffer.alloc(0)
-        const blockCount = Math.floor(plainText.length / 16)
-
-        for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) {
-            const plainTextBlock = Buffer.from(plainText.slice(blockIndex * 16, blockIndex * 16 + 16))
-
-            for (let i = 0; i < 16; i++) {
-                plainTextBlock[i] ^= iv1[i]
-            }
-            const cipherTextBlock = Buffer.from(aes.encrypt(plainTextBlock))
-
-            for (let i = 0; i < 16; i++) {
-                cipherTextBlock[i] ^= iv2[i]
-            }
-
-            iv1 = cipherTextBlock
-            iv2 = plainText.slice(blockIndex * 16, blockIndex * 16 + 16)
-            cipherText = Buffer.concat([cipherText, cipherTextBlock])
-        }
-        return cipherText
-    }
-}
-
-module.exports = AES

+ 0 - 23
gramjs/crypto/AESCTR.js

@@ -1,23 +0,0 @@
-const aesjs = require('aes-js')
-const stackTrace = require('stack-trace')
-
-class AESModeCTR {
-    constructor(key, iv) {
-        if (!(key instanceof Buffer) || !(iv instanceof Buffer) || iv.length !== 16) {
-            throw new Error('Key and iv need to be a buffer')
-        }
-        this.cipher = new aesjs.ModeOfOperation.ctr(Buffer.from(key), Buffer.from(iv))
-    }
-
-    encrypt(data) {
-        const res = this.cipher.encrypt(data)
-        return Buffer.from(res)
-    }
-
-    decrypt(data) {
-        return Buffer.from(this.cipher.decrypt(data))
-    }
-
-}
-
-module.exports = AESModeCTR

+ 0 - 12
gramjs/crypto/index.js

@@ -1,12 +0,0 @@
-const AES = require('./AES')
-const AESCTR = require('./AESCTR')
-const AuthKey = require('./AuthKey')
-const Factorizator = require('./Factorizator')
-const RSA = require('./RSA')
-module.exports = {
-    AES,
-    AESCTR,
-    AuthKey,
-    Factorizator,
-    RSA,
-}

+ 0 - 273
gramjs/extensions/HTML.js

@@ -1,273 +0,0 @@
-/* eslint-disable no-extend-native */
-/* eslint-disable no-case-declarations, no-fallthrough */
-const Scanner = require('./Scanner')
-const {
-    MessageEntityBold, MessageEntityItalic, MessageEntityCode,
-    MessageEntityPre, MessageEntityEmail, MessageEntityTextUrl,
-    MessageEntityUnderline, MessageEntityStrike, MessageEntityBlockquote,
-} = require('../tl/types')
-
-class HTMLParser extends Scanner {
-    constructor(str) {
-        super(str)
-        this.text = ''
-        this.entities = []
-        this._buildingEntities = {}
-        this._openTags = []
-        this._openTagsMeta = []
-    }
-
-    parse() {
-        while (!this.eof()) {
-            switch (this.peek(1)) {
-            case '<':
-                this.consume(1)
-                if (this.peek(1) === '/') {
-                    // Closing tag
-                    this.consume(1)
-                    const tag = this.scanUntil('>').trim()
-
-                    // Consume the closing bracket
-                    this.consume(1)
-
-                    this.handleEndTag(tag)
-                } else {
-                    // Opening tag
-                    let tag = this.scanUntil('>').trim()
-                    let attrs
-
-                    // Consume the closing bracket
-                    this.consume(1);
-
-                    [tag, ...attrs] = tag.split(/\s+/)
-                    attrs = attrs
-                        // Split on `=`
-                        .map((a) => a.split('='))
-                        // Take non key/value items and make them `true`
-                        .map((a) => a.length === 1 ? a.concat([true]) : a)
-                        // Remove quotes if they exist
-                        .map((a) => {
-                            const attr = a[1].replace(/^('|")|('|")$/g, '')
-                            return [a[0], attr]
-                        })
-                        .reduce((p, c) => {
-                            p[c[0]] = c[1]
-                            return p
-                        }, {})
-
-                    this.handleStartTag(tag, attrs)
-                }
-                break
-            default:
-                if (this.eof()) break
-                this.handleData(this.chr)
-                this.pos += 1
-            }
-        }
-
-        return [this.text, this.entities]
-    }
-
-    static unparse(text, entities, _offset = 0, _length = null) {
-        if (!_length) {
-            _length = text.length
-        }
-
-        const html = []
-        let lastOffset = 0
-
-        for (const [i, entity] of entities.entries()) {
-            if (entity.offset > _offset + _length) {
-                break
-            }
-
-            const relativeOffset = entity.offset - _offset
-            if (relativeOffset > lastOffset) {
-                html.push(text.substring(lastOffset, relativeOffset))
-            } else if (relativeOffset < lastOffset) {
-                continue
-            }
-
-            let skipEntity = false
-            let length = entity.length
-
-            while ((relativeOffset < _length) &&
-                   ('\ud800' <= text.substring(relativeOffset, length)) &&
-                   (text.substring(relativeOffset, length) <= '\udfff')) {
-                length += 1
-            }
-
-            const entityText = this.unparse(
-                text.substring(relativeOffset, relativeOffset + length),
-                entities.slice(i + 1, entities.length),
-                entity.offset,
-                length,
-            )
-
-            const entityType = entity.constructor.name
-
-            switch (entityType) {
-            case 'MessageEntityBold':
-                html.push(`<strong>${entityText}</strong>`)
-                break
-            case 'MessageEntityItalic':
-                html.push(`<em>${entityText}</em>`)
-                break
-            case 'MessageEntityCode':
-                html.push(`<code>${entityText}</code>`)
-                break
-            case 'MessageEntityUnderline':
-                html.push(`<u>${entityText}</u>`)
-                break
-            case 'MessageEntityStrike':
-                html.push(`<del>${entityText}</del>`)
-                break
-            case 'MessageEntityBlockquote':
-                html.push(`<blockquote>${entityText}</blockquote>`)
-                break
-            case 'MessageEntityPre':
-                if (entity.language) {
-                    html.push(`<pre>
-                      <code class="language-${entity.language}">
-                        ${entityText}
-                      </code>
-                    </pre>`)
-                } else {
-                    html.push(`<pre>${entityText}</pre>`)
-                }
-                break
-            case 'MessageEntityEmail':
-                html.push(`<a href="mailto:${entityText}">${entityText}</a>`)
-                break
-            case 'MessageEntityUrl':
-                html.push(`<a href="${entityText}">${entityText}</a>`)
-                break
-            case 'MessageEntityTextUrl':
-                html.push(`<a href="${entity.url}">${entityText}</a>`)
-                break
-            case 'MessageEntityMentionName':
-                html.push(`<a href="tg://user?id=${entity.userId}">${entityText}</a>`)
-                break
-            default:
-                skipEntity = true
-            }
-
-            lastOffset = relativeOffset + (skipEntity ? 0 : length)
-        }
-
-        while ((lastOffset < _length) &&
-               ('\ud800' <= text.substring(lastOffset)) &&
-               (text.substring(lastOffset) <= '\udfff')) {
-            lastOffset += 1
-        }
-
-        html.push(text.substring(lastOffset, text.length))
-        return html.join('')
-    }
-
-    handleStartTag(tag, attrs = {}) {
-        this._openTags.unshift(tag)
-        this._openTagsMeta.unshift(null)
-
-        let EntityType
-        const args = {}
-
-        switch (tag) {
-        case 'b':
-        case 'strong':
-            EntityType = MessageEntityBold
-            break
-        case 'i':
-        case 'em':
-            EntityType = MessageEntityItalic
-            break
-        case 'u':
-            EntityType = MessageEntityUnderline
-            break
-        case 's':
-        case 'del':
-            EntityType = MessageEntityStrike
-            break
-        case 'blockquote':
-            EntityType = MessageEntityBlockquote
-            break
-        case 'code':
-            // If we're in the middle of a <pre> tag, this <code> tag is
-            // probably intended for syntax highlighting.
-            //
-            // Syntax highlighting is set with
-            //     <code class='language-...'>codeblock</code>
-            // inside <pre> tags
-            const pre = this._buildingEntities['pre']
-            const language = attrs['class'] ? attrs['class'].match(/language-(\S+)/)[1] : null
-            if (pre && language) {
-                pre.language = language
-            } else {
-                EntityType = MessageEntityCode
-            }
-            break
-        case 'pre':
-            EntityType = MessageEntityPre
-            args['language'] = ''
-            break
-        case 'a':
-            let url = attrs['href']
-            if (!url) return
-
-            if (url.indexOf('mailto:') === 0) {
-                EntityType = MessageEntityEmail
-            } else {
-                EntityType = MessageEntityTextUrl
-                args['url'] = url
-                url = null
-            }
-
-            this._openTagsMeta.shift()
-            this._openTagsMeta.unshift(url)
-            break
-        default:
-            // Do nothing
-        }
-
-        if (EntityType && !(tag in this._buildingEntities)) {
-            this._buildingEntities[tag] = new EntityType({
-                offset: this.text.length,
-                // The length will be determined when closing the tag.
-                length: 0,
-                ...args,
-            })
-        }
-    }
-
-    handleData(text) {
-        for (const [, entity] of Object.entries(this._buildingEntities)) {
-            entity.length += text.length
-        }
-
-        this.text += text
-    }
-
-    handleEndTag(tag) {
-        this._openTags.shift()
-        this._openTagsMeta.shift()
-
-        const entity = this._buildingEntities[tag]
-        if (entity) {
-            delete this._buildingEntities[tag]
-            this.entities.push(entity)
-        }
-    }
-}
-
-const parse = (str) => {
-    const parser = new HTMLParser(str)
-    return parser.parse()
-}
-
-const unparse = HTMLParser.unparse
-
-module.exports = {
-    HTMLParser,
-    parse,
-    unparse,
-}

+ 0 - 166
gramjs/extensions/Markdown.js

@@ -1,166 +0,0 @@
-/* eslint-disable no-fallthrough */
-const Scanner = require('./Scanner')
-const {
-    MessageEntityBold, MessageEntityItalic, MessageEntityCode,
-    MessageEntityPre, MessageEntityTextUrl, MessageEntityMentionName,
-    MessageEntityStrike,
-} = require('../tl/types')
-const { regExpEscape } = require('../Helpers')
-
-const URL_RE = /\[([\S\s]+?)\]\((.+?)\)/
-const DELIMITERS = {
-    'MessageEntityBold': '**',
-    'MessageEntityItalic': '__',
-    'MessageEntityCode': '`',
-    'MessageEntityPre': '```',
-    'MessageEntityStrike': '~~',
-}
-
-class MarkdownParser extends Scanner {
-    constructor(str) {
-        super(str)
-        this.text = ''
-        this.entities = []
-    }
-
-    parse() {
-        // Do a little reset
-        this.text = ''
-        this.entities = []
-
-        while (!this.eof()) {
-            switch (this.chr) {
-            case '*':
-                if (this.peek(2) == '**') {
-                    if (this.parseEntity(MessageEntityBold, '**')) break
-                }
-            case '_':
-                if (this.peek(2) == '__') {
-                    if (this.parseEntity(MessageEntityItalic, '__')) break
-                }
-            case '~':
-                if (this.peek(2) == '~~') {
-                    if (this.parseEntity(MessageEntityStrike, '~~')) break
-                }
-            case '`':
-                if (this.peek(3) == '```') {
-                    if (this.parseEntity(MessageEntityPre, '```')) break
-                } else if (this.peek(1) == '`') {
-                    if (this.parseEntity(MessageEntityCode, '`')) break
-                }
-            case '[':
-                if (this.parseURL()) break
-            default:
-                this.text += this.chr
-                this.pos += 1
-            }
-        }
-
-        return [this.text, this.entities]
-    }
-
-    static unparse(text, entities) {
-        if (!text || !entities) return text
-        entities = Array.isArray(entities) ? entities : [entities]
-
-        let insertAt = []
-        for (const entity of entities) {
-            const s = entity.offset
-            const e = entity.offset + entity.length
-            const delimiter = DELIMITERS[entity.constructor.name]
-            if (delimiter) {
-                insertAt.push([s, delimiter])
-                insertAt.push([e, delimiter])
-            } else {
-                let url = null
-                if (entity instanceof MessageEntityTextUrl) {
-                    url = entity.url
-                } else if (entity instanceof MessageEntityMentionName) {
-                    url = `tg://user?id=${entity.userId}`
-                }
-
-                if (url) {
-                    insertAt.push([s, '['])
-                    insertAt.push([e, `](${url})`])
-                }
-            }
-        }
-
-        insertAt = insertAt.sort((a, b) => a[0] - b[0])
-        while (insertAt.length > 0) {
-            let [at, what] = insertAt.pop()
-
-            while ((at < text.length) && '\ud800' <= text[at] && text[at] <= '\udfff') {
-                at += 1
-            }
-
-            text = text.slice(0, at) + what + text.slice(at, text.size)
-        }
-
-        return text
-    }
-
-    parseEntity(EntityType, delimiter) {
-        // The offset for this entity should be the end of the
-        // text string
-        const offset = this.text.length
-
-        // Consume the delimiter
-        this.consume(delimiter.length)
-
-        // Scan until the delimiter is reached again. This is the
-        // entity's content.
-        const content = this.scanUntil(new RegExp(regExpEscape(delimiter)))
-
-        if (content) {
-            // Consume the delimiter again
-            this.consume(delimiter.length)
-
-            // Add the entire content to the text
-            this.text += content
-
-            // Create and return a new Entity
-            const entity = new EntityType({
-                offset,
-                length: content.length,
-            })
-            this.entities.push(entity)
-            return entity
-        }
-    }
-
-    parseURL() {
-        const match = this.rest.match(URL_RE)
-        if (match.index !== 0) return
-
-        const [full, txt, url] = match
-        const len = full.length
-        const offset = this.text.length
-
-        this.text += txt
-
-        const entity = new MessageEntityTextUrl({
-            offset: offset,
-            length: txt.length,
-            url: url,
-        })
-
-        this.consume(len)
-        this.entities.push(entity)
-
-        return entity
-    }
-}
-
-const parse = (str) => {
-    const parser = new MarkdownParser(str)
-    return parser.parse()
-}
-
-const unparse = MarkdownParser.unparse
-
-module.exports = {
-    MarkdownParser,
-    parse,
-    unparse,
-}

+ 0 - 58
gramjs/extensions/Scanner.js

@@ -1,58 +0,0 @@
-class Scanner {
-    constructor(str) {
-        this.str = str
-        this.pos = 0
-        this.lastMatch = null
-    }
-
-    get chr() {
-        return this.str[this.pos]
-    }
-
-    peek(n = 1) {
-        return this.str.slice(this.pos, this.pos + n)
-    }
-
-    reverse(n = 1) {
-        const pos = this.pos - n
-        this.pos = pos < 0 ? 0 : pos
-    }
-
-    consume(n = 1) {
-        return this.str.slice(this.pos, this.pos += n)
-    }
-
-    scanUntil(re, consumeMatch = false) {
-        let match
-        try {
-            match = this.lastMatch = this.rest.match(re)
-        } catch {
-            match = null
-        }
-
-        if (!match) return null
-
-        let len = match.index
-        if (consumeMatch) len += match[0].size
-
-        return this.consume(len)
-    }
-
-    get rest() {
-        return this.str.slice(this.pos, this.str.length) || null
-    }
-
-    reset() {
-        this.pos = 0
-    }
-
-    bof() {
-        return this.pos <= 0
-    }
-
-    eof() {
-        return this.pos >= this.str.length
-    }
-}
-
-module.exports = Scanner

+ 0 - 320
gramjs/sessions/JSONSession.js

@@ -1,320 +0,0 @@
-const { generateRandomLong, getRandomInt } = require('../Helpers')
-const fs = require('fs').promises
-const { existsSync, readFileSync } = require('fs')
-const AuthKey = require('../crypto/AuthKey')
-const { TLObject } = require('../tl/tlobject')
-const utils = require('../Utils')
-const types = require('../tl/types')
-
-BigInt.toJSON = function() {
-    return { fool: this.fool.toString('hex') }
-}
-BigInt.parseJson = function() {
-    return { fool: BigInt('0x' + this.fool) }
-}
-
-class Session {
-    constructor(sessionUserId) {
-        this.sessionUserId = sessionUserId
-        this._serverAddress = null
-        this._dcId = 0
-        this._port = null
-        // this.serverAddress = "localhost";
-        // this.port = 21;
-        this.authKey = undefined
-        this.id = generateRandomLong(false)
-        this.sequence = 0
-        this.salt = BigInt(0) // Unsigned long
-        this.timeOffset = BigInt(0)
-        this.lastMessageId = BigInt(0)
-        this.user = undefined
-        this._files = {}
-        this._entities = new Set()
-        this._updateStates = {}
-    }
-
-    /**
-     * Saves the current session object as session_user_id.session
-     */
-    async save() {
-        if (this.sessionUserId) {
-            const str = JSON.stringify(this, function(key, value) {
-                if (typeof value === 'bigint') {
-                    return value.toString() + 'n'
-                } else {
-                    return value
-                }
-            })
-            await fs.writeFile(`${this.sessionUserId}.session`, str)
-        }
-    }
-
-    setDC(dcId, serverAddress, port) {
-        this._dcId = dcId | 0
-        this._serverAddress = serverAddress
-        this._port = port
-    }
-
-    get serverAddress() {
-        return this._serverAddress
-    }
-
-    get port() {
-        return this._port
-    }
-
-    get dcId() {
-        return this._dcId
-    }
-
-    getUpdateState(entityId) {
-        return this._updateStates[entityId]
-    }
-
-    setUpdateState(entityId, state) {
-        return this._updateStates[entityId] = state
-    }
-
-    close() {
-    }
-
-    delete() {
-    }
-
-    _entityValuesToRow(id, hash, username, phone, name) {
-        // While this is a simple implementation it might be overrode by,
-        // other classes so they don't need to implement the plural form
-        // of the method. Don't remove.
-        return [id, hash, username, phone, name]
-    }
-
-    _entityToRow(e) {
-        if (!(e instanceof TLObject)) {
-            return
-        }
-        let p
-        let markedId
-        try {
-            p = utils.getInputPeer(e, false)
-            markedId = utils.getPeerId(p)
-        } catch (e) {
-            // Note: `get_input_peer` already checks for non-zero `access_hash`.
-            // See issues #354 and #392. It also checks that the entity
-            // is not `min`, because its `access_hash` cannot be used
-            // anywhere (since layer 102, there are two access hashes).
-            return
-        }
-        let pHash
-        if (p instanceof types.InputPeerUser || p instanceof types.InputPeerChannel) {
-            pHash = p.accessHash
-        } else if (p instanceof types.InputPeerChat) {
-            pHash = 0
-        } else {
-            return
-        }
-
-        let username = e.username
-        if (username) {
-            username = username.toLowerCase()
-        }
-        const phone = e.phone
-        const name = utils.getDisplayName(e)
-        return this._entityValuesToRow(markedId, pHash, username, phone, name)
-    }
-
-    _entitiesToRows(tlo) {
-        let entities = []
-        if (tlo instanceof TLObject && utils.isListLike(tlo)) {
-            // This may be a list of users already for instance
-            entities = tlo
-        } else {
-            if ('user' in tlo) {
-                entities.push(tlo.user)
-            }
-            if ('chats' in tlo && utils.isListLike(tlo.chats)) {
-                entities.concat(tlo.chats)
-            }
-            if ('users' in tlo && utils.isListLike(tlo.users)) {
-                entities.concat(tlo.users)
-            }
-        }
-        const rows = [] // Rows to add (id, hash, username, phone, name)
-        for (const e of entities) {
-            const row = this._entityToRow(e)
-            if (row) {
-                rows.push(row)
-            }
-        }
-        return rows
-    }
-
-
-    static tryLoadOrCreateNew(sessionUserId) {
-        if (sessionUserId === undefined) {
-            return new Session()
-        }
-        const filepath = `${sessionUserId}.session`
-
-
-        if (existsSync(filepath)) {
-            try {
-                const ob = JSON.parse(readFileSync(filepath, 'utf-8'), function(key, value) {
-                    if (typeof value == 'string' && value.match(/(\d+)n/)) {
-                        return BigInt(value.slice(0, -1))
-                    } else {
-                        return value
-                    }
-                })
-
-                const authKey = new AuthKey(Buffer.from(ob.authKey._key.data))
-                const session = new Session(ob.sessionUserId)
-                session._serverAddress = ob._serverAddress
-                session._port = ob._port
-                session._dcId = ob._dcId
-
-                // this.serverAddress = "localhost";
-                // this.port = 21;
-                session.authKey = authKey
-                session.id = ob.id
-                session.sequence = ob.sequence
-                session.salt = ob.salt // Unsigned long
-                session.timeOffset = ob.timeOffset
-                session.lastMessageId = ob.lastMessageId
-                session.user = ob.user
-                return session
-            } catch (e) {
-                return new Session(sessionUserId)
-            }
-        } else {
-            return new Session(sessionUserId)
-        }
-    }
-
-    getNewMsgId() {
-        const msTime = new Date().getTime()
-        let newMessageId =
-            (BigInt(BigInt(Math.floor(msTime / 1000)) + this.timeOffset) << BigInt(32)) |
-            (BigInt(msTime % 1000) << BigInt(22)) |
-            (BigInt(getRandomInt(0, 524288)) << BigInt(2)) // 2^19
-
-        if (this.lastMessageId >= newMessageId) {
-            newMessageId = this.lastMessageId + BigInt(4)
-        }
-        this.lastMessageId = newMessageId
-        return newMessageId
-    }
-
-    processEntities(tlo) {
-        const entitiesSet = this._entitiesToRows(tlo)
-        for (const e of entitiesSet) {
-            this._entities.add(e)
-        }
-    }
-
-    getEntityRowsByPhone(phone) {
-        for (const e of this._entities) { // id, hash, username, phone, name
-            if (e[3] === phone) {
-                return [e[0], e[1]]
-            }
-        }
-    }
-
-    getEntityRowsByName(name) {
-        for (const e of this._entities) { // id, hash, username, phone, name
-            if (e[4] === name) {
-                return [e[0], e[1]]
-            }
-        }
-    }
-
-    getEntityRowsByUsername(username) {
-        for (const e of this._entities) { // id, hash, username, phone, name
-            if (e[2] === username) {
-                return [e[0], e[1]]
-            }
-        }
-    }
-
-    getEntityRowsById(id, exact = true) {
-        if (exact) {
-            for (const e of this._entities) { // id, hash, username, phone, name
-                if (e[0] === id) {
-                    return [e[0], e[1]]
-                }
-            }
-        } else {
-            const ids = [utils.getPeerId(new types.PeerUser({ userId: id })),
-                utils.getPeerId(new types.PeerChat({ chatId: id })),
-                utils.getPeerId(new types.PeerChannel({ channelId: id })),
-            ]
-            for (const e of this._entities) { // id, hash, username, phone, name
-                if (ids.includes(e[0])) {
-                    return [e[0], e[1]]
-                }
-            }
-        }
-    }
-
-    getInputEntity(key) {
-        let exact
-        if (key.SUBCLASS_OF_ID !== undefined) {
-            if ([0xc91c90b6, 0xe669bf46, 0x40f202fd].includes(key.SUBCLASS_OF_ID)) {
-                // hex(crc32(b'InputPeer', b'InputUser' and b'InputChannel'))
-                // We already have an Input version, so nothing else required
-                return key
-            }
-            // Try to early return if this key can be casted as input peer
-            return utils.getInputPeer(key)
-        } else {
-            // Not a TLObject or can't be cast into InputPeer
-            if (key instanceof TLObject) {
-                key = utils.getPeerId(key)
-                exact = true
-            } else {
-                exact = !(typeof key == 'number') || key < 0
-            }
-        }
-        let result = null
-        if (typeof key === 'string') {
-            const phone = utils.parsePhone(key)
-            if (phone) {
-                result = this.getEntityRowsByPhone(phone)
-            } else {
-                const { username, isInvite } = utils.parseUsername(key)
-                if (username && !isInvite) {
-                    result = this.getEntityRowsByUsername(username)
-                } else {
-                    const tup = utils.resolveInviteLink(key)[1]
-                    if (tup) {
-                        result = this.getEntityRowsById(tup, false)
-                    }
-                }
-            }
-        } else if (typeof key === 'number') {
-            result = this.getEntityRowsById(key, exact)
-        }
-        if (!result && typeof key === 'string') {
-            result = this.getEntityRowsByName(key)
-        }
-
-        if (result) {
-            let entityId = result[0] // unpack resulting tuple
-            const entityHash = result[1]
-            const resolved = utils.resolveId(entityId)
-            entityId = resolved[0]
-            const kind = resolved[1]
-            // removes the mark and returns type of entity
-            if (kind === types.PeerUser) {
-                return new types.InputPeerUser({ userId: entityId, accessHash: entityHash })
-            } else if (kind === types.PeerChat) {
-                return new types.InputPeerChat({ chatId: entityId })
-            } else if (kind === types.PeerChannel) {
-                return new types.InputPeerChannel({ channelId: entityId, accessHash: entityHash })
-            }
-        } else {
-            throw new Error('Could not find input entity with key ' + key)
-        }
-    }
-}
-
-module.exports = Session

+ 0 - 258
gramjs/sessions/SQLiteSession.js

@@ -1,258 +0,0 @@
-const EXTENSION = '.session'
-const CURRENT_VERSION = 1
-const AuthKey = require('../crypto/AuthKey')
-const Database = require('better-sqlite3')
-const utils = require('../Utils')
-const { PeerUser, PeerChannel, PeerChat } = require('../tl/types')
-const types = require('../tl/types')
-const fs = require('fs')
-const MemorySession = require('./Memory')
-
-class SQLiteSession extends MemorySession {
-    /**
-     * This session contains the required information to login into your
-     * Telegram account. NEVER give the saved session file to anyone, since
-     * they would gain instant access to all your messages and contacts.
-
-     * If you think the session has been compromised, close all the sessions
-     * through an official Telegram client to revoke the authorization.
-     */
-    constructor(sessionId = null) {
-        super()
-        this.filename = ':memory:'
-        this.saveEntities = true
-
-        if (sessionId) {
-            this.filename = sessionId
-            if (!this.filename.endsWith(EXTENSION)) {
-                this.filename += EXTENSION
-            }
-        }
-
-        this.db = new Database(this.filename)
-        let stmt = this.db.prepare('SELECT name FROM sqlite_master where type=\'table\' and name=\'version\'')
-        if (stmt.get()) {
-            // Tables already exist, check for the version
-            stmt = this.db.prepare('select version from version')
-            const version = stmt.get().version
-            if (version < CURRENT_VERSION) {
-                this._upgradeDatabase(version)
-                this.db.exec('delete from version')
-                stmt = this.db.prepare('insert into version values (?)')
-                stmt.run(CURRENT_VERSION)
-                this.save()
-            }
-
-            // These values will be saved
-            stmt = this.db.prepare('select * from sessions')
-            const res = stmt.get()
-
-
-            if (res) {
-
-                this._dcId = res['dcId']
-                this._serverAddress = res['serverAddress']
-                this._port = res['port']
-                this._authKey = new AuthKey(res['authKey'])
-                this._takeoutId = res['takeoutId']
-            }
-        } else {
-            // Tables don't exist, create new ones
-            this._createTable(
-                'version (version integer primary key)'
-                ,
-                `sessions (
-                dcId integer primary key,
-                    serverAddress text,
-                    port integer,
-                    authKey blob,
-                    takeoutId integer
-                )`,
-                `entities (
-                id integer primary key,
-                    hash integer not null,
-                    username text,
-                    phone integer,
-                    name text
-                )`,
-                `sent_files (
-                md5Digest blob,
-                    fileSize integer,
-                    type integer,
-                    id integer,
-                    hash integer,
-                    primary key(md5Digest, fileSize, type)
-                )`,
-                `updateState (
-                id integer primary key,
-                    pts integer,
-                    qts integer,
-                    date integer,
-                    seq integer
-                )`,
-            )
-            stmt = this.db.prepare('insert into version values (?)')
-            stmt.run(CURRENT_VERSION)
-            this._updateSessionTable()
-            this.save()
-        }
-
-    }
-
-    load() {
-
-    }
-
-    get authKey() {
-        return super.authKey
-    }
-
-    _upgradeDatabase(old) {
-        // nothing so far
-    }
-
-    _createTable(...definitions) {
-        for (const definition of definitions) {
-            this.db.exec(`create table ${definition}`)
-        }
-    }
-
-    // Data from sessions should be kept as properties
-    // not to fetch the database every time we need it
-    setDC(dcId, serverAddress, port) {
-        super.setDC(dcId, serverAddress, port)
-        this._updateSessionTable()
-
-        // Fetch the authKey corresponding to this data center
-        const row = this.db.prepare('select authKey from sessions').get()
-        if (row && row.authKey) {
-            this._authKey = new AuthKey(row.authKey)
-        } else {
-            this._authKey = null
-        }
-    }
-
-    set authKey(value) {
-        this._authKey = value
-        this._updateSessionTable()
-    }
-
-    set takeoutId(value) {
-        this._takeoutId = value
-        this._updateSessionTable()
-    }
-
-    _updateSessionTable() {
-        // While we can save multiple rows into the sessions table
-        // currently we only want to keep ONE as the tables don't
-        // tell us which auth_key's are usable and will work. Needs
-        // some more work before being able to save auth_key's for
-        // multiple DCs. Probably done differently.
-        this.db.exec('delete from sessions')
-        const stmt = this.db.prepare('insert or replace into sessions values (?,?,?,?,?)')
-        stmt.run(this._dcId, this._serverAddress,
-            this._port, this._authKey ? this._authKey.key : Buffer.alloc(0), this._takeoutId)
-    }
-
-    getUpdateState(entityId) {
-        const row = this.db.prepare('select pts, qts, date, seq from updateState where id=?').get(entityId)
-        if (row) {
-            return new types.update.State({
-                pts: row.pts,
-                qts: row.qts, date: new Date(row.date), seq: row.seq, unreadCount: 0,
-            })
-        }
-    }
-
-    setUpdateState(entityId, state) {
-        const stmt = this.db.prepare('insert or replace into updateState values (?,?,?,?,?)')
-        stmt.run(entityId, state.pts, state.qts,
-            state.date.getTime(), state.seq)
-    }
-
-    save() {
-        // currently nothing needs to be done
-    }
-
-    /**
-     * Deletes the current session file
-     */
-    delete() {
-        if (this.db.name === ':memory:') {
-            return true
-        }
-        try {
-            fs.unlinkSync(this.db.name)
-            return true
-        } catch (e) {
-            return false
-        }
-    }
-
-    /**
-     * Lists all the sessions of the users who have ever connected
-     * using this client and never logged out
-     */
-    listSessions() {
-        // ???
-    }
-
-    // Entity processing
-    /**
-     * Processes all the found entities on the given TLObject,
-     * unless .enabled is False.
-     *
-     * Returns True if new input entities were added.
-     * @param tlo
-     */
-    processEntities(tlo) {
-        if (!this.saveEntities) {
-            return
-        }
-        const rows = this._entitiesToRows(tlo)
-        if (!rows) {
-            return
-        }
-        for (const row of rows) {
-            row[1] = Database.Integer(row[1].toString())
-            const stmt = this.db.prepare('insert or replace into entities values (?,?,?,?,?)')
-            stmt.run(...row)
-        }
-    }
-
-    getEntityRowsByPhone(phone) {
-        return this.db.prepare('select id, hash from entities where phone=?').get(phone)
-    }
-
-    getEntityRowsByUsername(username) {
-        return this.db.prepare('select id, hash from entities where username=?').get(username)
-    }
-
-    getEntityRowsByName(name) {
-        return this.db.prepare('select id, hash from entities where name=?').get(name)
-    }
-
-    getEntityRowsById(id, exact = true) {
-        if (exact) {
-            return this.db.prepare('select id, hash from entities where id=?').get(id)
-        } else {
-            return this.db.prepare('select id, hash from entities where id in (?,?,?)').get(
-                utils.getPeerId(new PeerUser(id)),
-                utils.getPeerId(new PeerChat(id)),
-                utils.getPeerId(new PeerChannel(id)),
-            )
-        }
-    }
-
-    // File processing
-
-    getFile(md5Digest, fileSize, cls) {
-        // nope
-    }
-
-    cacheFile(md5Digest, fileSize, instance) {
-        // nope
-    }
-}
-
-module.exports = SQLiteSession

+ 0 - 0
gramjs/tl/custom/index.js


+ 0 - 81
gramjs/tl/tlobject.js

@@ -1,81 +0,0 @@
-const struct = require('python-struct')
-
-class TLObject {
-    CONSTRUCTOR_ID = null;
-    SUBCLASS_OF_ID = null;
-
-    static prettyFormat() {
-        // TODO
-    }
-
-    /**
-     * Write bytes by using Telegram guidelines
-     * @param data {Buffer|string}
-     */
-    static serializeBytes(data) {
-        if (!(data instanceof Buffer)) {
-            if (typeof data == 'string') {
-                data = Buffer.from(data)
-            } else {
-                throw Error(`Bytes or str expected, not ${data.constructor.name}`)
-            }
-        }
-        const r = []
-        let padding
-        if (data.length < 254) {
-            padding = (data.length + 1) % 4
-            if (padding !== 0) {
-                padding = 4 - padding
-            }
-            r.push(Buffer.from([data.length]))
-            r.push(data)
-        } else {
-            padding = data.length % 4
-            if (padding !== 0) {
-                padding = 4 - padding
-            }
-            r.push(Buffer.from([254, data.length % 256, (data.length >> 8) % 256, (data.length >> 16) % 256]))
-            r.push(data)
-        }
-        r.push(Buffer.alloc(padding).fill(0))
-        return Buffer.concat(r)
-    }
-
-    static serializeDate(dt) {
-        if (!dt) {
-            return Buffer.alloc(4).fill(0)
-        }
-        if (dt instanceof Date) {
-            dt = Math.floor((Date.now() - dt.getTime()) / 1000)
-        }
-        if (typeof dt == 'number') {
-            return struct.pack('<i', dt)
-        }
-        throw Error(`Cannot interpret "${dt}" as a date`)
-    }
-
-    fromReader(reader) {
-        throw Error('not implemented')
-    }
-}
-
-/**
- * Represents a content-related `TLObject` (a request that can be sent).
- */
-class TLRequest extends TLObject {
-    /**
-     *
-     * @param reader {BinaryReader}
-     * @returns {boolean}
-     */
-    readResult(reader) {
-        return reader.tgReadObject()
-    }
-
-    async resolve(client, utils) {}
-}
-
-module.exports = {
-    TLObject,
-    TLRequest,
-}

+ 0 - 1418
gramjs_generator/data/api.tl

@@ -1,1418 +0,0 @@
-///////////////////////////////
-/////////////////// Layer cons
-///////////////////////////////
-
-//invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
-//invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;
-//invokeWithLayer1#53835315 query:!X = X;
-//invokeWithLayer2#289dd1f6 query:!X = X;
-//invokeWithLayer3#b7475268 query:!X = X;
-//invokeWithLayer4#dea0d430 query:!X = X;
-//invokeWithLayer5#417a57ae query:!X = X;
-//invokeWithLayer6#3a64d54d query:!X = X;
-//invokeWithLayer7#a5be56d3 query:!X = X;
-//invokeWithLayer8#e9abd9fd query:!X = X;
-//invokeWithLayer9#76715a63 query:!X = X;
-//invokeWithLayer10#39620c41 query:!X = X;
-//invokeWithLayer11#a6b88fdf query:!X = X;
-//invokeWithLayer12#dda60d3c query:!X = X;
-//invokeWithLayer13#427c8ea2 query:!X = X;
-//invokeWithLayer14#2b9b08fa query:!X = X;
-//invokeWithLayer15#b4418b64 query:!X = X;
-//invokeWithLayer16#cf5f0987 query:!X = X;
-//invokeWithLayer17#50858a19 query:!X = X;
-//invokeWithLayer18#1c900537 query:!X = X;
-//invokeWithLayer#da9b0d0d layer:int query:!X = X; // after 18 layer
-
-///////////////////////////////
-///////// Main application API
-///////////////////////////////
-
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
-
-true#3fedd339 = True;
-
-vector#1cb5c415 {t:Type} # [ t ] = Vector t;
-
-error#c4b9f9bb code:int text:string = Error;
-
-null#56730bcc = Null;
-
-inputPeerEmpty#7f3b18ea = InputPeer;
-inputPeerSelf#7da07ec9 = InputPeer;
-inputPeerChat#179be863 chat_id:int = InputPeer;
-inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer;
-inputPeerChannel#20adaef8 channel_id:int access_hash:long = InputPeer;
-inputPeerUserFromMessage#17bae2e6 peer:InputPeer msg_id:int user_id:int = InputPeer;
-inputPeerChannelFromMessage#9c95f7bb peer:InputPeer msg_id:int channel_id:int = InputPeer;
-
-inputUserEmpty#b98886cf = InputUser;
-inputUserSelf#f7c1b13f = InputUser;
-inputUser#d8292816 user_id:int access_hash:long = InputUser;
-inputUserFromMessage#2d117597 peer:InputPeer msg_id:int user_id:int = InputUser;
-
-inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
-
-inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
-inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
-
-inputMediaEmpty#9664f57f = InputMedia;
-inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
-inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
-inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
-inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
-inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
-inputMediaDocument#23ab23d2 flags:# id:InputDocument ttl_seconds:flags.0?int = InputMedia;
-inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
-inputMediaGifExternal#4843b0fd url:string q:string = InputMedia;
-inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
-inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
-inputMediaGame#d33f43f3 id:InputGame = InputMedia;
-inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
-inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
-inputMediaPoll#6b3765b poll:Poll = InputMedia;
-
-inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
-inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto;
-inputChatPhoto#8953ad37 id:InputPhoto = InputChatPhoto;
-
-inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
-inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
-
-inputPhotoEmpty#1cd7bf0d = InputPhoto;
-inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto;
-
-inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation;
-inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
-inputDocumentFileLocation#bad07584 id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation;
-inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
-inputTakeoutFileLocation#29be5899 = InputFileLocation;
-inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation;
-inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
-inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
-
-peerUser#9db1bc6d user_id:int = Peer;
-peerChat#bad0e5bb chat_id:int = Peer;
-peerChannel#bddde532 channel_id:int = Peer;
-
-storage.fileUnknown#aa963b05 = storage.FileType;
-storage.filePartial#40bc6f52 = storage.FileType;
-storage.fileJpeg#7efe0e = storage.FileType;
-storage.fileGif#cae1aadf = storage.FileType;
-storage.filePng#a4f63c0 = storage.FileType;
-storage.filePdf#ae1e508d = storage.FileType;
-storage.fileMp3#528a0677 = storage.FileType;
-storage.fileMov#4b09ebbc = storage.FileType;
-storage.fileMp4#b3cea0e4 = storage.FileType;
-storage.fileWebp#1081464c = storage.FileType;
-
-userEmpty#200250ba id:int = User;
-user#938458c1 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
-
-userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
-userProfilePhoto#ecd75d8c photo_id:long photo_small:FileLocation photo_big:FileLocation dc_id:int = UserProfilePhoto;
-
-userStatusEmpty#9d05049 = UserStatus;
-userStatusOnline#edb93949 expires:int = UserStatus;
-userStatusOffline#8c703f was_online:int = UserStatus;
-userStatusRecently#e26f42f1 = UserStatus;
-userStatusLastWeek#7bf09fc = UserStatus;
-userStatusLastMonth#77ebc742 = UserStatus;
-
-chatEmpty#9ba2d800 id:int = Chat;
-chat#3bda1bde flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
-chatForbidden#7328bdb id:int title:string = Chat;
-channel#d31a961e flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
-channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
-
-chatFull#1b7c9db3 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int = ChatFull;
-channelFull#2d895c74 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true can_set_location:flags.16?true has_scheduled:flags.19?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?int location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int pts:int = ChatFull;
-
-chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
-chatParticipantCreator#da13538a user_id:int = ChatParticipant;
-chatParticipantAdmin#e2d6e436 user_id:int inviter_id:int date:int = ChatParticipant;
-
-chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0?ChatParticipant = ChatParticipants;
-chatParticipants#3f460fed chat_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
-
-chatPhotoEmpty#37c1011c = ChatPhoto;
-chatPhoto#475cdbd5 photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto;
-
-messageEmpty#83e5de54 id:int = Message;
-message#452c0e65 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
-messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
-
-messageMediaEmpty#3ded6320 = MessageMedia;
-messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
-messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
-messageMediaContact#cbf24940 phone_number:string first_name:string last_name:string vcard:string user_id:int = MessageMedia;
-messageMediaUnsupported#9f84f49e = MessageMedia;
-messageMediaDocument#9cb070d7 flags:# document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
-messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
-messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
-messageMediaGame#fdb19008 game:Game = MessageMedia;
-messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
-messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
-messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
-
-messageActionEmpty#b6aef7b0 = MessageAction;
-messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
-messageActionChatEditTitle#b5a1ce5a title:string = MessageAction;
-messageActionChatEditPhoto#7fcb13a8 photo:Photo = MessageAction;
-messageActionChatDeletePhoto#95e3fbef = MessageAction;
-messageActionChatAddUser#488a7337 users:Vector<int> = MessageAction;
-messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
-messageActionChatJoinedByLink#f89cf5e8 inviter_id:int = MessageAction;
-messageActionChannelCreate#95d2ac92 title:string = MessageAction;
-messageActionChatMigrateTo#51bdb021 channel_id:int = MessageAction;
-messageActionChannelMigrateFrom#b055eaee title:string chat_id:int = MessageAction;
-messageActionPinMessage#94bd38ed = MessageAction;
-messageActionHistoryClear#9fbab604 = MessageAction;
-messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
-messageActionPaymentSentMe#8f31b327 flags:# currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction;
-messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAction;
-messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
-messageActionScreenshotTaken#4792929b = MessageAction;
-messageActionCustomAction#fae69f56 message:string = MessageAction;
-messageActionBotAllowed#abe9affe domain:string = MessageAction;
-messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
-messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
-messageActionContactSignUp#f3f25f76 = MessageAction;
-
-dialog#2c171f72 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
-dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
-
-photoEmpty#2331b22d id:long = Photo;
-photo#d07504a5 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> dc_id:int = Photo;
-
-photoSizeEmpty#e17e23c type:string = PhotoSize;
-photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
-photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
-photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
-
-geoPointEmpty#1117dd5f = GeoPoint;
-geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
-
-auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
-
-auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization;
-auth.authorizationSignUpRequired#44747e9a flags:# terms_of_service:flags.0?help.TermsOfService = auth.Authorization;
-
-auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorization;
-
-inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
-inputNotifyUsers#193b4417 = InputNotifyPeer;
-inputNotifyChats#4a95e84e = InputNotifyPeer;
-inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
-
-inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
-
-peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
-
-peerSettings#818426cd flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true = PeerSettings;
-
-wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
-
-inputReportReasonSpam#58dbcab8 = ReportReason;
-inputReportReasonViolence#1e22c78d = ReportReason;
-inputReportReasonPornography#2e59d922 = ReportReason;
-inputReportReasonChildAbuse#adf44ee3 = ReportReason;
-inputReportReasonOther#e1746d0a text:string = ReportReason;
-inputReportReasonCopyright#9b89f93a = ReportReason;
-inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
-
-userFull#edf17c12 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true user:User about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int = UserFull;
-
-contact#f911c994 user_id:int mutual:Bool = Contact;
-
-importedContact#d0028438 user_id:int client_id:long = ImportedContact;
-
-contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
-
-contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
-
-contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
-contacts.contacts#eae87e42 contacts:Vector<Contact> saved_count:int users:Vector<User> = contacts.Contacts;
-
-contacts.importedContacts#77d01c3b imported:Vector<ImportedContact> popular_invites:Vector<PopularContact> retry_contacts:Vector<long> users:Vector<User> = contacts.ImportedContacts;
-
-contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
-contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
-
-messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
-messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
-messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
-
-messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesSlice#c8edce1e flags:# inexact:flags.1?true count:int next_rate:flags.0?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesNotModified#74535f21 count:int = messages.Messages;
-
-messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
-messages.chatsSlice#9cd81144 count:int chats:Vector<Chat> = messages.Chats;
-
-messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
-
-messages.affectedHistory#b45c69d1 pts:int pts_count:int offset:int = messages.AffectedHistory;
-
-inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
-inputMessagesFilterPhotos#9609a51c = MessagesFilter;
-inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
-inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
-inputMessagesFilterDocument#9eddf188 = MessagesFilter;
-inputMessagesFilterUrl#7ef0dd87 = MessagesFilter;
-inputMessagesFilterGif#ffc86587 = MessagesFilter;
-inputMessagesFilterVoice#50f5c392 = MessagesFilter;
-inputMessagesFilterMusic#3751b49e = MessagesFilter;
-inputMessagesFilterChatPhotos#3a20ecb8 = MessagesFilter;
-inputMessagesFilterPhoneCalls#80c99768 flags:# missed:flags.0?true = MessagesFilter;
-inputMessagesFilterRoundVoice#7a7c17a4 = MessagesFilter;
-inputMessagesFilterRoundVideo#b549da53 = MessagesFilter;
-inputMessagesFilterMyMentions#c1f8e69a = MessagesFilter;
-inputMessagesFilterGeo#e7026d0d = MessagesFilter;
-inputMessagesFilterContacts#e062db83 = MessagesFilter;
-
-updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
-updateMessageID#4e90bfd6 id:int random_id:long = Update;
-updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
-updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
-updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
-updateChatParticipants#7761198 participants:ChatParticipants = Update;
-updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
-updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
-updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
-updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
-updateEncryptedChatTyping#1710f156 chat_id:int = Update;
-updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
-updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
-updateChatParticipantAdd#ea4b0e5c chat_id:int user_id:int inviter_id:int date:int version:int = Update;
-updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
-updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
-updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
-updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
-updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector<MessageEntity> = Update;
-updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
-updateUserPhone#12b9417b user_id:int phone:string = Update;
-updateReadHistoryInbox#9c974fdf flags:# folder_id:flags.0?int peer:Peer max_id:int still_unread_count:int pts:int pts_count:int = Update;
-updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
-updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update;
-updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
-updateChannelTooLong#eb0467fb flags:# channel_id:int pts:flags.0?int = Update;
-updateChannel#b6d45656 channel_id:int = Update;
-updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
-updateReadChannelInbox#330b5424 flags:# folder_id:flags.0?int channel_id:int max_id:int still_unread_count:int pts:int = Update;
-updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
-updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
-updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
-updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
-updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector<long> = Update;
-updateStickerSets#43ae3dec = Update;
-updateSavedGifs#9375341e = Update;
-updateBotInlineQuery#54826690 flags:# query_id:long user_id:int query:string geo:flags.0?GeoPoint offset:string = Update;
-updateBotInlineSend#e48f964 flags:# user_id:int query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update;
-updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update;
-updateChannelPinnedMessage#98592475 channel_id:int id:int = Update;
-updateBotCallbackQuery#e73547e1 flags:# query_id:long user_id:int peer:Peer msg_id:int chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
-updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
-updateInlineBotCallbackQuery#f9d27a5a flags:# query_id:long user_id:int msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
-updateReadChannelOutbox#25d6c9c7 channel_id:int max_id:int = Update;
-updateDraftMessage#ee2bb969 peer:Peer draft:DraftMessage = Update;
-updateReadFeaturedStickers#571d2742 = Update;
-updateRecentStickers#9a422c20 = Update;
-updateConfig#a229dd06 = Update;
-updatePtsChanged#3354678f = Update;
-updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
-updateDialogPinned#6e6fe51c flags:# pinned:flags.0?true folder_id:flags.1?int peer:DialogPeer = Update;
-updatePinnedDialogs#fa0f3ca2 flags:# folder_id:flags.1?int order:flags.0?Vector<DialogPeer> = Update;
-updateBotWebhookJSON#8317c0c3 data:DataJSON = Update;
-updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update;
-updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
-updateBotPrecheckoutQuery#5d2f3aa9 flags:# query_id:long user_id:int payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string currency:string total_amount:long = Update;
-updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
-updateLangPackTooLong#46560264 lang_code:string = Update;
-updateLangPack#56022f4d difference:LangPackDifference = Update;
-updateFavedStickers#e511996d = Update;
-updateChannelReadMessagesContents#89893b45 channel_id:int messages:Vector<int> = Update;
-updateContactsReset#7084a7be = Update;
-updateChannelAvailableMessages#70db6837 channel_id:int available_min_id:int = Update;
-updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
-updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
-updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update;
-updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
-updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
-updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
-updatePeerSettings#6a7e7366 peer:Peer settings:PeerSettings = Update;
-updatePeerLocated#b4afcfb0 peers:Vector<PeerLocated> = Update;
-updateNewScheduledMessage#39a51dfb message:Message = Update;
-updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector<int> = Update;
-updateTheme#8216fba3 theme:Theme = Update;
-
-updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
-
-updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
-updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
-updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
-updates.differenceTooLong#4afe8f6d pts:int = updates.Difference;
-
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#914fbf11 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#16812688 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
-
-photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
-photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> = photos.Photos;
-
-photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
-
-upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
-upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
-
-dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
-
-config#330b4067 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
-
-nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
-
-help.appUpdate#1da7158f flags:# can_not_skip:flags.0?true id:int version:string text:string entities:Vector<MessageEntity> document:flags.1?Document url:flags.2?string = help.AppUpdate;
-help.noAppUpdate#c45a6536 = help.AppUpdate;
-
-help.inviteText#18cb9f78 message:string = help.InviteText;
-
-encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
-encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
-encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
-encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat;
-encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
-
-inputEncryptedChat#f141b5e1 chat_id:int access_hash:long = InputEncryptedChat;
-
-encryptedFileEmpty#c21f497e = EncryptedFile;
-encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile;
-
-inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
-inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
-inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
-inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
-
-encryptedMessage#ed18c118 random_id:long chat_id:int date:int bytes:bytes file:EncryptedFile = EncryptedMessage;
-encryptedMessageService#23734b06 random_id:long chat_id:int date:int bytes:bytes = EncryptedMessage;
-
-messages.dhConfigNotModified#c0e24635 random:bytes = messages.DhConfig;
-messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhConfig;
-
-messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
-messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
-
-inputDocumentEmpty#72f0eaae = InputDocument;
-inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
-
-documentEmpty#36f8c871 id:long = Document;
-document#9ba29cc1 flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumbs:flags.0?Vector<PhotoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document;
-
-help.support#17c6b5f6 phone_number:string user:User = help.Support;
-
-notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
-notifyUsers#b4c83b4c = NotifyPeer;
-notifyChats#c007cec3 = NotifyPeer;
-notifyBroadcasts#d612e8ef = NotifyPeer;
-
-sendMessageTypingAction#16bf744e = SendMessageAction;
-sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
-sendMessageRecordVideoAction#a187d66f = SendMessageAction;
-sendMessageUploadVideoAction#e9763aec progress:int = SendMessageAction;
-sendMessageRecordAudioAction#d52f73f7 = SendMessageAction;
-sendMessageUploadAudioAction#f351d7ab progress:int = SendMessageAction;
-sendMessageUploadPhotoAction#d1d34a26 progress:int = SendMessageAction;
-sendMessageUploadDocumentAction#aa0cd9e4 progress:int = SendMessageAction;
-sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
-sendMessageChooseContactAction#628cbc6f = SendMessageAction;
-sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
-sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
-sendMessageUploadRoundAction#243e1c66 progress:int = SendMessageAction;
-
-contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
-
-inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
-inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
-inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey;
-inputPrivacyKeyPhoneP2P#db9e70d2 = InputPrivacyKey;
-inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey;
-inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey;
-inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey;
-inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey;
-
-privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
-privacyKeyChatInvite#500e6dfa = PrivacyKey;
-privacyKeyPhoneCall#3d662b7b = PrivacyKey;
-privacyKeyPhoneP2P#39491cc8 = PrivacyKey;
-privacyKeyForwards#69ec56a3 = PrivacyKey;
-privacyKeyProfilePhoto#96151fed = PrivacyKey;
-privacyKeyPhoneNumber#d19ae46d = PrivacyKey;
-privacyKeyAddedByPhone#42ffd42b = PrivacyKey;
-
-inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
-inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
-inputPrivacyValueAllowUsers#131cc67f users:Vector<InputUser> = InputPrivacyRule;
-inputPrivacyValueDisallowContacts#ba52007 = InputPrivacyRule;
-inputPrivacyValueDisallowAll#d66b66c9 = InputPrivacyRule;
-inputPrivacyValueDisallowUsers#90110467 users:Vector<InputUser> = InputPrivacyRule;
-inputPrivacyValueAllowChatParticipants#4c81c1ba chats:Vector<int> = InputPrivacyRule;
-inputPrivacyValueDisallowChatParticipants#d82363af chats:Vector<int> = InputPrivacyRule;
-
-privacyValueAllowContacts#fffe1bac = PrivacyRule;
-privacyValueAllowAll#65427b82 = PrivacyRule;
-privacyValueAllowUsers#4d5bbe0c users:Vector<int> = PrivacyRule;
-privacyValueDisallowContacts#f888fa1a = PrivacyRule;
-privacyValueDisallowAll#8b73e763 = PrivacyRule;
-privacyValueDisallowUsers#c7f49b7 users:Vector<int> = PrivacyRule;
-privacyValueAllowChatParticipants#18be796b chats:Vector<int> = PrivacyRule;
-privacyValueDisallowChatParticipants#acae0690 chats:Vector<int> = PrivacyRule;
-
-account.privacyRules#50a04e45 rules:Vector<PrivacyRule> chats:Vector<Chat> users:Vector<User> = account.PrivacyRules;
-
-accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
-
-documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
-documentAttributeAnimated#11b58939 = DocumentAttribute;
-documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute;
-documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:int w:int h:int = DocumentAttribute;
-documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
-documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
-documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
-
-messages.stickersNotModified#f1749a22 = messages.Stickers;
-messages.stickers#e4599bbd hash:int stickers:Vector<Document> = messages.Stickers;
-
-stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
-
-messages.allStickersNotModified#e86602c3 = messages.AllStickers;
-messages.allStickers#edfd405f hash:int sets:Vector<StickerSet> = messages.AllStickers;
-
-messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
-
-webPageEmpty#eb1477e8 id:long = WebPage;
-webPagePending#c586da1c id:long date:int = WebPage;
-webPage#fa64e172 flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document documents:flags.11?Vector<Document> cached_page:flags.10?Page = WebPage;
-webPageNotModified#85849473 = WebPage;
-
-authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
-
-account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
-
-account.password#ad2641f8 flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes = account.Password;
-
-account.passwordSettings#9a5c33e5 flags:# email:flags.0?string secure_settings:flags.1?SecureSecretSettings = account.PasswordSettings;
-
-account.passwordInputSettings#c23727c9 flags:# new_algo:flags.0?PasswordKdfAlgo new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string new_secure_settings:flags.2?SecureSecretSettings = account.PasswordInputSettings;
-
-auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
-
-receivedNotifyMessage#a384b779 id:int flags:int = ReceivedNotifyMessage;
-
-chatInviteEmpty#69df3769 = ExportedChatInvite;
-chatInviteExported#fc2e05bc link:string = ExportedChatInvite;
-
-chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
-chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector<User> = ChatInvite;
-
-inputStickerSetEmpty#ffb62b95 = InputStickerSet;
-inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
-inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
-inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
-
-stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet;
-
-messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
-
-botCommand#c27ac8c7 command:string description:string = BotCommand;
-
-botInfo#98e81d3a user_id:int description:string commands:Vector<BotCommand> = BotInfo;
-
-keyboardButton#a2fa4880 text:string = KeyboardButton;
-keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton;
-keyboardButtonCallback#683a5e46 text:string data:bytes = KeyboardButton;
-keyboardButtonRequestPhone#b16a6c29 text:string = KeyboardButton;
-keyboardButtonRequestGeoLocation#fc796b3f text:string = KeyboardButton;
-keyboardButtonSwitchInline#568a748 flags:# same_peer:flags.0?true text:string query:string = KeyboardButton;
-keyboardButtonGame#50f41ccf text:string = KeyboardButton;
-keyboardButtonBuy#afd93fbb text:string = KeyboardButton;
-keyboardButtonUrlAuth#10b78d29 flags:# text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton;
-inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton;
-
-keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
-
-replyKeyboardHide#a03e5b85 flags:# selective:flags.2?true = ReplyMarkup;
-replyKeyboardForceReply#f4108aa0 flags:# single_use:flags.1?true selective:flags.2?true = ReplyMarkup;
-replyKeyboardMarkup#3502758c flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true rows:Vector<KeyboardButtonRow> = ReplyMarkup;
-replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;
-
-messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
-messageEntityMention#fa04579d offset:int length:int = MessageEntity;
-messageEntityHashtag#6f635b0d offset:int length:int = MessageEntity;
-messageEntityBotCommand#6cef8ac7 offset:int length:int = MessageEntity;
-messageEntityUrl#6ed02538 offset:int length:int = MessageEntity;
-messageEntityEmail#64e475c2 offset:int length:int = MessageEntity;
-messageEntityBold#bd610bc9 offset:int length:int = MessageEntity;
-messageEntityItalic#826f8b60 offset:int length:int = MessageEntity;
-messageEntityCode#28a20571 offset:int length:int = MessageEntity;
-messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
-messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
-messageEntityMentionName#352dca58 offset:int length:int user_id:int = MessageEntity;
-inputMessageEntityMentionName#208e68c9 offset:int length:int user_id:InputUser = MessageEntity;
-messageEntityPhone#9b69e34b offset:int length:int = MessageEntity;
-messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity;
-messageEntityUnderline#9c4e7e8b offset:int length:int = MessageEntity;
-messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity;
-messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity;
-
-inputChannelEmpty#ee8c1e86 = InputChannel;
-inputChannel#afeb712e channel_id:int access_hash:long = InputChannel;
-inputChannelFromMessage#2a286531 peer:InputPeer msg_id:int channel_id:int = InputChannel;
-
-contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;
-
-messageRange#ae30253 min_id:int max_id:int = MessageRange;
-
-updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int = updates.ChannelDifference;
-updates.channelDifferenceTooLong#a4bcc6fe flags:# final:flags.0?true timeout:flags.1?int dialog:Dialog messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
-updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:flags.1?int new_messages:Vector<Message> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
-
-channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter;
-channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector<MessageRange> = ChannelMessagesFilter;
-
-channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
-channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
-channelParticipantCreator#808d15a4 flags:# user_id:int rank:flags.0?string = ChannelParticipant;
-channelParticipantAdmin#ccbebbaf flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant;
-channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
-
-channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
-channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
-channelParticipantsKicked#a3b54985 q:string = ChannelParticipantsFilter;
-channelParticipantsBots#b0d1865b = ChannelParticipantsFilter;
-channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
-channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
-channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
-
-channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
-channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
-
-channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
-
-help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;
-
-foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif;
-foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif;
-
-messages.foundGifs#450a1c0a next_offset:int results:Vector<FoundGif> = messages.FoundGifs;
-
-messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs;
-messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
-
-inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
-inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
-inputBotInlineMessageMediaGeo#c1b15d65 flags:# geo_point:InputGeoPoint period:int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
-inputBotInlineMessageMediaVenue#417bbf11 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
-inputBotInlineMessageMediaContact#a6edbffd flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
-inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
-
-inputBotInlineResult#88bf9319 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?InputWebDocument content:flags.5?InputWebDocument send_message:InputBotInlineMessage = InputBotInlineResult;
-inputBotInlineResultPhoto#a8d864a7 id:string type:string photo:InputPhoto send_message:InputBotInlineMessage = InputBotInlineResult;
-inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult;
-inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult;
-
-botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
-botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
-botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
-botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
-botInlineMessageMediaContact#18d1cdc2 flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
-
-botInlineResult#11965f3a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?WebDocument content:flags.5?WebDocument send_message:BotInlineMessage = BotInlineResult;
-botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
-
-messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM results:Vector<BotInlineResult> cache_time:int users:Vector<User> = messages.BotResults;
-
-exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
-
-messageFwdHeader#ec338270 flags:# from_id:flags.0?int from_name:flags.5?string date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
-
-auth.codeTypeSms#72a3158c = auth.CodeType;
-auth.codeTypeCall#741cd3e3 = auth.CodeType;
-auth.codeTypeFlashCall#226ccefb = auth.CodeType;
-
-auth.sentCodeTypeApp#3dbb5986 length:int = auth.SentCodeType;
-auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
-auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
-auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
-
-messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
-
-messages.messageEditData#26b5dde6 flags:# caption:flags.0?true = messages.MessageEditData;
-
-inputBotInlineMessageID#890c3d89 dc_id:int id:long access_hash:long = InputBotInlineMessageID;
-
-inlineBotSwitchPM#3c20629f text:string start_param:string = InlineBotSwitchPM;
-
-messages.peerDialogs#3371c354 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> state:updates.State = messages.PeerDialogs;
-
-topPeer#edcdc05b peer:Peer rating:double = TopPeer;
-
-topPeerCategoryBotsPM#ab661b5b = TopPeerCategory;
-topPeerCategoryBotsInline#148677e2 = TopPeerCategory;
-topPeerCategoryCorrespondents#637b7ed = TopPeerCategory;
-topPeerCategoryGroups#bd17a14a = TopPeerCategory;
-topPeerCategoryChannels#161d9628 = TopPeerCategory;
-topPeerCategoryPhoneCalls#1e76a78c = TopPeerCategory;
-topPeerCategoryForwardUsers#a8406ca9 = TopPeerCategory;
-topPeerCategoryForwardChats#fbeec0f0 = TopPeerCategory;
-
-topPeerCategoryPeers#fb834291 category:TopPeerCategory count:int peers:Vector<TopPeer> = TopPeerCategoryPeers;
-
-contacts.topPeersNotModified#de266ef5 = contacts.TopPeers;
-contacts.topPeers#70b772a8 categories:Vector<TopPeerCategoryPeers> chats:Vector<Chat> users:Vector<User> = contacts.TopPeers;
-contacts.topPeersDisabled#b52c939d = contacts.TopPeers;
-
-draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage;
-draftMessage#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector<MessageEntity> date:int = DraftMessage;
-
-messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers;
-messages.featuredStickers#f89d88e5 hash:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
-
-messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
-messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
-
-messages.archivedStickers#4fcba9c8 count:int sets:Vector<StickerSetCovered> = messages.ArchivedStickers;
-
-messages.stickerSetInstallResultSuccess#38641628 = messages.StickerSetInstallResult;
-messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered> = messages.StickerSetInstallResult;
-
-stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
-stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
-
-maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
-
-inputStickeredMediaPhoto#4a992157 id:InputPhoto = InputStickeredMedia;
-inputStickeredMediaDocument#438865b id:InputDocument = InputStickeredMedia;
-
-game#bdf9653b flags:# id:long access_hash:long short_name:string title:string description:string photo:Photo document:flags.0?Document = Game;
-
-inputGameID#32c3e77 id:long access_hash:long = InputGame;
-inputGameShortName#c331e80a bot_id:InputUser short_name:string = InputGame;
-
-highScore#58fffcd0 pos:int user_id:int score:int = HighScore;
-
-messages.highScores#9a3bfd99 scores:Vector<HighScore> users:Vector<User> = messages.HighScores;
-
-textEmpty#dc3d824f = RichText;
-textPlain#744694e0 text:string = RichText;
-textBold#6724abc4 text:RichText = RichText;
-textItalic#d912a59c text:RichText = RichText;
-textUnderline#c12622c4 text:RichText = RichText;
-textStrike#9bf8bb95 text:RichText = RichText;
-textFixed#6c3f19b9 text:RichText = RichText;
-textUrl#3c2884c1 text:RichText url:string webpage_id:long = RichText;
-textEmail#de5a0dd6 text:RichText email:string = RichText;
-textConcat#7e6260d7 texts:Vector<RichText> = RichText;
-textSubscript#ed6a8504 text:RichText = RichText;
-textSuperscript#c7fb5e01 text:RichText = RichText;
-textMarked#34b8621 text:RichText = RichText;
-textPhone#1ccb966a text:RichText phone:string = RichText;
-textImage#81ccf4f document_id:long w:int h:int = RichText;
-textAnchor#35553762 text:RichText name:string = RichText;
-
-pageBlockUnsupported#13567e8a = PageBlock;
-pageBlockTitle#70abc3fd text:RichText = PageBlock;
-pageBlockSubtitle#8ffa9a1f text:RichText = PageBlock;
-pageBlockAuthorDate#baafe5e0 author:RichText published_date:int = PageBlock;
-pageBlockHeader#bfd064ec text:RichText = PageBlock;
-pageBlockSubheader#f12bb6e1 text:RichText = PageBlock;
-pageBlockParagraph#467a0766 text:RichText = PageBlock;
-pageBlockPreformatted#c070d93e text:RichText language:string = PageBlock;
-pageBlockFooter#48870999 text:RichText = PageBlock;
-pageBlockDivider#db20b188 = PageBlock;
-pageBlockAnchor#ce0d37b0 name:string = PageBlock;
-pageBlockList#e4e88011 items:Vector<PageListItem> = PageBlock;
-pageBlockBlockquote#263d7c26 text:RichText caption:RichText = PageBlock;
-pageBlockPullquote#4f4456d3 text:RichText caption:RichText = PageBlock;
-pageBlockPhoto#1759c560 flags:# photo_id:long caption:PageCaption url:flags.0?string webpage_id:flags.0?long = PageBlock;
-pageBlockVideo#7c8fe7b6 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:PageCaption = PageBlock;
-pageBlockCover#39f23300 cover:PageBlock = PageBlock;
-pageBlockEmbed#a8718dc5 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:flags.5?int h:flags.5?int caption:PageCaption = PageBlock;
-pageBlockEmbedPost#f259a80b url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:PageCaption = PageBlock;
-pageBlockCollage#65a0fa4d items:Vector<PageBlock> caption:PageCaption = PageBlock;
-pageBlockSlideshow#31f9590 items:Vector<PageBlock> caption:PageCaption = PageBlock;
-pageBlockChannel#ef1751b5 channel:Chat = PageBlock;
-pageBlockAudio#804361ea audio_id:long caption:PageCaption = PageBlock;
-pageBlockKicker#1e148390 text:RichText = PageBlock;
-pageBlockTable#bf4dea82 flags:# bordered:flags.0?true striped:flags.1?true title:RichText rows:Vector<PageTableRow> = PageBlock;
-pageBlockOrderedList#9a8ae1e1 items:Vector<PageListOrderedItem> = PageBlock;
-pageBlockDetails#76768bed flags:# open:flags.0?true blocks:Vector<PageBlock> title:RichText = PageBlock;
-pageBlockRelatedArticles#16115a96 title:RichText articles:Vector<PageRelatedArticle> = PageBlock;
-pageBlockMap#a44f3ef6 geo:GeoPoint zoom:int w:int h:int caption:PageCaption = PageBlock;
-
-phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
-phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
-phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason;
-phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason;
-
-dataJSON#7d748d04 data:string = DataJSON;
-
-labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;
-
-invoice#c30aa358 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true currency:string prices:Vector<LabeledPrice> = Invoice;
-
-paymentCharge#ea02c27e id:string provider_charge_id:string = PaymentCharge;
-
-postAddress#1e8caaeb street_line1:string street_line2:string city:string state:string country_iso2:string post_code:string = PostAddress;
-
-paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string email:flags.2?string shipping_address:flags.3?PostAddress = PaymentRequestedInfo;
-
-paymentSavedCredentialsCard#cdc27a1f id:string title:string = PaymentSavedCredentials;
-
-webDocument#1c570ed1 url:string access_hash:long size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument;
-webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument;
-
-inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;
-
-inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation;
-inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation;
-
-upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile;
-
-payments.paymentForm#3f56aea3 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true bot_id:int invoice:Invoice provider_id:int url:string native_provider:flags.4?string native_params:flags.4?DataJSON saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?PaymentSavedCredentials users:Vector<User> = payments.PaymentForm;
-
-payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = payments.ValidatedRequestedInfo;
-
-payments.paymentResult#4e5f810d updates:Updates = payments.PaymentResult;
-payments.paymentVerificationNeeded#d8411139 url:string = payments.PaymentResult;
-
-payments.paymentReceipt#500911e1 flags:# date:int bot_id:int invoice:Invoice provider_id:int info:flags.0?PaymentRequestedInfo shipping:flags.1?ShippingOption currency:string total_amount:long credentials_title:string users:Vector<User> = payments.PaymentReceipt;
-
-payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_info:flags.0?PaymentRequestedInfo = payments.SavedInfo;
-
-inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials;
-inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;
-inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials;
-inputPaymentCredentialsAndroidPay#ca05d50e payment_token:DataJSON google_transaction_id:string = InputPaymentCredentials;
-
-account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
-
-shippingOption#b6213cdf id:string title:string prices:Vector<LabeledPrice> = ShippingOption;
-
-inputStickerSetItem#ffa0a496 flags:# document:InputDocument emoji:string mask_coords:flags.0?MaskCoords = InputStickerSetItem;
-
-inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall;
-
-phoneCallEmpty#5366c915 id:long = PhoneCall;
-phoneCallWaiting#1b8f4ad1 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
-phoneCallRequested#87eabb53 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
-phoneCallAccepted#997c454a flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
-phoneCall#8742ae7f flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int = PhoneCall;
-phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.5?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
-
-phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
-
-phoneCallProtocol#a2bb35cb flags:# udp_p2p:flags.0?true udp_reflector:flags.1?true min_layer:int max_layer:int = PhoneCallProtocol;
-
-phone.phoneCall#ec82e140 phone_call:PhoneCall users:Vector<User> = phone.PhoneCall;
-
-upload.cdnFileReuploadNeeded#eea8e46e request_token:bytes = upload.CdnFile;
-upload.cdnFile#a99fca4f bytes:bytes = upload.CdnFile;
-
-cdnPublicKey#c982eaba dc_id:int public_key:string = CdnPublicKey;
-
-cdnConfig#5725e40a public_keys:Vector<CdnPublicKey> = CdnConfig;
-
-langPackString#cad181f6 key:string value:string = LangPackString;
-langPackStringPluralized#6c47ac9f flags:# key:string zero_value:flags.0?string one_value:flags.1?string two_value:flags.2?string few_value:flags.3?string many_value:flags.4?string other_value:string = LangPackString;
-langPackStringDeleted#2979eeb2 key:string = LangPackString;
-
-langPackDifference#f385c1f6 lang_code:string from_version:int version:int strings:Vector<LangPackString> = LangPackDifference;
-
-langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:flags.3?true name:string native_name:string lang_code:string base_lang_code:flags.1?string plural_code:string strings_count:int translated_count:int translations_url:string = LangPackLanguage;
-
-channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction;
-channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction;
-channelAdminLogEventActionChangeUsername#6a4afc38 prev_value:string new_value:string = ChannelAdminLogEventAction;
-channelAdminLogEventActionChangePhoto#434bd2af prev_photo:Photo new_photo:Photo = ChannelAdminLogEventAction;
-channelAdminLogEventActionToggleInvites#1b7907ae new_value:Bool = ChannelAdminLogEventAction;
-channelAdminLogEventActionToggleSignatures#26ae0971 new_value:Bool = ChannelAdminLogEventAction;
-channelAdminLogEventActionUpdatePinned#e9e82c18 message:Message = ChannelAdminLogEventAction;
-channelAdminLogEventActionEditMessage#709b2405 prev_message:Message new_message:Message = ChannelAdminLogEventAction;
-channelAdminLogEventActionDeleteMessage#42e047bb message:Message = ChannelAdminLogEventAction;
-channelAdminLogEventActionParticipantJoin#183040d3 = ChannelAdminLogEventAction;
-channelAdminLogEventActionParticipantLeave#f89777f2 = ChannelAdminLogEventAction;
-channelAdminLogEventActionParticipantInvite#e31c34d8 participant:ChannelParticipant = ChannelAdminLogEventAction;
-channelAdminLogEventActionParticipantToggleBan#e6d83d7e prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
-channelAdminLogEventActionParticipantToggleAdmin#d5676710 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
-channelAdminLogEventActionChangeStickerSet#b1c3caa7 prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
-channelAdminLogEventActionTogglePreHistoryHidden#5f5c95f1 new_value:Bool = ChannelAdminLogEventAction;
-channelAdminLogEventActionDefaultBannedRights#2df5fc0a prev_banned_rights:ChatBannedRights new_banned_rights:ChatBannedRights = ChannelAdminLogEventAction;
-channelAdminLogEventActionStopPoll#8f079643 message:Message = ChannelAdminLogEventAction;
-channelAdminLogEventActionChangeLinkedChat#a26f881b prev_value:int new_value:int = ChannelAdminLogEventAction;
-channelAdminLogEventActionChangeLocation#e6b76ae prev_value:ChannelLocation new_value:ChannelLocation = ChannelAdminLogEventAction;
-channelAdminLogEventActionToggleSlowMode#53909779 prev_value:int new_value:int = ChannelAdminLogEventAction;
-
-channelAdminLogEvent#3b5a3e40 id:long date:int user_id:int action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
-
-channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
-
-channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true = ChannelAdminLogEventsFilter;
-
-popularContact#5ce14175 client_id:long importers:int = PopularContact;
-
-messages.favedStickersNotModified#9e8fa6d3 = messages.FavedStickers;
-messages.favedStickers#f37f2f16 hash:int packs:Vector<StickerPack> stickers:Vector<Document> = messages.FavedStickers;
-
-recentMeUrlUnknown#46e1d13d url:string = RecentMeUrl;
-recentMeUrlUser#8dbc3336 url:string user_id:int = RecentMeUrl;
-recentMeUrlChat#a01b22f9 url:string chat_id:int = RecentMeUrl;
-recentMeUrlChatInvite#eb49081d url:string chat_invite:ChatInvite = RecentMeUrl;
-recentMeUrlStickerSet#bc0a57dc url:string set:StickerSetCovered = RecentMeUrl;
-
-help.recentMeUrls#e0310d7 urls:Vector<RecentMeUrl> chats:Vector<Chat> users:Vector<User> = help.RecentMeUrls;
-
-inputSingleMedia#1cc6e91f flags:# media:InputMedia random_id:long message:string entities:flags.0?Vector<MessageEntity> = InputSingleMedia;
-
-webAuthorization#cac943f2 hash:long bot_id:int domain:string browser:string platform:string date_created:int date_active:int ip:string region:string = WebAuthorization;
-
-account.webAuthorizations#ed56c9fc authorizations:Vector<WebAuthorization> users:Vector<User> = account.WebAuthorizations;
-
-inputMessageID#a676a322 id:int = InputMessage;
-inputMessageReplyTo#bad88395 id:int = InputMessage;
-inputMessagePinned#86872538 = InputMessage;
-
-inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
-inputDialogPeerFolder#64600527 folder_id:int = InputDialogPeer;
-
-dialogPeer#e56dbf05 peer:Peer = DialogPeer;
-dialogPeerFolder#514519e2 folder_id:int = DialogPeer;
-
-messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets;
-messages.foundStickerSets#5108d648 hash:int sets:Vector<StickerSetCovered> = messages.FoundStickerSets;
-
-fileHash#6242c773 offset:int limit:int hash:bytes = FileHash;
-
-inputClientProxy#75588b3f address:string port:int = InputClientProxy;
-
-help.proxyDataEmpty#e09e1fb8 expires:int = help.ProxyData;
-help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vector<User> = help.ProxyData;
-
-help.termsOfServiceUpdateEmpty#e3309f7f expires:int = help.TermsOfServiceUpdate;
-help.termsOfServiceUpdate#28ecf961 expires:int terms_of_service:help.TermsOfService = help.TermsOfServiceUpdate;
-
-inputSecureFileUploaded#3334b0f0 id:long parts:int md5_checksum:string file_hash:bytes secret:bytes = InputSecureFile;
-inputSecureFile#5367e5be id:long access_hash:long = InputSecureFile;
-
-secureFileEmpty#64199744 = SecureFile;
-secureFile#e0277a62 id:long access_hash:long size:int dc_id:int date:int file_hash:bytes secret:bytes = SecureFile;
-
-secureData#8aeabec3 data:bytes data_hash:bytes secret:bytes = SecureData;
-
-securePlainPhone#7d6099dd phone:string = SecurePlainData;
-securePlainEmail#21ec5a5f email:string = SecurePlainData;
-
-secureValueTypePersonalDetails#9d2a81e3 = SecureValueType;
-secureValueTypePassport#3dac6a00 = SecureValueType;
-secureValueTypeDriverLicense#6e425c4 = SecureValueType;
-secureValueTypeIdentityCard#a0d0744b = SecureValueType;
-secureValueTypeInternalPassport#99a48f23 = SecureValueType;
-secureValueTypeAddress#cbe31e26 = SecureValueType;
-secureValueTypeUtilityBill#fc36954e = SecureValueType;
-secureValueTypeBankStatement#89137c0d = SecureValueType;
-secureValueTypeRentalAgreement#8b883488 = SecureValueType;
-secureValueTypePassportRegistration#99e3806a = SecureValueType;
-secureValueTypeTemporaryRegistration#ea02ec33 = SecureValueType;
-secureValueTypePhone#b320aadb = SecureValueType;
-secureValueTypeEmail#8e3ca7ee = SecureValueType;
-
-secureValue#187fa0ca flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?SecureFile reverse_side:flags.2?SecureFile selfie:flags.3?SecureFile translation:flags.6?Vector<SecureFile> files:flags.4?Vector<SecureFile> plain_data:flags.5?SecurePlainData hash:bytes = SecureValue;
-
-inputSecureValue#db21d0a7 flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?InputSecureFile reverse_side:flags.2?InputSecureFile selfie:flags.3?InputSecureFile translation:flags.6?Vector<InputSecureFile> files:flags.4?Vector<InputSecureFile> plain_data:flags.5?SecurePlainData = InputSecureValue;
-
-secureValueHash#ed1ecdb0 type:SecureValueType hash:bytes = SecureValueHash;
-
-secureValueErrorData#e8a40bd9 type:SecureValueType data_hash:bytes field:string text:string = SecureValueError;
-secureValueErrorFrontSide#be3dfa type:SecureValueType file_hash:bytes text:string = SecureValueError;
-secureValueErrorReverseSide#868a2aa5 type:SecureValueType file_hash:bytes text:string = SecureValueError;
-secureValueErrorSelfie#e537ced6 type:SecureValueType file_hash:bytes text:string = SecureValueError;
-secureValueErrorFile#7a700873 type:SecureValueType file_hash:bytes text:string = SecureValueError;
-secureValueErrorFiles#666220e9 type:SecureValueType file_hash:Vector<bytes> text:string = SecureValueError;
-secureValueError#869d758f type:SecureValueType hash:bytes text:string = SecureValueError;
-secureValueErrorTranslationFile#a1144770 type:SecureValueType file_hash:bytes text:string = SecureValueError;
-secureValueErrorTranslationFiles#34636dd8 type:SecureValueType file_hash:Vector<bytes> text:string = SecureValueError;
-
-secureCredentialsEncrypted#33f0ea47 data:bytes hash:bytes secret:bytes = SecureCredentialsEncrypted;
-
-account.authorizationForm#ad2e1cd8 flags:# required_types:Vector<SecureRequiredType> values:Vector<SecureValue> errors:Vector<SecureValueError> users:Vector<User> privacy_policy_url:flags.0?string = account.AuthorizationForm;
-
-account.sentEmailCode#811f854f email_pattern:string length:int = account.SentEmailCode;
-
-help.deepLinkInfoEmpty#66afa166 = help.DeepLinkInfo;
-help.deepLinkInfo#6a4ee832 flags:# update_app:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = help.DeepLinkInfo;
-
-savedPhoneContact#1142bd56 phone:string first_name:string last_name:string date:int = SavedContact;
-
-account.takeout#4dba4501 id:long = account.Takeout;
-
-passwordKdfAlgoUnknown#d45ab096 = PasswordKdfAlgo;
-passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow#3a912d4a salt1:bytes salt2:bytes g:int p:bytes = PasswordKdfAlgo;
-
-securePasswordKdfAlgoUnknown#4a8537 = SecurePasswordKdfAlgo;
-securePasswordKdfAlgoPBKDF2HMACSHA512iter100000#bbf2dda0 salt:bytes = SecurePasswordKdfAlgo;
-securePasswordKdfAlgoSHA512#86471d92 salt:bytes = SecurePasswordKdfAlgo;
-
-secureSecretSettings#1527bcac secure_algo:SecurePasswordKdfAlgo secure_secret:bytes secure_secret_id:long = SecureSecretSettings;
-
-inputCheckPasswordEmpty#9880f658 = InputCheckPasswordSRP;
-inputCheckPasswordSRP#d27ff082 srp_id:long A:bytes M1:bytes = InputCheckPasswordSRP;
-
-secureRequiredType#829d99da flags:# native_names:flags.0?true selfie_required:flags.1?true translation_required:flags.2?true type:SecureValueType = SecureRequiredType;
-secureRequiredTypeOneOf#27477b4 types:Vector<SecureRequiredType> = SecureRequiredType;
-
-help.passportConfigNotModified#bfb9f457 = help.PassportConfig;
-help.passportConfig#a098d6af hash:int countries_langs:DataJSON = help.PassportConfig;
-
-inputAppEvent#1d1b1245 time:double type:string peer:long data:JSONValue = InputAppEvent;
-
-jsonObjectValue#c0de1bd9 key:string value:JSONValue = JSONObjectValue;
-
-jsonNull#3f6d7b68 = JSONValue;
-jsonBool#c7345e6a value:Bool = JSONValue;
-jsonNumber#2be0dfa4 value:double = JSONValue;
-jsonString#b71e767a value:string = JSONValue;
-jsonArray#f7444763 value:Vector<JSONValue> = JSONValue;
-jsonObject#99c1d49d value:Vector<JSONObjectValue> = JSONValue;
-
-pageTableCell#34566b6a flags:# header:flags.0?true align_center:flags.3?true align_right:flags.4?true valign_middle:flags.5?true valign_bottom:flags.6?true text:flags.7?RichText colspan:flags.1?int rowspan:flags.2?int = PageTableCell;
-
-pageTableRow#e0c0c5e5 cells:Vector<PageTableCell> = PageTableRow;
-
-pageCaption#6f747657 text:RichText credit:RichText = PageCaption;
-
-pageListItemText#b92fb6cd text:RichText = PageListItem;
-pageListItemBlocks#25e073fc blocks:Vector<PageBlock> = PageListItem;
-
-pageListOrderedItemText#5e068047 num:string text:RichText = PageListOrderedItem;
-pageListOrderedItemBlocks#98dd8936 num:string blocks:Vector<PageBlock> = PageListOrderedItem;
-
-pageRelatedArticle#b390dc08 flags:# url:string webpage_id:long title:flags.0?string description:flags.1?string photo_id:flags.2?long author:flags.3?string published_date:flags.4?int = PageRelatedArticle;
-
-page#ae891bec flags:# part:flags.0?true rtl:flags.1?true v2:flags.2?true url:string blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
-
-help.supportName#8c05f1c9 name:string = help.SupportName;
-
-help.userInfoEmpty#f3ae2eed = help.UserInfo;
-help.userInfo#1eb3758 message:string entities:Vector<MessageEntity> author:string date:int = help.UserInfo;
-
-pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
-
-poll#d5529d06 id:long flags:# closed:flags.0?true question:string answers:Vector<PollAnswer> = Poll;
-
-pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true option:bytes voters:int = PollAnswerVoters;
-
-pollResults#5755785a flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int = PollResults;
-
-chatOnlines#f041e250 onlines:int = ChatOnlines;
-
-statsURL#47a971e0 url:string = StatsURL;
-
-chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true = ChatAdminRights;
-
-chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights;
-
-inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
-inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
-
-account.wallPapersNotModified#1c199183 = account.WallPapers;
-account.wallPapers#702b65a9 hash:int wallpapers:Vector<WallPaper> = account.WallPapers;
-
-codeSettings#debebe83 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true = CodeSettings;
-
-wallPaperSettings#a12f40b8 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int intensity:flags.3?int = WallPaperSettings;
-
-autoDownloadSettings#d246fd47 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true photo_size_max:int video_size_max:int file_size_max:int = AutoDownloadSettings;
-
-account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings;
-
-emojiKeyword#d5b3b9f9 keyword:string emoticons:Vector<string> = EmojiKeyword;
-emojiKeywordDeleted#236df622 keyword:string emoticons:Vector<string> = EmojiKeyword;
-
-emojiKeywordsDifference#5cc761bd lang_code:string from_version:int version:int keywords:Vector<EmojiKeyword> = EmojiKeywordsDifference;
-
-emojiURL#a575739d url:string = EmojiURL;
-
-emojiLanguage#b3fb5361 lang_code:string = EmojiLanguage;
-
-fileLocationToBeDeprecated#bc7fc6cd volume_id:long local_id:int = FileLocation;
-
-folder#ff544e65 flags:# autofill_new_broadcasts:flags.0?true autofill_public_groups:flags.1?true autofill_new_correspondents:flags.2?true id:int title:string photo:flags.3?ChatPhoto = Folder;
-
-inputFolderPeer#fbd2c296 peer:InputPeer folder_id:int = InputFolderPeer;
-
-folderPeer#e9baa668 peer:Peer folder_id:int = FolderPeer;
-
-messages.searchCounter#e844ebff flags:# inexact:flags.1?true filter:MessagesFilter count:int = messages.SearchCounter;
-
-urlAuthResultRequest#92d33a0e flags:# request_write_access:flags.0?true bot:User domain:string = UrlAuthResult;
-urlAuthResultAccepted#8f8c0e4e url:string = UrlAuthResult;
-urlAuthResultDefault#a9d6db1f = UrlAuthResult;
-
-channelLocationEmpty#bfb5ad8b = ChannelLocation;
-channelLocation#209b82db geo_point:GeoPoint address:string = ChannelLocation;
-
-peerLocated#ca461b5d peer:Peer expires:int distance:int = PeerLocated;
-
-restrictionReason#d072acb4 platform:string reason:string text:string = RestrictionReason;
-
-inputTheme#3c5693e9 id:long access_hash:long = InputTheme;
-inputThemeSlug#f5890df1 slug:string = InputTheme;
-
-themeDocumentNotModified#483d270c = Theme;
-theme#f7d90ce0 flags:# creator:flags.0?true default:flags.1?true id:long access_hash:long slug:string title:string document:flags.2?Document installs_count:int = Theme;
-
-account.themesNotModified#f41eb622 = account.Themes;
-account.themes#7f676421 hash:int themes:Vector<Theme> = account.Themes;
-
----functions---
-
-invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
-invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
-initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
-invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
-invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
-invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
-invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
-
-auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
-auth.signUp#80eee427 phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
-auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
-auth.logOut#5717da40 = Bool;
-auth.resetAuthorizations#9fab0d1a = Bool;
-auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
-auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
-auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool;
-auth.importBotAuthorization#67a3ff2c flags:int api_id:int api_hash:string bot_auth_token:string = auth.Authorization;
-auth.checkPassword#d18b4d16 password:InputCheckPasswordSRP = auth.Authorization;
-auth.requestPasswordRecovery#d897bc66 = auth.PasswordRecovery;
-auth.recoverPassword#4ea56e92 code:string = auth.Authorization;
-auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentCode;
-auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
-auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
-
-account.registerDevice#68976c6f flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
-account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
-account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
-account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
-account.resetNotifySettings#db7e1747 = Bool;
-account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
-account.updateStatus#6628562c offline:Bool = Bool;
-account.getWallPapers#aabb1763 hash:int = account.WallPapers;
-account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
-account.checkUsername#2714d86c username:string = Bool;
-account.updateUsername#3e0bdd7c username:string = User;
-account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
-account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
-account.deleteAccount#418d4e0b reason:string = Bool;
-account.getAccountTTL#8fc711d = AccountDaysTTL;
-account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
-account.sendChangePhoneCode#82574ae5 phone_number:string settings:CodeSettings = auth.SentCode;
-account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
-account.updateDeviceLocked#38df3532 period:int = Bool;
-account.getAuthorizations#e320c158 = account.Authorizations;
-account.resetAuthorization#df77f3bc hash:long = Bool;
-account.getPassword#548a30f5 = account.Password;
-account.getPasswordSettings#9cd4eaf9 password:InputCheckPasswordSRP = account.PasswordSettings;
-account.updatePasswordSettings#a59b102f password:InputCheckPasswordSRP new_settings:account.PasswordInputSettings = Bool;
-account.sendConfirmPhoneCode#1b3faa88 hash:string settings:CodeSettings = auth.SentCode;
-account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
-account.getTmpPassword#449e0b51 password:InputCheckPasswordSRP period:int = account.TmpPassword;
-account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
-account.resetWebAuthorization#2d01b9ef hash:long = Bool;
-account.resetWebAuthorizations#682d2594 = Bool;
-account.getAllSecureValues#b288bc7d = Vector<SecureValue>;
-account.getSecureValue#73665bc2 types:Vector<SecureValueType> = Vector<SecureValue>;
-account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue;
-account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
-account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm;
-account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
-account.sendVerifyPhoneCode#a5a356f9 phone_number:string settings:CodeSettings = auth.SentCode;
-account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
-account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
-account.verifyEmail#ecba39db email:string code:string = Bool;
-account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
-account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
-account.confirmPasswordEmail#8fdf1920 code:string = Bool;
-account.resendPasswordEmail#7a7f2a15 = Bool;
-account.cancelPasswordEmail#c1cbd5b6 = Bool;
-account.getContactSignUpNotification#9f07c728 = Bool;
-account.setContactSignUpNotification#cff43f61 silent:Bool = Bool;
-account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true peer:flags.0?InputNotifyPeer = Updates;
-account.getWallPaper#fc8ddbea wallpaper:InputWallPaper = WallPaper;
-account.uploadWallPaper#dd853661 file:InputFile mime_type:string settings:WallPaperSettings = WallPaper;
-account.saveWallPaper#6c5a5b37 wallpaper:InputWallPaper unsave:Bool settings:WallPaperSettings = Bool;
-account.installWallPaper#feed5769 wallpaper:InputWallPaper settings:WallPaperSettings = Bool;
-account.resetWallPapers#bb3b9804 = Bool;
-account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings;
-account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool;
-account.uploadTheme#1c3db333 flags:# file:InputFile thumb:flags.0?InputFile file_name:string mime_type:string = Document;
-account.createTheme#2b7ffd7f slug:string title:string document:InputDocument = Theme;
-account.updateTheme#3b8ea202 flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument = Theme;
-account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool;
-account.installTheme#7ae43737 flags:# dark:flags.0?true format:flags.1?string theme:flags.1?InputTheme = Bool;
-account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme;
-account.getThemes#285946f8 format:string hash:int = account.Themes;
-
-users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
-users.getFullUser#ca30a5b1 id:InputUser = UserFull;
-users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
-
-contacts.getContactIDs#2caa4a42 hash:int = Vector<int>;
-contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
-contacts.getContacts#c023849f hash:int = contacts.Contacts;
-contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts;
-contacts.deleteContacts#96a0e00 id:Vector<InputUser> = Updates;
-contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool;
-contacts.block#332b49fc id:InputUser = Bool;
-contacts.unblock#e54100bd id:InputUser = Bool;
-contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
-contacts.search#11f812d8 q:string limit:int = contacts.Found;
-contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
-contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
-contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
-contacts.resetSaved#879537f1 = Bool;
-contacts.getSaved#82f1e39f = Vector<SavedContact>;
-contacts.toggleTopPeers#8514bdda enabled:Bool = Bool;
-contacts.addContact#e8f463d0 flags:# add_phone_privacy_exception:flags.0?true id:InputUser first_name:string last_name:string phone:string = Updates;
-contacts.acceptContact#f831a20f id:InputUser = Updates;
-contacts.getLocated#a356056 geo_point:InputGeoPoint = Updates;
-
-messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
-messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
-messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
-messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
-messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
-messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
-messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
-messages.sendMessage#520c3870 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
-messages.sendMedia#3491eba9 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
-messages.forwardMessages#d9fee60e flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true grouped:flags.9?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int = Updates;
-messages.reportSpam#cf1592db peer:InputPeer = Bool;
-messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
-messages.report#bd82b658 peer:InputPeer id:Vector<int> reason:ReportReason = Bool;
-messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
-messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
-messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
-messages.editChatPhoto#ca4c79d8 chat_id:int photo:InputChatPhoto = Updates;
-messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
-messages.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = Updates;
-messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
-messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
-messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
-messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
-messages.discardEncryption#edd923c5 chat_id:int = Bool;
-messages.setEncryptedTyping#791451ed peer:InputEncryptedChat typing:Bool = Bool;
-messages.readEncryptedHistory#7f4b690a peer:InputEncryptedChat max_date:int = Bool;
-messages.sendEncrypted#a9776773 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
-messages.sendEncryptedFile#9a901b66 peer:InputEncryptedChat random_id:long data:bytes file:InputEncryptedFile = messages.SentEncryptedMessage;
-messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
-messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
-messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
-messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
-messages.getStickers#43d4f2c emoticon:string hash:int = messages.Stickers;
-messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
-messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
-messages.exportChatInvite#df7534c peer:InputPeer = ExportedChatInvite;
-messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
-messages.importChatInvite#6c50051c hash:string = Updates;
-messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
-messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = messages.StickerSetInstallResult;
-messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
-messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates;
-messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector<int> increment:Bool = Vector<int>;
-messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
-messages.migrateChat#15a3b8e3 chat_id:int = Updates;
-messages.searchGlobal#bf7225a4 flags:# folder_id:flags.0?int q:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
-messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool;
-messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document;
-messages.searchGifs#bf9a776b q:string offset:int = messages.FoundGifs;
-messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
-messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
-messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
-messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
-messages.sendInlineBotResult#220815b0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string schedule_date:flags.10?int = Updates;
-messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
-messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.15?int = Updates;
-messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
-messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
-messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
-messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
-messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
-messages.getAllDrafts#6a3f8d65 = Updates;
-messages.getFeaturedStickers#2dacca4f hash:int = messages.FeaturedStickers;
-messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
-messages.getRecentStickers#5ea192c9 flags:# attached:flags.0?true hash:int = messages.RecentStickers;
-messages.saveRecentSticker#392718f8 flags:# attached:flags.0?true id:InputDocument unsave:Bool = Bool;
-messages.clearRecentStickers#8999602d flags:# attached:flags.0?true = Bool;
-messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true offset_id:long limit:int = messages.ArchivedStickers;
-messages.getMaskStickers#65b8c79f hash:int = messages.AllStickers;
-messages.getAttachedStickers#cc5b67cc media:InputStickeredMedia = Vector<StickerSetCovered>;
-messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true force:flags.1?true peer:InputPeer id:int user_id:InputUser score:int = Updates;
-messages.setInlineGameScore#15ad9f64 flags:# edit_message:flags.0?true force:flags.1?true id:InputBotInlineMessageID user_id:InputUser score:int = Bool;
-messages.getGameHighScores#e822649d peer:InputPeer id:int user_id:InputUser = messages.HighScores;
-messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:InputUser = messages.HighScores;
-messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = messages.Chats;
-messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
-messages.getWebPage#32ca8f91 url:string hash:int = WebPage;
-messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
-messages.reorderPinnedDialogs#3b1adf37 flags:# force:flags.0?true folder_id:int order:Vector<InputDialogPeer> = Bool;
-messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs;
-messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;
-messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;
-messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia;
-messages.sendScreenshotNotification#c97df020 peer:InputPeer reply_to_msg_id:int random_id:long = Updates;
-messages.getFavedStickers#21ce0b0e hash:int = messages.FavedStickers;
-messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
-messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
-messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
-messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = messages.Messages;
-messages.sendMultiMedia#cc0110cb flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int = Updates;
-messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
-messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
-messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
-messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
-messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
-messages.clearAllDrafts#7e58ee9c = Bool;
-messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true peer:InputPeer id:int = Updates;
-messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
-messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
-messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
-messages.getStatsURL#812c2ae6 flags:# dark:flags.0?true peer:InputPeer params:string = StatsURL;
-messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
-messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
-messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference;
-messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
-messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector<string> = Vector<EmojiLanguage>;
-messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
-messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
-messages.requestUrlAuth#e33f5613 peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
-messages.acceptUrlAuth#f729ea98 flags:# write_allowed:flags.0?true peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
-messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool;
-messages.getScheduledHistory#e2c2685b peer:InputPeer hash:int = messages.Messages;
-messages.getScheduledMessages#bdbb0464 peer:InputPeer id:Vector<int> = messages.Messages;
-messages.sendScheduledMessages#bd38850a peer:InputPeer id:Vector<int> = Updates;
-messages.deleteScheduledMessages#59ae2b16 peer:InputPeer id:Vector<int> = Updates;
-
-updates.getState#edd4882a = updates.State;
-updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
-updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
-
-photos.updateProfilePhoto#f0bb5152 id:InputPhoto = UserProfilePhoto;
-photos.uploadProfilePhoto#4f32c098 file:InputFile = photos.Photo;
-photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
-photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
-
-upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
-upload.getFile#b15a9afc flags:# precise:flags.0?true location:InputFileLocation offset:int limit:int = upload.File;
-upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
-upload.getWebFile#24e6818d location:InputWebFileLocation offset:int limit:int = upload.WebFile;
-upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
-upload.reuploadCdnFile#9b2754a8 file_token:bytes request_token:bytes = Vector<FileHash>;
-upload.getCdnFileHashes#4da54231 file_token:bytes offset:int = Vector<FileHash>;
-upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<FileHash>;
-
-help.getConfig#c4f9186b = Config;
-help.getNearestDc#1fb33026 = NearestDc;
-help.getAppUpdate#522d5a7d source:string = help.AppUpdate;
-help.getInviteText#4d392343 = help.InviteText;
-help.getSupport#9cdf08cd = help.Support;
-help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
-help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
-help.getCdnConfig#52029342 = CdnConfig;
-help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls;
-help.getProxyData#3d7758e1 = help.ProxyData;
-help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
-help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
-help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
-help.getAppConfig#98914110 = JSONValue;
-help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
-help.getPassportConfig#c661ad08 hash:int = help.PassportConfig;
-help.getSupportName#d360e72c = help.SupportName;
-help.getUserInfo#38a08d3 user_id:InputUser = help.UserInfo;
-help.editUserInfo#66b91b70 user_id:InputUser message:string entities:Vector<MessageEntity> = help.UserInfo;
-
-channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
-channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
-channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
-channels.reportSpam#fe087810 channel:InputChannel user_id:InputUser id:Vector<int> = Bool;
-channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
-channels.getParticipants#123e05e9 channel:InputChannel filter:ChannelParticipantsFilter offset:int limit:int hash:int = channels.ChannelParticipants;
-channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channels.ChannelParticipant;
-channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
-channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
-channels.createChannel#3d5fb10f flags:# broadcast:flags.0?true megagroup:flags.1?true title:string about:string geo_point:flags.2?InputGeoPoint address:flags.2?string = Updates;
-channels.editAdmin#d33c8902 channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights rank:string = Updates;
-channels.editTitle#566decd0 channel:InputChannel title:string = Updates;
-channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates;
-channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
-channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
-channels.joinChannel#24b524c5 channel:InputChannel = Updates;
-channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
-channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
-channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
-channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
-channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
-channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats;
-channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates;
-channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
-channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
-channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
-channels.deleteHistory#af369d42 channel:InputChannel max_id:int = Bool;
-channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
-channels.getLeftChannels#8341ecc0 offset:int = messages.Chats;
-channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
-channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool;
-channels.editCreator#8f38cd1f channel:InputChannel user_id:InputUser password:InputCheckPasswordSRP = Updates;
-channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint address:string = Bool;
-channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates;
-
-bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
-bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
-
-payments.getPaymentForm#99f09745 msg_id:int = payments.PaymentForm;
-payments.getPaymentReceipt#a092a980 msg_id:int = payments.PaymentReceipt;
-payments.validateRequestedInfo#770a8e74 flags:# save:flags.0?true msg_id:int info:PaymentRequestedInfo = payments.ValidatedRequestedInfo;
-payments.sendPaymentForm#2b8879b3 flags:# msg_id:int requested_info_id:flags.0?string shipping_option_id:flags.1?string credentials:InputPaymentCredentials = payments.PaymentResult;
-payments.getSavedInfo#227d824b = payments.SavedInfo;
-payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool;
-
-stickers.createStickerSet#9bd86e6a flags:# masks:flags.0?true user_id:InputUser title:string short_name:string stickers:Vector<InputStickerSetItem> = messages.StickerSet;
-stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
-stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = messages.StickerSet;
-stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet;
-
-phone.getCallConfig#55451fa9 = DataJSON;
-phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
-phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
-phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
-phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
-phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
-phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
-phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
-
-langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
-langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
-langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:int = LangPackDifference;
-langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>;
-langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage;
-
-folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;
-folders.deleteFolder#1c295881 folder_id:int = Updates;
-
-// LAYER 105

+ 0 - 290
gramjs_generator/data/errors.csv

@@ -1,290 +0,0 @@
-name,codes,description
-ABOUT_TOO_LONG,400,The provided bio is too long
-ACCESS_TOKEN_EXPIRED,400,Bot token expired
-ACCESS_TOKEN_INVALID,400,The provided token is not valid
-ACTIVE_USER_REQUIRED,401,The method is only available to already activated users
-ADMINS_TOO_MUCH,400,Too many admins
-ADMIN_RANK_EMOJI_NOT_ALLOWED,400,Emoji are not allowed in admin titles or ranks
-ADMIN_RANK_INVALID,400,The given admin title or rank was invalid (possibly larger than 16 characters)
-API_ID_INVALID,400,The api_id/api_hash combination is invalid
-API_ID_PUBLISHED_FLOOD,400,"This API id was published somewhere, you can't use it now"
-ARTICLE_TITLE_EMPTY,400,The title of the article is empty
-AUTH_BYTES_INVALID,400,The provided authorization is invalid
-AUTH_KEY_DUPLICATED,406,"The authorization key (session file) was used under two different IP addresses simultaneously, and can no longer be used. Use the same session exclusively, or use different sessions"
-AUTH_KEY_INVALID,401,The key is invalid
-AUTH_KEY_PERM_EMPTY,401,"The method is unavailable for temporary authorization key, not bound to permanent"
-AUTH_KEY_UNREGISTERED,401,The key is not registered in the system
-AUTH_RESTART,500,Restart the authorization process
-BANNED_RIGHTS_INVALID,400,"You cannot use that set of permissions in this request, i.e. restricting view_messages as a default"
-BOTS_TOO_MUCH,400,There are too many bots in this chat/channel
-BOT_CHANNELS_NA,400,Bots can't edit admin privileges
-BOT_GROUPS_BLOCKED,400,This bot can't be added to groups
-BOT_INLINE_DISABLED,400,This bot can't be used in inline mode
-BOT_INVALID,400,This is not a valid bot
-BOT_METHOD_INVALID,400,The API access for bot users is restricted. The method you tried to invoke cannot be executed as a bot
-BOT_MISSING,400,This method can only be run by a bot
-BOT_PAYMENTS_DISABLED,400,This method can only be run by a bot
-BOT_POLLS_DISABLED,400,You cannot create polls under a bot account
-BROADCAST_ID_INVALID,400,The channel is invalid
-BUTTON_DATA_INVALID,400,The provided button data is invalid
-BUTTON_TYPE_INVALID,400,The type of one of the buttons you provided is invalid
-BUTTON_URL_INVALID,400,Button URL invalid
-CALL_ALREADY_ACCEPTED,400,The call was already accepted
-CALL_ALREADY_DECLINED,400,The call was already declined
-CALL_OCCUPY_FAILED,500,The call failed because the user is already making another call
-CALL_PEER_INVALID,400,The provided call peer object is invalid
-CALL_PROTOCOL_FLAGS_INVALID,400,Call protocol flags invalid
-CDN_METHOD_INVALID,400,This method cannot be invoked on a CDN server. Refer to https://core.telegram.org/cdn#schema for available methods
-CHANNELS_ADMIN_PUBLIC_TOO_MUCH,400,"You're admin of too many public channels, make some channels private to change the username of this channel"
-CHANNELS_TOO_MUCH,400,You have joined too many channels/supergroups
-CHANNEL_INVALID,400,"Invalid channel object. Make sure to pass the right types, for instance making sure that the request is designed for channels or otherwise look for a different one more suited"
-CHANNEL_PRIVATE,400,The channel specified is private and you lack permission to access it. Another reason may be that you were banned from it
-CHANNEL_PUBLIC_GROUP_NA,403,channel/supergroup not available
-CHAT_ABOUT_NOT_MODIFIED,400,About text has not changed
-CHAT_ABOUT_TOO_LONG,400,Chat about too long
-CHAT_ADMIN_INVITE_REQUIRED,403,You do not have the rights to do this
-CHAT_ADMIN_REQUIRED,400 403,"Chat admin privileges are required to do that in the specified chat (for example, to send a message in a channel which is not yours), or invalid permissions used for the channel or group"
-CHAT_FORBIDDEN,,You cannot write in this chat
-CHAT_ID_EMPTY,400,The provided chat ID is empty
-CHAT_ID_INVALID,400,"Invalid object ID for a chat. Make sure to pass the right types, for instance making sure that the request is designed for chats (not channels/megagroups) or otherwise look for a different one more suited\nAn example working with a megagroup and AddChatUserRequest, it will fail because megagroups are channels. Use InviteToChannelRequest instead"
-CHAT_INVALID,400,The chat is invalid for this request
-CHAT_LINK_EXISTS,400,The chat is linked to a channel and cannot be used in that request
-CHAT_NOT_MODIFIED,400,"The chat or channel wasn't modified (title, invites, username, admins, etc. are the same)"
-CHAT_RESTRICTED,400,The chat is restricted and cannot be used in that request
-CHAT_SEND_GIFS_FORBIDDEN,403,You can't send gifs in this chat
-CHAT_SEND_INLINE_FORBIDDEN,400,You cannot send inline results in this chat
-CHAT_SEND_MEDIA_FORBIDDEN,403,You can't send media in this chat
-CHAT_SEND_STICKERS_FORBIDDEN,403,You can't send stickers in this chat
-CHAT_TITLE_EMPTY,400,No chat title provided
-CHAT_WRITE_FORBIDDEN,403,You can't write in this chat
-CODE_EMPTY,400,The provided code is empty
-CODE_HASH_INVALID,400,Code hash invalid
-CODE_INVALID,400,Code invalid (i.e. from email)
-CONNECTION_API_ID_INVALID,400,The provided API id is invalid
-CONNECTION_DEVICE_MODEL_EMPTY,400,Device model empty
-CONNECTION_LANG_PACK_INVALID,400,"The specified language pack is not valid. This is meant to be used by official applications only so far, leave it empty"
-CONNECTION_LAYER_INVALID,400,The very first request must always be InvokeWithLayerRequest
-CONNECTION_NOT_INITED,400,Connection not initialized
-CONNECTION_SYSTEM_EMPTY,400,Connection system empty
-CONTACT_ID_INVALID,400,The provided contact ID is invalid
-DATA_INVALID,400,Encrypted data invalid
-DATA_JSON_INVALID,400,The provided JSON data is invalid
-DATE_EMPTY,400,Date empty
-DC_ID_INVALID,400,This occurs when an authorization is tried to be exported for the same data center one is currently connected to
-DH_G_A_INVALID,400,g_a invalid
-EMAIL_HASH_EXPIRED,400,The email hash expired and cannot be used to verify it
-EMAIL_INVALID,400,The given email is invalid
-EMAIL_UNCONFIRMED_X,400,"Email unconfirmed, the length of the code must be {code_length}"
-EMOTICON_EMPTY,400,The emoticon field cannot be empty
-ENCRYPTED_MESSAGE_INVALID,400,Encrypted message invalid
-ENCRYPTION_ALREADY_ACCEPTED,400,Secret chat already accepted
-ENCRYPTION_ALREADY_DECLINED,400,The secret chat was already declined
-ENCRYPTION_DECLINED,400,The secret chat was declined
-ENCRYPTION_ID_INVALID,400,The provided secret chat ID is invalid
-ENCRYPTION_OCCUPY_FAILED,500,TDLib developer claimed it is not an error while accepting secret chats and 500 is used instead of 420
-ENTITIES_TOO_LONG,400,It is no longer possible to send such long data inside entity tags (for example inline text URLs)
-ENTITY_MENTION_USER_INVALID,400,You can't use this entity
-ERROR_TEXT_EMPTY,400,The provided error message is empty
-EXPORT_CARD_INVALID,400,Provided card is invalid
-EXTERNAL_URL_INVALID,400,External URL invalid
-FIELD_NAME_EMPTY,,The field with the name FIELD_NAME is missing
-FIELD_NAME_INVALID,,The field with the name FIELD_NAME is invalid
-FILE_ID_INVALID,400,The provided file id is invalid
-FILE_MIGRATE_X,303,The file to be accessed is currently stored in DC {new_dc}
-FILE_PARTS_INVALID,400,The number of file parts is invalid
-FILE_PART_0_MISSING,,File part 0 missing
-FILE_PART_EMPTY,400,The provided file part is empty
-FILE_PART_INVALID,400,The file part number is invalid
-FILE_PART_LENGTH_INVALID,400,The length of a file part is invalid
-FILE_PART_SIZE_INVALID,400,The provided file part size is invalid
-FILE_PART_X_MISSING,400,Part {which} of the file is missing from storage
-FILEREF_UPGRADE_NEEDED,406,The file reference needs to be refreshed before being used again
-FIRSTNAME_INVALID,400,The first name is invalid
-FLOOD_TEST_PHONE_WAIT_X,420,A wait of {seconds} seconds is required in the test servers
-FLOOD_WAIT_X,420,A wait of {seconds} seconds is required
-FOLDER_ID_EMPTY,400,The folder you tried to delete was already empty
-FOLDER_ID_INVALID,400,The folder you tried to use was not valid
-FRESH_RESET_AUTHORISATION_FORBIDDEN,406,The current session is too new and cannot be used to reset other authorisations yet
-GIF_ID_INVALID,400,The provided GIF ID is invalid
-GROUPED_MEDIA_INVALID,400,Invalid grouped media
-HASH_INVALID,400,The provided hash is invalid
-HISTORY_GET_FAILED,500,Fetching of history failed
-IMAGE_PROCESS_FAILED,400,Failure while processing image
-INLINE_RESULT_EXPIRED,400,The inline query expired
-INPUT_CONSTRUCTOR_INVALID,400,The provided constructor is invalid
-INPUT_FETCH_ERROR,,An error occurred while deserializing TL parameters
-INPUT_FETCH_FAIL,400,Failed deserializing TL payload
-INPUT_LAYER_INVALID,400,The provided layer is invalid
-INPUT_METHOD_INVALID,,The invoked method does not exist anymore or has never existed
-INPUT_REQUEST_TOO_LONG,400,The input request was too long. This may be a bug in the library as it can occur when serializing more bytes than it should (like appending the vector constructor code at the end of a message)
-INPUT_USER_DEACTIVATED,400,The specified user was deleted
-INTERDC_X_CALL_ERROR,,An error occurred while communicating with DC {dc}
-INTERDC_X_CALL_RICH_ERROR,,A rich error occurred while communicating with DC {dc}
-INVITE_HASH_EMPTY,400,The invite hash is empty
-INVITE_HASH_EXPIRED,400,The chat the user tried to join has expired and is not valid anymore
-INVITE_HASH_INVALID,400,The invite hash is invalid
-LANG_PACK_INVALID,400,The provided language pack is invalid
-LASTNAME_INVALID,,The last name is invalid
-LIMIT_INVALID,400,An invalid limit was provided. See https://core.telegram.org/api/files#downloading-files
-LINK_NOT_MODIFIED,400,The channel is already linked to this group
-LOCATION_INVALID,400,The location given for a file was invalid. See https://core.telegram.org/api/files#downloading-files
-MAX_ID_INVALID,400,The provided max ID is invalid
-MAX_QTS_INVALID,400,The provided QTS were invalid
-MD5_CHECKSUM_INVALID,,The MD5 check-sums do not match
-MEDIA_CAPTION_TOO_LONG,400,The caption is too long
-MEDIA_EMPTY,400,The provided media object is invalid
-MEDIA_INVALID,400,Media invalid
-MEDIA_NEW_INVALID,400,The new media to edit the message with is invalid (such as stickers or voice notes)
-MEDIA_PREV_INVALID,400,The old media cannot be edited with anything else (such as stickers or voice notes)
-MEGAGROUP_ID_INVALID,400,The group is invalid
-MEGAGROUP_PREHISTORY_HIDDEN,400,You can't set this discussion group because it's history is hidden
-MEMBER_NO_LOCATION,500,An internal failure occurred while fetching user info (couldn't find location)
-MEMBER_OCCUPY_PRIMARY_LOC_FAILED,500,Occupation of primary member location failed
-MESSAGE_AUTHOR_REQUIRED,403,Message author required
-MESSAGE_DELETE_FORBIDDEN,403,"You can't delete one of the messages you tried to delete, most likely because it is a service message."
-MESSAGE_EDIT_TIME_EXPIRED,400,"You can't edit this message anymore, too much time has passed since its creation."
-MESSAGE_EMPTY,400,Empty or invalid UTF-8 message was sent
-MESSAGE_IDS_EMPTY,400,No message ids were provided
-MESSAGE_ID_INVALID,400,"The specified message ID is invalid or you can't do that operation on such message"
-MESSAGE_NOT_MODIFIED,400,Content of the message was not modified
-MESSAGE_TOO_LONG,400,Message was too long. Current maximum length is 4096 UTF-8 characters
-MSG_WAIT_FAILED,400,A waiting call returned an error
-MT_SEND_QUEUE_TOO_LONG,500,
-NEED_CHAT_INVALID,500,The provided chat is invalid
-NEED_MEMBER_INVALID,500,The provided member is invalid or does not exist (for example a thumb size)
-NETWORK_MIGRATE_X,303,The source IP address is associated with DC {new_dc}
-NEW_SALT_INVALID,400,The new salt is invalid
-NEW_SETTINGS_INVALID,400,The new settings are invalid
-OFFSET_INVALID,400,"The given offset was invalid, it must be divisible by 1KB. See https://core.telegram.org/api/files#downloading-files"
-OFFSET_PEER_ID_INVALID,400,The provided offset peer is invalid
-OPTIONS_TOO_MUCH,400,You defined too many options for the poll
-PACK_SHORT_NAME_INVALID,400,"Invalid sticker pack name. It must begin with a letter, can't contain consecutive underscores and must end in ""_by_<bot username>""."
-PACK_SHORT_NAME_OCCUPIED,400,A stickerpack with this name already exists
-PARTICIPANTS_TOO_FEW,400,Not enough participants
-PARTICIPANT_CALL_FAILED,500,Failure while making call
-PARTICIPANT_VERSION_OUTDATED,400,The other participant does not use an up to date telegram client with support for calls
-PASSWORD_EMPTY,400,The provided password is empty
-PASSWORD_HASH_INVALID,400,The password (and thus its hash value) you entered is invalid
-PASSWORD_REQUIRED,400,The account must have 2-factor authentication enabled (a password) before this method can be used
-PAYMENT_PROVIDER_INVALID,400,The payment provider was not recognised or its token was invalid
-PEER_FLOOD,,Too many requests
-PEER_ID_INVALID,400,An invalid Peer was used. Make sure to pass the right peer type
-PEER_ID_NOT_SUPPORTED,400,The provided peer ID is not supported
-PERSISTENT_TIMESTAMP_EMPTY,400,Persistent timestamp empty
-PERSISTENT_TIMESTAMP_INVALID,400,Persistent timestamp invalid
-PERSISTENT_TIMESTAMP_OUTDATED,500,Persistent timestamp outdated
-PHONE_CODE_EMPTY,400,The phone code is missing
-PHONE_CODE_EXPIRED,400,The confirmation code has expired
-PHONE_CODE_HASH_EMPTY,,The phone code hash is missing
-PHONE_CODE_INVALID,400,The phone code entered was invalid
-PHONE_MIGRATE_X,303,The phone number a user is trying to use for authorization is associated with DC {new_dc}
-PHONE_NUMBER_APP_SIGNUP_FORBIDDEN,400,
-PHONE_NUMBER_BANNED,400,The used phone number has been banned from Telegram and cannot be used anymore. Maybe check https://www.telegram.org/faq_spam
-PHONE_NUMBER_FLOOD,400,You asked for the code too many times.
-PHONE_NUMBER_INVALID,400 406,The phone number is invalid
-PHONE_NUMBER_OCCUPIED,400,The phone number is already in use
-PHONE_NUMBER_UNOCCUPIED,400,The phone number is not yet being used
-PHONE_PASSWORD_FLOOD,406,You have tried logging in too many times
-PHONE_PASSWORD_PROTECTED,400,This phone is password protected
-PHOTO_CONTENT_URL_EMPTY,400,The content from the URL used as a photo appears to be empty or has caused another HTTP error
-PHOTO_CROP_SIZE_SMALL,400,Photo is too small
-PHOTO_EXT_INVALID,400,The extension of the photo is invalid
-PHOTO_INVALID,400,Photo invalid
-PHOTO_INVALID_DIMENSIONS,400,The photo dimensions are invalid (hint: `pip install pillow` for `send_file` to resize images)
-PHOTO_SAVE_FILE_INVALID,400,The photo you tried to send cannot be saved by Telegram. A reason may be that it exceeds 10MB. Try resizing it locally
-PHOTO_THUMB_URL_EMPTY,400,The URL used as a thumbnail appears to be empty or has caused another HTTP error
-PIN_RESTRICTED,400,You can't pin messages in private chats with other people
-POLL_OPTION_DUPLICATE,400,A duplicate option was sent in the same poll
-POLL_UNSUPPORTED,400,This layer does not support polls in the issued method
-PRIVACY_KEY_INVALID,400,The privacy key is invalid
-PTS_CHANGE_EMPTY,500,No PTS change
-QUERY_ID_EMPTY,400,The query ID is empty
-QUERY_ID_INVALID,400,The query ID is invalid
-QUERY_TOO_SHORT,400,The query string is too short
-RANDOM_ID_DUPLICATE,500,You provided a random ID that was already used
-RANDOM_ID_INVALID,400,A provided random ID is invalid
-RANDOM_LENGTH_INVALID,400,Random length invalid
-RANGES_INVALID,400,Invalid range provided
-REACTION_EMPTY,400,No reaction provided
-REACTION_INVALID,400,Invalid reaction provided (only emoji are allowed)
-REG_ID_GENERATE_FAILED,500,Failure while generating registration ID
-REPLY_MARKUP_INVALID,400,The provided reply markup is invalid
-REPLY_MARKUP_TOO_LONG,400,The data embedded in the reply markup buttons was too much
-RESULT_ID_DUPLICATE,400,Duplicated IDs on the sent results. Make sure to use unique IDs.
-RESULT_TYPE_INVALID,400,Result type invalid
-RESULTS_TOO_MUCH,400,You sent too many results. See https://core.telegram.org/bots/api#answerinlinequery for the current limit.
-RIGHT_FORBIDDEN,403,Either your admin rights do not allow you to do this or you passed the wrong rights combination (some rights only apply to channels and vice versa)
-RPC_CALL_FAIL,,"Telegram is having internal issues, please try again later."
-RPC_MCGET_FAIL,,"Telegram is having internal issues, please try again later."
-RSA_DECRYPT_FAILED,400,Internal RSA decryption failed
-SCHEDULE_DATE_TOO_LATE,400,The date you tried to schedule is too far in the future (last known limit of 1 year and a few hours)
-SCHEDULE_TOO_MUCH,400,You cannot schedule more messages in this chat (last known limit of 100 per chat)
-SEARCH_QUERY_EMPTY,400,The search query is empty
-SECONDS_INVALID,400,"Slow mode only supports certain values (e.g. 0, 10s, 30s, 1m, 5m, 15m and 1h)"
-SEND_MESSAGE_MEDIA_INVALID,400,The message media was invalid or not specified
-SEND_MESSAGE_TYPE_INVALID,400,The message type is invalid
-SESSION_EXPIRED,401,The authorization has expired
-SESSION_PASSWORD_NEEDED,401,Two-steps verification is enabled and a password is required
-SESSION_REVOKED,401,"The authorization has been invalidated, because of the user terminating all sessions"
-SHA256_HASH_INVALID,400,The provided SHA256 hash is invalid
-SHORTNAME_OCCUPY_FAILED,400,An error occurred when trying to register the short-name used for the sticker pack. Try a different name
-SLOWMODE_WAIT_X,420,A wait of {seconds} seconds is required before sending another message in this chat
-START_PARAM_EMPTY,400,The start parameter is empty
-START_PARAM_INVALID,400,Start parameter invalid
-STICKERSET_INVALID,400,The provided sticker set is invalid
-STICKERS_EMPTY,400,No sticker provided
-STICKER_EMOJI_INVALID,400,Sticker emoji invalid
-STICKER_FILE_INVALID,400,Sticker file invalid
-STICKER_ID_INVALID,400,The provided sticker ID is invalid
-STICKER_INVALID,400,The provided sticker is invalid
-STICKER_PNG_DIMENSIONS,400,Sticker png dimensions invalid
-STORAGE_CHECK_FAILED,500,Server storage check failed
-STORE_INVALID_SCALAR_TYPE,500,
-TAKEOUT_INIT_DELAY_X,420,A wait of {seconds} seconds is required before being able to initiate the takeout
-TAKEOUT_INVALID,400,The takeout session has been invalidated by another data export session
-TAKEOUT_REQUIRED,400,You must initialize a takeout request first
-TEMP_AUTH_KEY_EMPTY,400,No temporary auth key provided
-Timeout,-503,A timeout occurred while fetching data from the worker
-TMP_PASSWORD_DISABLED,400,The temporary password is disabled
-TOKEN_INVALID,400,The provided token is invalid
-TTL_DAYS_INVALID,400,The provided TTL is invalid
-TYPES_EMPTY,400,The types field is empty
-TYPE_CONSTRUCTOR_INVALID,,The type constructor is invalid
-UNKNOWN_METHOD,500,The method you tried to call cannot be called on non-CDN DCs
-UNTIL_DATE_INVALID,400,That date cannot be specified in this request (try using None)
-URL_INVALID,400,The URL used was invalid (e.g. when answering a callback with an URL that's not t.me/yourbot or your game's URL)
-USERNAME_INVALID,400,"Nobody is using this username, or the username is unacceptable. If the latter, it must match r""[a-zA-Z][\w\d]{3,30}[a-zA-Z\d]"""
-USERNAME_NOT_MODIFIED,400,The username is not different from the current username
-USERNAME_NOT_OCCUPIED,400,The username is not in use by anyone else yet
-USERNAME_OCCUPIED,400,The username is already taken
-USERS_TOO_FEW,400,"Not enough users (to create a chat, for example)"
-USERS_TOO_MUCH,400,"The maximum number of users has been exceeded (to create a chat, for example)"
-USER_ADMIN_INVALID,400,Either you're not an admin or you tried to ban an admin that you didn't promote
-USER_ALREADY_PARTICIPANT,400,The authenticated user is already a participant of the chat
-USER_BANNED_IN_CHANNEL,400,You're banned from sending messages in supergroups/channels
-USER_BLOCKED,400,User blocked
-USER_BOT,400,Bots can only be admins in channels.
-USER_BOT_INVALID,400 403,This method can only be called by a bot
-USER_BOT_REQUIRED,400,This method can only be called by a bot
-USER_CHANNELS_TOO_MUCH,403,One of the users you tried to add is already in too many channels/supergroups
-USER_CREATOR,400,"You can't leave this channel, because you're its creator"
-USER_DEACTIVATED,401,The user has been deleted/deactivated
-USER_DEACTIVATED_BAN,401,The user has been deleted/deactivated
-USER_ID_INVALID,400,"Invalid object ID for a user. Make sure to pass the right types, for instance making sure that the request is designed for users or otherwise look for a different one more suited"
-USER_INVALID,400,The given user was invalid
-USER_IS_BLOCKED,400 403,User is blocked
-USER_IS_BOT,400,Bots can't send messages to other bots
-USER_KICKED,400,This user was kicked from this supergroup/channel
-USER_MIGRATE_X,303,The user whose identity is being used to execute queries is associated with DC {new_dc}
-USER_NOT_MUTUAL_CONTACT,400 403,The provided user is not a mutual contact
-USER_NOT_PARTICIPANT,400,The target user is not a member of the specified megagroup or channel
-USER_PRIVACY_RESTRICTED,403,The user's privacy settings do not allow you to do this
-USER_RESTRICTED,403,"You're spamreported, you can't create channels or chats."
-VIDEO_CONTENT_TYPE_INVALID,400,The video content type is not supported with the given parameters (i.e. supports_streaming)
-WALLPAPER_FILE_INVALID,400,The given file cannot be used as a wallpaper
-WALLPAPER_INVALID,400,The input wallpaper was not valid
-WC_CONVERT_URL_INVALID,400,WC convert URL invalid
-WEBPAGE_CURL_FAILED,400,Failure while fetching the webpage with cURL
-WEBPAGE_MEDIA_EMPTY,400,Webpage media empty
-WORKER_BUSY_TOO_LONG_RETRY,500,Telegram workers are too busy to respond immediately
-YOU_BLOCKED_USER,400,You blocked this user

+ 0 - 27
gramjs_generator/data/friendly.csv

@@ -1,27 +0,0 @@
-ns,friendly,raw
-account.AccountMethods,takeout,invokeWithTakeout account.initTakeoutSession account.finishTakeoutSession
-auth.AuthMethods,sign_in,auth.signIn auth.importBotAuthorization
-auth.AuthMethods,sign_up,auth.signUp
-auth.AuthMethods,send_code_request,auth.sendCode auth.resendCode
-auth.AuthMethods,log_out,auth.logOut
-auth.AuthMethods,edit_2fa,account.updatePasswordSettings
-bots.BotMethods,inline_query,messages.getInlineBotResults
-chats.ChatMethods,action,messages.setTyping
-chats.ChatMethods,edit_admin,channels.editAdmin messages.editChatAdmin
-chats.ChatMethods,edit_permissions,channels.editBanned messages.editChatDefaultBannedRights
-chats.ChatMethods,iter_participants,channels.getParticipants
-chats.ChatMethods,iter_admin_log,channels.getAdminLog
-dialogs.DialogMethods,iter_dialogs,messages.getDialogs
-dialogs.DialogMethods,iter_drafts,messages.getAllDrafts
-dialogs.DialogMethods,edit_folder,folders.deleteFolder folders.editPeerFolders
-downloads.DownloadMethods,download_media,upload.getFile
-messages.MessageMethods,iter_messages,messages.searchGlobal messages.search messages.getHistory channels.getMessages messages.getMessages
-messages.MessageMethods,send_message,messages.sendMessage
-messages.MessageMethods,forward_messages,messages.forwardMessages
-messages.MessageMethods,edit_message,messages.editInlineBotMessage messages.editMessage
-messages.MessageMethods,delete_messages,channels.deleteMessages messages.deleteMessages
-messages.MessageMethods,send_read_acknowledge,messages.readMentions channels.readHistory messages.readHistory
-updates.UpdateMethods,catch_up,updates.getDifference updates.getChannelDifference
-uploads.UploadMethods,send_file,messages.sendMedia messages.sendMultiMedia messages.uploadMedia
-uploads.UploadMethods,upload_file,upload.saveFilePart upload.saveBigFilePart
-users.UserMethods,get_entity,users.getUsers messages.getChats channels.getChannels contacts.resolveUsername

+ 0 - 50
gramjs_generator/data/html/404.html

@@ -1,50 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>Oopsie! | GramJS</title>
-
-        <meta charset="utf-8" />
-        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
-        <meta name="viewport" content="width=device-width, initial-scale=1" />
-        <style type="text/css">
-            body {
-                background-color: #f0f4f8;
-                font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial,
-                    sans-serif;
-            }
-            div {
-                width: 560px;
-                margin: 5em auto;
-                padding: 50px;
-                background-color: #fff;
-                border-radius: 1em;
-            }
-            a:link,
-            a:visited {
-                color: #38488f;
-                text-decoration: none;
-            }
-            @media (max-width: 700px) {
-                body {
-                    background-color: #fff;
-                }
-                div {
-                    width: auto;
-                    margin: 0 auto;
-                    border-radius: 0;
-                    padding: 1em;
-                }
-            }
-        </style>
-    </head>
-    <body>
-        <div>
-            <h1>You seem a bit lost…</h1>
-            <p>
-                You seem to be lost! Don't worry, that's just Telegram's API
-                being itself. Shall we go back to the
-                <a href="index.html">Main Page</a>?
-            </p>
-        </div>
-    </body>
-</html>

+ 0 - 236
gramjs_generator/data/html/core.html

@@ -1,236 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-        <title>GramJS API</title>
-        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-        <link id="style" href="css/docs.dark.css" rel="stylesheet" />
-        <script>
-            (function() {
-                var style = document.getElementById('style');
-
-                // setTheme(<link />, 'light' / 'dark')
-                function setTheme(theme) {
-                    localStorage.setItem('theme', theme);
-                    return (style.href = 'css/docs.' + theme + '.css');
-                }
-
-                // setThemeOnClick(<link />, 'light' / 'dark', <a />)
-                function setThemeOnClick(theme, button) {
-                    return button.addEventListener('click', function(e) {
-                        setTheme(theme);
-                        e.preventDefault();
-                        return false;
-                    });
-                }
-
-                setTheme(localStorage.getItem('theme') || 'light');
-
-                document.addEventListener('DOMContentLoaded', function() {
-                    setThemeOnClick(
-                        'light',
-                        document.getElementById('themeLight')
-                    );
-                    setThemeOnClick(
-                        'dark',
-                        document.getElementById('themeDark')
-                    );
-                });
-            })();
-        </script>
-        <link
-            href="https://fonts.googleapis.com/css?family=Nunito|Source+Code+Pro"
-            rel="stylesheet"
-        />
-    </head>
-    <body>
-        <div id="main_div">
-            <noscript
-                >Please enable JavaScript if you would like to use
-                search.</noscript
-            >
-            <h1>GramJS API</h1>
-            <p>
-                This documentation was generated straight from the
-                <code>scheme.tl</code> provided by Telegram. However, there is
-                no official documentation per se on what the methods,
-                constructors and types mean. Nevertheless, this page aims to
-                provide easy access to all the available methods, their
-                definition and parameters.
-            </p>
-            <p id="themeSelect">
-                <a href="#" id="themeLight">light</a> /
-                <a href="#" id="themeDark">dark</a> theme.
-            </p>
-            <p>Please note that when you see this:</p>
-            <pre>
----functions---
-users.getUsers#0d91a548 id:Vector&lt;InputUser&gt; = Vector&lt;User&gt;</pre
-            >
-
-            <p>
-                This is <b>not</b> Python code. It's the "TL definition". It's
-                an easy-to-read line that gives a quick overview on the
-                parameters and its result. You don't need to worry about this.
-                See
-                <a
-                    href="https://docs.telethon.dev/en/latest/developing/understanding-the-type-language.html"
-                    >Understanding the Type Language</a
-                >
-                for more details on it.
-            </p>
-
-            <h3>Index</h3>
-            <ul>
-                <li>
-                    <a href="#methods">Methods</a>
-                    (<a href="methods/index.html">full list</a>)
-                </li>
-                <li>
-                    <a href="#types">Types</a>
-                    (<a href="types/index.html">full list</a>)
-                </li>
-                <li>
-                    <a href="#constructors">Constructors</a>
-                    (<a href="constructors/index.html">full list</a>)
-                </li>
-                <li><a href="#core">Core types</a></li>
-                <li><a href="#example">Full example</a></li>
-            </ul>
-
-            <h3 id="methods">Methods</h3>
-            <p>
-                Currently there are <b>{methodCount} methods</b> available for
-                the layer {layer}.
-                <a href="methods/index.html">See the complete method list</a>.
-                <br /><br />
-                Methods, also known as <i>requests</i>, are used to interact
-                with the Telegram API itself and are invoked through
-                <code>client(Request(...))</code>. <b>Only these</b> can be used
-                like that! You cannot invoke types or constructors, only
-                requests. After this, Telegram will return a
-                <code>result</code>, which may be, for instance, a bunch of
-                messages, some dialogs, users, etc.
-            </p>
-
-            <h3 id="types">Types</h3>
-            <p>
-                Currently there are <b>{typeCount} types</b>.
-                <a href="types/index.html">See the complete list of types</a>.
-            </p>
-
-            <p>
-                The Telegram types are the <i>abstract</i> results that you
-                receive after invoking a request. They are "abstract" because
-                they can have multiple constructors. For instance, the abstract
-                type <code>User</code> can be either <code>UserEmpty</code> or
-                <code>User</code>. You should, most of the time, make sure you
-                received the desired type by using the
-                <code>isinstance(result, Constructor)</code> Python function.
-                When a request needs a Telegram type as argument, you should
-                create an instance of it by using one of its, possibly multiple,
-                constructors.
-            </p>
-
-            <h3 id="constructors">Constructors</h3>
-            <p>
-                Currently there are <b>{constructorCount} constructors</b>.
-                <a href="constructors/index.html"
-                    >See the list of all constructors</a
-                >.
-            </p>
-
-            <p>
-                Constructors are the way you can create instances of the
-                abstract types described above, and also the instances which are
-                actually returned from the functions although they all share a
-                common abstract type.
-            </p>
-
-            <h3 id="core">Core types</h3>
-            <p>
-                Core types are types from which the rest of Telegram types build
-                upon:
-            </p>
-            <ul>
-                <li id="int">
-                    <b>int</b>: The value should be an integer type, like
-                    <span class="sh1">42</span>. It should have 32 bits or less.
-                    You can check the bit length by calling
-                    <code>a.bit_length()</code>, where <code>a</code> is an
-                    integer variable.
-                </li>
-                <li id="long">
-                    <b>long</b>: Different name for an integer type. The numbers
-                    given should have 64 bits or less.
-                </li>
-                <li id="int128">
-                    <b>int128</b>: Another integer type, should have 128 bits or
-                    less.
-                </li>
-                <li id="int256">
-                    <b>int256</b>: The largest integer type, allowing 256 bits
-                    or less.
-                </li>
-                <li id="double">
-                    <b>double</b>: The value should be a floating point value,
-                    such as <span class="sh1">123.456</span>.
-                </li>
-                <li id="vector">
-                    <b>Vector&lt;T&gt;</b>: If a type <code>T</code> is wrapped
-                    around <code>Vector&lt;T&gt;</code>, then it means that the
-                    argument should be a <i>list</i> of it. For instance, a
-                    valid value for <code>Vector&lt;int&gt;</code> would be
-                    <code>[1, 2, 3]</code>.
-                </li>
-                <li id="string">
-                    <b>string</b>: A valid UTF-8 string should be supplied. This
-                    is right how Python strings work, no further encoding is
-                    required.
-                </li>
-                <li id="bool">
-                    <b>Bool</b>: Either <code>True</code> or <code>False</code>.
-                </li>
-                <li id="true">
-                    <b>flag</b>: These arguments aren't actually sent but rather
-                    encoded as flags. Any truthy value (<code>True</code>,
-                    <code>7</code>) will enable this flag, although it's
-                    recommended to use <code>True</code> or <code>None</code> to
-                    symbolize that it's not present.
-                </li>
-                <li id="bytes">
-                    <b>bytes</b>: A sequence of bytes, like
-                    <code>b'hello'</code>, should be supplied.
-                </li>
-                <li id="date">
-                    <b>date</b>: Although this type is internally used as an
-                    <code>int</code>, you can pass a <code>datetime</code> or
-                    <code>date</code> object instead to work with date
-                    parameters.<br />
-                    Note that the library uses the date in <b>UTC+0</b>, since
-                    timezone conversion is not responsibility of the library.
-                    Furthermore, this eases converting into any other timezone
-                    without the need for a middle step.
-                </li>
-            </ul>
-
-            <h3 id="example">Full example</h3>
-            <p>
-                All methods shown here have dummy examples on how to write them,
-                so you don't get confused with their TL definition. However,
-                this may not always run. They are just there to show the right
-                syntax.
-            </p>
-
-            <p>
-                You should check out
-                <a
-                    href="https://docs.telethon.dev/en/latest/concepts/full-api.html"
-                    >how to access the full API</a
-                >
-                in ReadTheDocs.
-            </p>
-        </div>
-        <script src="js/search.js"></script>
-    </body>
-</html>

+ 0 - 185
gramjs_generator/data/html/css/docs.dark.css

@@ -1,185 +0,0 @@
-body {
-    font-family: 'Nunito', sans-serif;
-    color: #bbb;
-    background-color:#000;
-    font-size: 16px;
-}
-
-a {
-    color: #42aaed;
-    text-decoration: none;
-}
-
-pre {
-    font-family: 'Source Code Pro', monospace;
-    padding: 8px;
-    color: #567;
-    background: #080a0c;
-    border-radius: 0;
-    overflow-x: auto;
-}
-
-a:hover {
-    color: #64bbdd;
-    text-decoration: underline;
-}
-
-table {
-    width: 100%;
-    max-width: 100%;
-}
-
-table td {
-    border-top: 1px solid #111;
-    padding: 8px;
-}
-
-.horizontal {
-    margin-bottom: 16px;
-    list-style: none;
-    background: #080a0c;
-    border-radius: 4px;
-    padding: 8px 16px;
-}
-
-.horizontal li {
-    display: inline-block;
-    margin: 0 8px 0 0;
-}
-
-.horizontal img {
-    display: inline-block;
-    margin: 0 8px -2px 0;
-}
-
-h1, summary.title {
-    font-size: 24px;
-}
-
-h3 {
-    font-size: 20px;
-}
-
-#main_div {
-  padding: 20px 0;
-  max-width: 800px;
-  margin: 0 auto;
-}
-
-pre::-webkit-scrollbar {
-    visibility: visible;
-    display: block;
-    height: 12px;
-}
-
-pre::-webkit-scrollbar-track:horizontal {
-    background: #222;
-    border-radius: 0;
-    height: 12px;
-}
-
-pre::-webkit-scrollbar-thumb:horizontal {
-    background: #444;
-    border-radius: 0;
-    height: 12px;
-}
-
-:target {
-    border: 2px solid #149;
-    background: #246;
-    padding: 4px;
-}
-
-/* 'sh' stands for Syntax Highlight */
-span.sh1 {
-    color: #f93;
-}
-
-span.tooltip {
-    border-bottom: 1px dashed #ddd;
-}
-
-#searchBox {
-    width: 100%;
-    border: none;
-    height: 20px;
-    padding: 8px;
-    font-size: 16px;
-    border-radius: 2px;
-    border: 2px solid #222;
-    background: #000;
-    color: #eee;
-}
-
-#searchBox:placeholder-shown {
-    color: #bbb;
-    font-style: italic;
-}
-
-button {
-    border-radius: 2px;
-    font-size: 16px;
-    padding: 8px;
-    color: #bbb;
-    background-color: #111;
-    border: 2px solid #146;
-    transition-duration: 300ms;
-}
-
-button:hover {
-    background-color: #146;
-    color: #fff;
-}
-
-/* https://www.w3schools.com/css/css_navbar.asp */
-ul.together {
-    list-style-type: none;
-    margin: 0;
-    padding: 0;
-    overflow: hidden;
-}
-
-ul.together li {
-    float: left;
-}
-
-ul.together li a {
-    display: block;
-    border-radius: 8px;
-    background: #111;
-    padding: 4px 8px;
-    margin: 8px;
-}
-
-/* https://stackoverflow.com/a/30810322 */
-.invisible {
-    left: 0;
-    top: -99px;
-    padding: 0;
-    width: 2em;
-    height: 2em;
-    border: none;
-    outline: none;
-    position: fixed;
-    box-shadow: none;
-    color: transparent;
-    background: transparent;
-}
-
-@media (max-width: 640px) {
-    h1, summary.title {
-        font-size: 18px;
-    }
-    h3 {
-        font-size: 16px;
-    }
-
-    #dev_page_content_wrap {
-        padding-top: 12px;
-    }
-
-    #dev_page_title {
-        margin-top: 10px;
-        margin-bottom: 20px;
-    }
-}

+ 0 - 229
gramjs_generator/data/html/css/docs.h4x0r.css

@@ -1,229 +0,0 @@
-/* Begin of https://cdn.jsdelivr.net/npm/hack-font@3/build/web/hack.css
- *
- *  Hack typeface https://github.com/source-foundry/Hack
- *  License: https://github.com/source-foundry/Hack/blob/master/LICENSE.md
- */
-@font-face {
-  font-family: 'Hack';
-  src: url('fonts/hack-regular.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-regular.woff?sha=3114f1256') format('woff');
-  font-weight: 400;
-  font-style: normal;
-}
-
-@font-face {
-  font-family: 'Hack';
-  src: url('fonts/hack-bold.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-bold.woff?sha=3114f1256') format('woff');
-  font-weight: 700;
-  font-style: normal;
-}
-
-@font-face {
-  font-family: 'Hack';
-  src: url('fonts/hack-italic.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-italic.woff?sha=3114f1256') format('woff');
-  font-weight: 400;
-  font-style: italic;
-}
-
-@font-face {
-  font-family: 'Hack';
-  src: url('fonts/hack-bolditalic.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-bolditalic.woff?sha=3114f1256') format('woff');
-  font-weight: 700;
-  font-style: italic;
-}
-
-/* End of https://cdn.jsdelivr.net/npm/hack-font@3/build/web/hack.css */
-
-body {
-    font-family: 'Hack', monospace;
-    color: #0a0;
-    background-color: #000;
-    font-size: 16px;
-}
-
-::-moz-selection {
-    color: #000;
-    background: #0a0;
-}
-
-::selection {
-    color: #000;
-    background: #0a0;
-}
-
-a {
-    color: #0a0;
-}
-
-pre {
-    padding: 8px;
-    color: #0c0;
-    background: #010;
-    border-radius: 0;
-    overflow-x: auto;
-}
-
-a:hover {
-    color: #0f0;
-    text-decoration: underline;
-}
-
-table {
-    width: 100%;
-    max-width: 100%;
-}
-
-table td {
-    border-top: 1px solid #111;
-    padding: 8px;
-}
-
-.horizontal {
-    margin-bottom: 16px;
-    list-style: none;
-    background: #010;
-    border-radius: 4px;
-    padding: 8px 16px;
-}
-
-.horizontal li {
-    display: inline-block;
-    margin: 0 8px 0 0;
-}
-
-.horizontal img {
-    opacity: 0;
-    display: inline-block;
-    margin: 0 8px -2px 0;
-}
-
-h1, summary.title {
-    font-size: 24px;
-}
-
-h3 {
-    font-size: 20px;
-}
-
-#main_div {
-  padding: 20px 0;
-  max-width: 800px;
-  margin: 0 auto;
-}
-
-pre::-webkit-scrollbar {
-    visibility: visible;
-    display: block;
-    height: 12px;
-}
-
-pre::-webkit-scrollbar-track:horizontal {
-    background: #222;
-    border-radius: 0;
-    height: 12px;
-}
-
-pre::-webkit-scrollbar-thumb:horizontal {
-    background: #444;
-    border-radius: 0;
-    height: 12px;
-}
-
-:target {
-    border: 2px solid #0f0;
-    background: #010;
-    padding: 4px;
-}
-
-/* 'sh' stands for Syntax Highlight */
-span.sh1 {
-    color: #0f0;
-}
-
-span.tooltip {
-    border-bottom: 1px dashed #ddd;
-}
-
-#searchBox {
-    width: 100%;
-    border: none;
-    height: 20px;
-    padding: 8px;
-    font-size: 16px;
-    border-radius: 2px;
-    border: 2px solid #222;
-    background: #000;
-    color: #0e0;
-    font-family: 'Hack', monospace;
-}
-
-#searchBox:placeholder-shown {
-    color: #0b0;
-    font-style: italic;
-}
-
-button {
-    font-size: 16px;
-    padding: 8px;
-    color: #0f0;
-    background-color: #071007;
-    border: 2px solid #131;
-    transition-duration: 300ms;
-    font-family: 'Hack', monospace;
-}
-
-button:hover {
-    background-color: #131;
-}
-
-/* https://www.w3schools.com/css/css_navbar.asp */
-ul.together {
-    list-style-type: none;
-    margin: 0;
-    padding: 0;
-    overflow: hidden;
-}
-
-ul.together li {
-    float: left;
-}
-
-ul.together li a {
-    display: block;
-    border-radius: 8px;
-    background: #121;
-    padding: 4px 8px;
-    margin: 8px;
-}
-
-/* https://stackoverflow.com/a/30810322 */
-.invisible {
-    left: 0;
-    top: -99px;
-    padding: 0;
-    width: 2em;
-    height: 2em;
-    border: none;
-    outline: none;
-    position: fixed;
-    box-shadow: none;
-    color: transparent;
-    background: transparent;
-}
-
-@media (max-width: 640px) {
-    h1, summary.title {
-        font-size: 18px;
-    }
-    h3 {
-        font-size: 16px;
-    }
-
-    #dev_page_content_wrap {
-        padding-top: 12px;
-    }
-
-    #dev_page_title {
-        margin-top: 10px;
-        margin-bottom: 20px;
-    }
-}

+ 0 - 182
gramjs_generator/data/html/css/docs.light.css

@@ -1,182 +0,0 @@
-body {
-    font-family: 'Nunito', sans-serif;
-    color: #333;
-    background-color:#eee;
-    font-size: 16px;
-}
-
-a {
-    color: #329add;
-    text-decoration: none;
-}
-
-pre {
-    font-family: 'Source Code Pro', monospace;
-    padding: 8px;
-    color: #567;
-    background: #e0e4e8;
-    border-radius: 0;
-    overflow-x: auto;
-}
-
-a:hover {
-    color: #64bbdd;
-    text-decoration: underline;
-}
-
-table {
-    width: 100%;
-    max-width: 100%;
-}
-
-table td {
-    border-top: 1px solid #ddd;
-    padding: 8px;
-}
-
-.horizontal {
-    margin-bottom: 16px;
-    list-style: none;
-    background: #e0e4e8;
-    border-radius: 4px;
-    padding: 8px 16px;
-}
-
-.horizontal li {
-    display: inline-block;
-    margin: 0 8px 0 0;
-}
-
-.horizontal img {
-    display: inline-block;
-    margin: 0 8px -2px 0;
-}
-
-h1, summary.title {
-    font-size: 24px;
-}
-
-h3 {
-    font-size: 20px;
-}
-
-#main_div {
-  padding: 20px 0;
-  max-width: 800px;
-  margin: 0 auto;
-}
-
-pre::-webkit-scrollbar {
-    visibility: visible;
-    display: block;
-    height: 12px;
-}
-
-pre::-webkit-scrollbar-track:horizontal {
-    background: #def;
-    border-radius: 0;
-    height: 12px;
-}
-
-pre::-webkit-scrollbar-thumb:horizontal {
-    background: #bdd;
-    border-radius: 0;
-    height: 12px;
-}
-
-:target {
-    border: 2px solid #f8f800;
-    background: #f8f8f8;
-    padding: 4px;
-}
-
-/* 'sh' stands for Syntax Highlight */
-span.sh1 {
-    color: #f70;
-}
-
-span.tooltip {
-    border-bottom: 1px dashed #444;
-}
-
-#searchBox {
-    width: 100%;
-    border: none;
-    height: 20px;
-    padding: 8px;
-    font-size: 16px;
-    border-radius: 2px;
-    border: 2px solid #ddd;
-}
-
-#searchBox:placeholder-shown {
-    font-style: italic;
-}
-
-button {
-    border-radius: 2px;
-    font-size: 16px;
-    padding: 8px;
-    color: #000;
-    background-color: #f7f7f7;
-    border: 2px solid #329add;
-    transition-duration: 300ms;
-}
-
-button:hover {
-    background-color: #329add;
-    color: #f7f7f7;
-}
-
-/* https://www.w3schools.com/css/css_navbar.asp */
-ul.together {
-    list-style-type: none;
-    margin: 0;
-    padding: 0;
-    overflow: hidden;
-}
-
-ul.together li {
-    float: left;
-}
-
-ul.together li a {
-    display: block;
-    border-radius: 8px;
-    background: #e0e4e8;
-    padding: 4px 8px;
-    margin: 8px;
-}
-
-/* https://stackoverflow.com/a/30810322 */
-.invisible {
-    left: 0;
-    top: -99px;
-    padding: 0;
-    width: 2em;
-    height: 2em;
-    border: none;
-    outline: none;
-    position: fixed;
-    box-shadow: none;
-    color: transparent;
-    background: transparent;
-}
-
-@media (max-width: 640px) {
-    h1, summary.title {
-        font-size: 18px;
-    }
-    h3 {
-        font-size: 16px;
-    }
-
-    #dev_page_content_wrap {
-        padding-top: 12px;
-    }
-
-    #dev_page_title {
-        margin-top: 10px;
-        margin-bottom: 20px;
-    }
-}

+ 0 - 35
gramjs_generator/data/html/img/arrow.svg

@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   version="1.1"
-   id="svg2"
-   viewBox="0 0 9 15"
-   height="15"
-   width="9">
-  <defs
-     id="defs4" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     transform="translate(0,-1037.3622)"
-     id="layer1">
-    <path
-       id="path4163"
-       d="m 0.1049,1039.6602 5.34527,5.0641 -5.43588,5.4358 1.81196,1.812 7.15946,-7.1594 -7.0291,-7.0604 z"
-       style="fill:#42aaed;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-  </g>
-</svg>

+ 0 - 244
gramjs_generator/data/html/js/search.js

@@ -1,244 +0,0 @@
-root = document.getElementById("main_div");
-root.innerHTML = `
-<!-- You can append '?q=query' to the URL to default to a search -->
-<input id="searchBox" type="text" onkeyup="updateSearch(event)"
-       placeholder="Search for requests and types…" />
-
-<div id="searchDiv">
-    <div id="exactMatch" style="display:none;">
-        <b>Exact match:</b>
-        <ul id="exactList" class="together">
-        </ul>
-    </div>
-
-    <details id="methods" open><summary class="title">Methods (<span id="methodsCount">0</span>)</summary>
-        <ul id="methodsList" class="together">
-        </ul>
-    </details>
-
-    <details id="types" open><summary class="title">Types (<span id="typesCount">0</span>)</summary>
-        <ul id="typesList" class="together">
-        </ul>
-    </details>
-
-    <details id="constructors"><summary class="title">Constructors (<span id="constructorsCount">0</span>)</summary>
-        <ul id="constructorsList" class="together">
-        </ul>
-    </details>
-</div>
-<div id="contentDiv">
-` + root.innerHTML + "</div>";
-
-// HTML modified, now load documents
-contentDiv = document.getElementById("contentDiv");
-searchDiv = document.getElementById("searchDiv");
-searchBox = document.getElementById("searchBox");
-
-// Search lists
-methodsDetails = document.getElementById("methods");
-methodsList = document.getElementById("methodsList");
-methodsCount = document.getElementById("methodsCount");
-
-typesDetails = document.getElementById("types");
-typesList = document.getElementById("typesList");
-typesCount = document.getElementById("typesCount");
-
-constructorsDetails = document.getElementById("constructors");
-constructorsList = document.getElementById("constructorsList");
-constructorsCount = document.getElementById("constructorsCount");
-
-// Exact match
-exactMatch = document.getElementById("exactMatch");
-exactList = document.getElementById("exactList");
-
-try {
-    requests = [{requestNames}];
-    types = [{typeNames}];
-    constructors = [{constructorNames}];
-
-    requestsu = [{requestUrls}];
-    typesu = [{typeUrls}];
-    constructorsu = [{constructorUrls}];
-} catch (e) {
-    requests = [];
-    types = [];
-    constructors = [];
-    requestsu = [];
-    typesu = [];
-    constructorsu = [];
-}
-
-if (typeof prependPath !== 'undefined') {
-    for (var i = 0; i != requestsu.length; ++i) {
-        requestsu[i] = prependPath + requestsu[i];
-    }
-    for (var i = 0; i != typesu.length; ++i) {
-        typesu[i] = prependPath + typesu[i];
-    }
-    for (var i = 0; i != constructorsu.length; ++i) {
-        constructorsu[i] = prependPath + constructorsu[i];
-    }
-}
-
-// Assumes haystack has no whitespace and both are lowercase.
-//
-// Returns the penalty for finding the needle in the haystack
-// or -1 if the needle wasn't found at all.
-function find(haystack, needle) {
-    if (haystack.indexOf(needle) != -1) {
-        return 0;
-    }
-    var hi = 0;
-    var ni = 0;
-    var penalty = 0;
-    var started = false;
-    while (true) {
-        while (needle[ni] < 'a' || needle[ni] > 'z') {
-            ++ni;
-            if (ni == needle.length) {
-                return penalty;
-            }
-        }
-        while (haystack[hi] != needle[ni]) {
-            ++hi;
-            if (started) {
-                ++penalty;
-            }
-            if (hi == haystack.length) {
-                return -1;
-            }
-        }
-        ++hi;
-        ++ni;
-        started = true;
-        if (ni == needle.length) {
-            return penalty;
-        }
-        if (hi == haystack.length) {
-            return -1;
-        }
-    }
-}
-
-// Given two input arrays "original" and "original urls" and a query,
-// return a pair of arrays with matching "query" elements from "original".
-//
-// TODO Perhaps return an array of pairs instead a pair of arrays (for cache).
-function getSearchArray(original, originalu, query) {
-    var destination = [];
-    var destinationu = [];
-
-    for (var i = 0; i < original.length; ++i) {
-        var penalty = find(original[i].toLowerCase(), query);
-        if (penalty > -1 && penalty < original[i].length / 3) {
-            destination.push(original[i]);
-            destinationu.push(originalu[i]);
-        }
-    }
-
-    return [destination, destinationu];
-}
-
-// Modify "countSpan" and "resultList" accordingly based on the elements
-// given as [[elements], [element urls]] (both with the same length)
-function buildList(countSpan, resultList, foundElements) {
-    var result = "";
-    for (var i = 0; i < foundElements[0].length; ++i) {
-        result += '<li>';
-        result += '<a href="' + foundElements[1][i] + '">';
-        result += foundElements[0][i];
-        result += '</a></li>';
-    }
-
-    if (countSpan) {
-        countSpan.innerHTML = "" + foundElements[0].length;
-    }
-    resultList.innerHTML = result;
-}
-
-function updateSearch(event) {
-    var query = searchBox.value.toLowerCase();
-    if (!query) {
-        contentDiv.style.display = "";
-        searchDiv.style.display = "none";
-        return;
-    }
-
-    contentDiv.style.display = "none";
-    searchDiv.style.display = "";
-
-    var foundRequests = getSearchArray(requests, requestsu, query);
-    var foundTypes = getSearchArray(types, typesu, query);
-    var foundConstructors = getSearchArray(constructors, constructorsu, query);
-
-    var original = requests.concat(constructors);
-    var originalu = requestsu.concat(constructorsu);
-    var destination = [];
-    var destinationu = [];
-
-    for (var i = 0; i < original.length; ++i) {
-        if (original[i].toLowerCase().replace("request", "") == query) {
-            destination.push(original[i]);
-            destinationu.push(originalu[i]);
-        }
-    }
-
-    if (event && event.keyCode == 13) {
-        if (destination.length != 0) {
-            window.location = destinationu[0];
-        } else if (methodsDetails.open && foundRequests[1].length) {
-            window.location = foundRequests[1][0];
-        } else if (typesDetails.open && foundTypes[1].length) {
-            window.location = foundTypes[1][0];
-        } else if (constructorsDetails.open && foundConstructors[1].length) {
-            window.location = foundConstructors[1][0];
-        }
-        return;
-    }
-
-    buildList(methodsCount, methodsList, foundRequests);
-    buildList(typesCount, typesList, foundTypes);
-    buildList(constructorsCount, constructorsList, foundConstructors);
-
-    // Now look for exact matches
-    if (destination.length == 0) {
-        exactMatch.style.display = "none";
-    } else {
-        exactMatch.style.display = "";
-        buildList(null, exactList, [destination, destinationu]);
-        return destinationu[0];
-    }
-}
-
-function getQuery(name) {
-    var query = window.location.search.substring(1);
-    var vars = query.split("&");
-    for (var i = 0; i != vars.length; ++i) {
-        var pair = vars[i].split("=");
-        if (pair[0] == name)
-            return decodeURI(pair[1]);
-    }
-}
-
-document.onkeydown = function (e) {
-    if (e.key == '/' || e.key == 's' || e.key == 'S') {
-        if (document.activeElement != searchBox) {
-            searchBox.focus();
-            return false;
-        }
-    } else if (e.key == '?') {
-        alert('Pressing any of: /sS\nWill focus the search bar\n\n' +
-              'Pressing: enter\nWill navigate to the first match')
-    }
-}
-
-var query = getQuery('q');
-if (query) {
-    searchBox.value = query;
-}
-
-var exactUrl = updateSearch();
-var redirect = getQuery('redirect');
-if (exactUrl && redirect != 'no') {
-    window.location = exactUrl;
-}

+ 0 - 300
gramjs_generator/data/methods.csv

@@ -1,300 +0,0 @@
-method,usability,errors
-account.acceptAuthorization,user,
-account.cancelPasswordEmail,user,
-account.changePhone,user,PHONE_NUMBER_INVALID
-account.checkUsername,user,USERNAME_INVALID
-account.confirmPasswordEmail,user,
-account.confirmPhone,user,CODE_HASH_INVALID PHONE_CODE_EMPTY
-account.deleteSecureValue,user,
-account.finishTakeoutSession,user,
-account.getAccountTTL,user,
-account.getAllSecureValues,user,
-account.getAuthorizationForm,user,
-account.getAuthorizations,user,
-account.getContactSignUpNotification,user,
-account.getNotifyExceptions,user,
-account.getNotifySettings,user,PEER_ID_INVALID
-account.getPassword,user,
-account.getPasswordSettings,user,PASSWORD_HASH_INVALID
-account.getPrivacy,user,PRIVACY_KEY_INVALID
-account.getSecureValue,user,
-account.getTmpPassword,user,PASSWORD_HASH_INVALID TMP_PASSWORD_DISABLED
-account.getWallPaper,user,WALLPAPER_INVALID
-account.getWallPapers,user,
-account.getWebAuthorizations,user,
-account.initTakeoutSession,user,
-account.installWallPaper,user,WALLPAPER_INVALID
-account.registerDevice,user,TOKEN_INVALID
-account.reportPeer,user,PEER_ID_INVALID
-account.resendPasswordEmail,user,
-account.resetAuthorization,user,HASH_INVALID
-account.resetNotifySettings,user,
-account.resetWallPapers,user,
-account.resetWebAuthorization,user,
-account.resetWebAuthorizations,user,
-account.saveSecureValue,user,PASSWORD_REQUIRED
-account.saveWallPaper,user,WALLPAPER_INVALID
-account.sendChangePhoneCode,user,PHONE_NUMBER_INVALID
-account.sendConfirmPhoneCode,user,HASH_INVALID
-account.sendVerifyEmailCode,user,EMAIL_INVALID
-account.sendVerifyPhoneCode,user,
-account.setAccountTTL,user,TTL_DAYS_INVALID
-account.setContactSignUpNotification,user,
-account.setPrivacy,user,PRIVACY_KEY_INVALID
-account.unregisterDevice,user,TOKEN_INVALID
-account.updateDeviceLocked,user,
-account.updateNotifySettings,user,PEER_ID_INVALID
-account.updatePasswordSettings,user,EMAIL_UNCONFIRMED_X NEW_SALT_INVALID NEW_SETTINGS_INVALID PASSWORD_HASH_INVALID
-account.updateProfile,user,ABOUT_TOO_LONG FIRSTNAME_INVALID
-account.updateStatus,user,SESSION_PASSWORD_NEEDED
-account.updateUsername,user,USERNAME_INVALID USERNAME_NOT_MODIFIED USERNAME_OCCUPIED
-account.uploadWallPaper,user,WALLPAPER_FILE_INVALID
-account.verifyEmail,user,EMAIL_INVALID
-account.verifyPhone,user,
-auth.bindTempAuthKey,both,ENCRYPTED_MESSAGE_INVALID INPUT_REQUEST_TOO_LONG TEMP_AUTH_KEY_EMPTY Timeout
-auth.cancelCode,user,PHONE_NUMBER_INVALID
-auth.checkPassword,user,PASSWORD_HASH_INVALID
-auth.dropTempAuthKeys,both,
-auth.exportAuthorization,both,DC_ID_INVALID
-auth.importAuthorization,both,AUTH_BYTES_INVALID USER_ID_INVALID
-auth.importBotAuthorization,both,ACCESS_TOKEN_EXPIRED ACCESS_TOKEN_INVALID API_ID_INVALID
-auth.logOut,both,
-auth.recoverPassword,user,CODE_EMPTY
-auth.requestPasswordRecovery,user,PASSWORD_EMPTY
-auth.resendCode,user,PHONE_NUMBER_INVALID
-auth.resetAuthorizations,user,Timeout
-auth.sendCode,user,API_ID_INVALID API_ID_PUBLISHED_FLOOD AUTH_RESTART INPUT_REQUEST_TOO_LONG PHONE_NUMBER_APP_SIGNUP_FORBIDDEN PHONE_NUMBER_BANNED PHONE_NUMBER_FLOOD PHONE_NUMBER_INVALID PHONE_PASSWORD_FLOOD PHONE_PASSWORD_PROTECTED
-auth.signIn,user,PHONE_CODE_EMPTY PHONE_CODE_EXPIRED PHONE_CODE_INVALID PHONE_NUMBER_INVALID PHONE_NUMBER_UNOCCUPIED SESSION_PASSWORD_NEEDED
-auth.signUp,user,FIRSTNAME_INVALID MEMBER_OCCUPY_PRIMARY_LOC_FAILED PHONE_CODE_EMPTY PHONE_CODE_EXPIRED PHONE_CODE_INVALID PHONE_NUMBER_FLOOD PHONE_NUMBER_INVALID PHONE_NUMBER_OCCUPIED REG_ID_GENERATE_FAILED
-bots.answerWebhookJSONQuery,bot,QUERY_ID_INVALID USER_BOT_INVALID
-bots.sendCustomRequest,bot,USER_BOT_INVALID
-channels.checkUsername,user,CHANNEL_INVALID CHAT_ID_INVALID USERNAME_INVALID
-channels.createChannel,user,CHAT_TITLE_EMPTY USER_RESTRICTED
-channels.deleteChannel,user,CHANNEL_INVALID CHANNEL_PRIVATE
-channels.deleteHistory,user,
-channels.deleteMessages,both,CHANNEL_INVALID CHANNEL_PRIVATE MESSAGE_DELETE_FORBIDDEN
-channels.deleteUserHistory,user,CHANNEL_INVALID CHAT_ADMIN_REQUIRED
-channels.editAdmin,both,ADMINS_TOO_MUCH ADMIN_RANK_EMOJI_NOT_ALLOWED ADMIN_RANK_INVALID BOT_CHANNELS_NA CHANNEL_INVALID CHAT_ADMIN_INVITE_REQUIRED CHAT_ADMIN_REQUIRED RIGHT_FORBIDDEN USER_CREATOR USER_ID_INVALID USER_NOT_MUTUAL_CONTACT USER_PRIVACY_RESTRICTED
-channels.editBanned,both,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED USER_ADMIN_INVALID USER_ID_INVALID
-channels.editPhoto,both,CHANNEL_INVALID CHAT_ADMIN_REQUIRED PHOTO_INVALID
-channels.editTitle,both,CHANNEL_INVALID CHAT_ADMIN_REQUIRED CHAT_NOT_MODIFIED
-channels.exportMessageLink,user,CHANNEL_INVALID
-channels.getAdminLog,user,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED
-channels.getAdminedPublicChannels,user,
-channels.getChannels,both,CHANNEL_INVALID CHANNEL_PRIVATE NEED_CHAT_INVALID
-channels.getFullChannel,both,CHANNEL_INVALID CHANNEL_PRIVATE CHANNEL_PUBLIC_GROUP_NA Timeout
-channels.getLeftChannels,user,
-channels.getMessages,both,CHANNEL_INVALID CHANNEL_PRIVATE MESSAGE_IDS_EMPTY
-channels.getParticipant,both,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED USER_ID_INVALID USER_NOT_PARTICIPANT
-channels.getParticipants,both,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED INPUT_CONSTRUCTOR_INVALID Timeout
-channels.inviteToChannel,user,BOTS_TOO_MUCH BOT_GROUPS_BLOCKED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_INVALID CHAT_WRITE_FORBIDDEN INPUT_USER_DEACTIVATED USERS_TOO_MUCH USER_BANNED_IN_CHANNEL USER_BLOCKED USER_BOT USER_CHANNELS_TOO_MUCH USER_ID_INVALID USER_KICKED USER_NOT_MUTUAL_CONTACT USER_PRIVACY_RESTRICTED
-channels.joinChannel,user,CHANNELS_TOO_MUCH CHANNEL_INVALID CHANNEL_PRIVATE
-channels.leaveChannel,both,CHANNEL_INVALID CHANNEL_PRIVATE CHANNEL_PUBLIC_GROUP_NA USER_CREATOR USER_NOT_PARTICIPANT
-channels.readHistory,user,CHANNEL_INVALID CHANNEL_PRIVATE
-channels.readMessageContents,user,CHANNEL_INVALID CHANNEL_PRIVATE
-channels.reportSpam,user,CHANNEL_INVALID INPUT_USER_DEACTIVATED
-channels.setDiscussionGroup,user,BROADCAST_ID_INVALID LINK_NOT_MODIFIED MEGAGROUP_ID_INVALID MEGAGROUP_PREHISTORY_HIDDEN
-channels.setStickers,both,CHANNEL_INVALID PARTICIPANTS_TOO_FEW
-channels.togglePreHistoryHidden,user,CHAT_LINK_EXISTS
-channels.toggleSignatures,user,CHANNEL_INVALID
-channels.toggleSlowMode,user,SECONDS_INVALID
-channels.updateUsername,user,CHANNELS_ADMIN_PUBLIC_TOO_MUCH CHANNEL_INVALID CHAT_ADMIN_REQUIRED USERNAME_INVALID USERNAME_OCCUPIED
-contacts.block,user,CONTACT_ID_INVALID
-contacts.deleteByPhones,user,
-contacts.deleteContact,user,CONTACT_ID_INVALID
-contacts.deleteContacts,user,NEED_MEMBER_INVALID Timeout
-contacts.getBlocked,user,
-contacts.getContactIDs,user,
-contacts.getContacts,user,
-contacts.getSaved,user,TAKEOUT_REQUIRED
-contacts.getStatuses,user,
-contacts.getTopPeers,user,TYPES_EMPTY
-contacts.importContacts,user,
-contacts.resetSaved,user,
-contacts.resetTopPeerRating,user,PEER_ID_INVALID
-contacts.resolveUsername,both,AUTH_KEY_PERM_EMPTY SESSION_PASSWORD_NEEDED USERNAME_INVALID USERNAME_NOT_OCCUPIED
-contacts.search,user,QUERY_TOO_SHORT SEARCH_QUERY_EMPTY Timeout
-contacts.toggleTopPeers,user,
-contacts.unblock,user,CONTACT_ID_INVALID
-contest.saveDeveloperInfo,both,
-folders.deleteFolder,user,FOLDER_ID_EMPTY
-folders.editPeerFolders,user,FOLDER_ID_INVALID
-help.acceptTermsOfService,user,
-help.editUserInfo,user,USER_INVALID
-help.getAppChangelog,user,
-help.getAppConfig,user,
-help.getAppUpdate,user,
-help.getCdnConfig,both,AUTH_KEY_PERM_EMPTY Timeout
-help.getConfig,both,AUTH_KEY_DUPLICATED Timeout
-help.getDeepLinkInfo,user,
-help.getInviteText,user,
-help.getNearestDc,user,
-help.getPassportConfig,user,
-help.getProxyData,user,
-help.getRecentMeUrls,user,
-help.getSupport,user,
-help.getSupportName,user,USER_INVALID
-help.getTermsOfServiceUpdate,user,
-help.getUserInfo,user,USER_INVALID
-help.saveAppLog,user,
-help.setBotUpdatesStatus,both,
-initConnection,both,CONNECTION_LAYER_INVALID INPUT_FETCH_FAIL
-invokeAfterMsg,both,
-invokeAfterMsgs,both,
-invokeWithLayer,both,AUTH_BYTES_INVALID AUTH_KEY_DUPLICATED CDN_METHOD_INVALID CHAT_WRITE_FORBIDDEN CONNECTION_API_ID_INVALID CONNECTION_DEVICE_MODEL_EMPTY CONNECTION_LANG_PACK_INVALID CONNECTION_NOT_INITED CONNECTION_SYSTEM_EMPTY INPUT_LAYER_INVALID INVITE_HASH_EXPIRED NEED_MEMBER_INVALID Timeout
-invokeWithMessagesRange,both,
-invokeWithTakeout,both,
-invokeWithoutUpdates,both,
-langpack.getDifference,user,LANG_PACK_INVALID
-langpack.getLangPack,user,LANG_PACK_INVALID
-langpack.getLanguage,user,
-langpack.getLanguages,user,LANG_PACK_INVALID
-langpack.getStrings,user,LANG_PACK_INVALID
-messages.acceptEncryption,user,CHAT_ID_INVALID ENCRYPTION_ALREADY_ACCEPTED ENCRYPTION_ALREADY_DECLINED ENCRYPTION_OCCUPY_FAILED
-messages.addChatUser,user,CHAT_ADMIN_REQUIRED CHAT_ID_INVALID INPUT_USER_DEACTIVATED PEER_ID_INVALID USERS_TOO_MUCH USER_ALREADY_PARTICIPANT USER_ID_INVALID USER_NOT_MUTUAL_CONTACT USER_PRIVACY_RESTRICTED
-messages.checkChatInvite,user,INVITE_HASH_EMPTY INVITE_HASH_EXPIRED INVITE_HASH_INVALID
-messages.clearAllDrafts,user,
-messages.clearRecentStickers,user,
-messages.createChat,user,USERS_TOO_FEW USER_RESTRICTED
-messages.deleteChatUser,both,CHAT_ID_INVALID PEER_ID_INVALID USER_NOT_PARTICIPANT
-messages.deleteHistory,user,PEER_ID_INVALID
-messages.deleteMessages,both,MESSAGE_DELETE_FORBIDDEN
-messages.discardEncryption,user,CHAT_ID_EMPTY ENCRYPTION_ALREADY_DECLINED ENCRYPTION_ID_INVALID
-messages.editChatAbout,both,
-messages.editChatAdmin,user,CHAT_ID_INVALID
-messages.editChatDefaultBannedRights,both,BANNED_RIGHTS_INVALID
-messages.editChatPhoto,both,CHAT_ID_INVALID INPUT_CONSTRUCTOR_INVALID INPUT_FETCH_FAIL PEER_ID_INVALID PHOTO_EXT_INVALID
-messages.editChatTitle,both,CHAT_ID_INVALID NEED_CHAT_INVALID
-messages.editInlineBotMessage,both,MESSAGE_ID_INVALID MESSAGE_NOT_MODIFIED
-messages.editMessage,both,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_WRITE_FORBIDDEN INPUT_USER_DEACTIVATED MEDIA_NEW_INVALID MEDIA_PREV_INVALID MESSAGE_AUTHOR_REQUIRED MESSAGE_EDIT_TIME_EXPIRED MESSAGE_EMPTY MESSAGE_ID_INVALID MESSAGE_NOT_MODIFIED PEER_ID_INVALID
-messages.exportChatInvite,user,CHAT_ID_INVALID
-messages.faveSticker,user,STICKER_ID_INVALID
-messages.forwardMessages,both,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_SEND_GIFS_FORBIDDEN CHAT_SEND_MEDIA_FORBIDDEN CHAT_SEND_STICKERS_FORBIDDEN CHAT_WRITE_FORBIDDEN GROUPED_MEDIA_INVALID INPUT_USER_DEACTIVATED MEDIA_EMPTY MESSAGE_IDS_EMPTY MESSAGE_ID_INVALID PEER_ID_INVALID PTS_CHANGE_EMPTY RANDOM_ID_DUPLICATE RANDOM_ID_INVALID SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
-messages.getAllChats,user,
-messages.getAllDrafts,user,
-messages.getAllStickers,user,
-messages.getArchivedStickers,user,
-messages.getAttachedStickers,user,
-messages.getBotCallbackAnswer,user,CHANNEL_INVALID DATA_INVALID MESSAGE_ID_INVALID PEER_ID_INVALID Timeout
-messages.getChats,both,CHAT_ID_INVALID PEER_ID_INVALID
-messages.getCommonChats,user,USER_ID_INVALID
-messages.getDhConfig,user,RANDOM_LENGTH_INVALID
-messages.getDialogUnreadMarks,user,
-messages.getDialogs,user,INPUT_CONSTRUCTOR_INVALID OFFSET_PEER_ID_INVALID SESSION_PASSWORD_NEEDED Timeout
-messages.getDocumentByHash,both,SHA256_HASH_INVALID
-messages.getFavedStickers,user,
-messages.getFeaturedStickers,user,
-messages.getFullChat,both,CHAT_ID_INVALID PEER_ID_INVALID
-messages.getGameHighScores,bot,PEER_ID_INVALID USER_BOT_REQUIRED
-messages.getHistory,user,AUTH_KEY_DUPLICATED AUTH_KEY_PERM_EMPTY CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ID_INVALID PEER_ID_INVALID Timeout
-messages.getInlineBotResults,user,BOT_INLINE_DISABLED BOT_INVALID CHANNEL_PRIVATE Timeout
-messages.getInlineGameHighScores,bot,MESSAGE_ID_INVALID USER_BOT_REQUIRED
-messages.getMaskStickers,user,
-messages.getMessageEditData,user,MESSAGE_AUTHOR_REQUIRED PEER_ID_INVALID
-messages.getMessages,both,
-messages.getMessagesViews,user,CHANNEL_PRIVATE CHAT_ID_INVALID PEER_ID_INVALID
-messages.getOnlines,user,
-messages.getPeerDialogs,user,CHANNEL_PRIVATE PEER_ID_INVALID
-messages.getPeerSettings,user,CHANNEL_INVALID PEER_ID_INVALID
-messages.getPinnedDialogs,user,
-messages.getPollResults,user,
-messages.getRecentLocations,user,
-messages.getRecentStickers,user,
-messages.getSavedGifs,user,
-messages.getSplitRanges,user,
-messages.getStatsURL,user,
-messages.getStickerSet,both,STICKERSET_INVALID
-messages.getStickers,user,EMOTICON_EMPTY
-messages.getUnreadMentions,user,PEER_ID_INVALID
-messages.getWebPage,user,WC_CONVERT_URL_INVALID
-messages.getWebPagePreview,user,
-messages.hideReportSpam,user,PEER_ID_INVALID
-messages.importChatInvite,user,CHANNELS_TOO_MUCH INVITE_HASH_EMPTY INVITE_HASH_EXPIRED INVITE_HASH_INVALID SESSION_PASSWORD_NEEDED USERS_TOO_MUCH USER_ALREADY_PARTICIPANT
-messages.installStickerSet,user,STICKERSET_INVALID
-messages.markDialogUnread,user,
-messages.migrateChat,user,CHAT_ADMIN_REQUIRED CHAT_ID_INVALID PEER_ID_INVALID
-messages.readEncryptedHistory,user,MSG_WAIT_FAILED
-messages.readFeaturedStickers,user,
-messages.readHistory,user,PEER_ID_INVALID Timeout
-messages.readMentions,user,
-messages.readMessageContents,user,
-messages.receivedMessages,user,
-messages.receivedQueue,user,MSG_WAIT_FAILED MAX_QTS_INVALID
-messages.reorderPinnedDialogs,user,PEER_ID_INVALID
-messages.reorderStickerSets,user,
-messages.report,user,
-messages.reportEncryptedSpam,user,CHAT_ID_INVALID
-messages.reportSpam,user,PEER_ID_INVALID
-messages.requestEncryption,user,DH_G_A_INVALID USER_ID_INVALID
-messages.saveDraft,user,PEER_ID_INVALID
-messages.saveGif,user,GIF_ID_INVALID
-messages.saveRecentSticker,user,STICKER_ID_INVALID
-messages.search,user,CHAT_ADMIN_REQUIRED INPUT_CONSTRUCTOR_INVALID INPUT_USER_DEACTIVATED PEER_ID_INVALID PEER_ID_NOT_SUPPORTED SEARCH_QUERY_EMPTY USER_ID_INVALID
-messages.searchGifs,user,SEARCH_QUERY_EMPTY
-messages.searchGlobal,user,SEARCH_QUERY_EMPTY
-messages.searchStickerSets,user,
-messages.sendEncrypted,user,CHAT_ID_INVALID DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED
-messages.sendEncryptedFile,user,MSG_WAIT_FAILED
-messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED
-messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
-messages.sendMedia,both,BOT_PAYMENTS_DISABLED BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PAYMENT_PROVIDER_INVALID PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
-messages.sendMessage,both,AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
-messages.sendMultiMedia,both,SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH
-messages.sendReaction,User,REACTION_INVALID
-messages.sendVote,user,
-messages.setBotCallbackAnswer,both,QUERY_ID_INVALID URL_INVALID
-messages.setBotPrecheckoutResults,both,ERROR_TEXT_EMPTY
-messages.setBotShippingResults,both,QUERY_ID_INVALID
-messages.setEncryptedTyping,user,CHAT_ID_INVALID
-messages.setGameScore,bot,PEER_ID_INVALID USER_BOT_REQUIRED
-messages.setInlineBotResults,bot,ARTICLE_TITLE_EMPTY BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID MESSAGE_EMPTY PHOTO_CONTENT_URL_EMPTY PHOTO_THUMB_URL_EMPTY QUERY_ID_INVALID REPLY_MARKUP_INVALID RESULT_TYPE_INVALID SEND_MESSAGE_MEDIA_INVALID SEND_MESSAGE_TYPE_INVALID START_PARAM_INVALID USER_BOT_INVALID
-messages.setInlineGameScore,bot,MESSAGE_ID_INVALID USER_BOT_REQUIRED
-messages.setTyping,both,CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ID_INVALID CHAT_WRITE_FORBIDDEN PEER_ID_INVALID USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT
-messages.startBot,user,BOT_INVALID PEER_ID_INVALID START_PARAM_EMPTY START_PARAM_INVALID
-messages.toggleDialogPin,user,PEER_ID_INVALID
-messages.uninstallStickerSet,user,STICKERSET_INVALID
-messages.updatePinnedMessage,both,
-messages.uploadEncryptedFile,user,
-messages.uploadMedia,both,BOT_MISSING MEDIA_INVALID PEER_ID_INVALID
-payments.clearSavedInfo,user,
-payments.getPaymentForm,user,MESSAGE_ID_INVALID
-payments.getPaymentReceipt,user,MESSAGE_ID_INVALID
-payments.getSavedInfo,user,
-payments.sendPaymentForm,user,MESSAGE_ID_INVALID
-payments.validateRequestedInfo,user,MESSAGE_ID_INVALID
-phone.acceptCall,user,CALL_ALREADY_ACCEPTED CALL_ALREADY_DECLINED CALL_OCCUPY_FAILED CALL_PEER_INVALID CALL_PROTOCOL_FLAGS_INVALID
-phone.confirmCall,user,CALL_ALREADY_DECLINED CALL_PEER_INVALID
-phone.discardCall,user,CALL_ALREADY_ACCEPTED CALL_PEER_INVALID
-phone.getCallConfig,user,
-phone.receivedCall,user,CALL_ALREADY_DECLINED CALL_PEER_INVALID
-phone.requestCall,user,CALL_PROTOCOL_FLAGS_INVALID PARTICIPANT_CALL_FAILED PARTICIPANT_VERSION_OUTDATED USER_ID_INVALID USER_IS_BLOCKED USER_PRIVACY_RESTRICTED
-phone.saveCallDebug,user,CALL_PEER_INVALID DATA_JSON_INVALID
-phone.setCallRating,user,CALL_PEER_INVALID
-photos.deletePhotos,user,
-photos.getUserPhotos,both,MAX_ID_INVALID USER_ID_INVALID
-photos.updateProfilePhoto,user,
-photos.uploadProfilePhoto,user,FILE_PARTS_INVALID IMAGE_PROCESS_FAILED PHOTO_CROP_SIZE_SMALL PHOTO_EXT_INVALID
-ping,both,
-reqDHParams,both,
-reqPq,both,
-reqPqMulti,both,
-rpcDropAnswer,both,
-setClientDHParams,both,
-stickers.addStickerToSet,bot,BOT_MISSING STICKERSET_INVALID
-stickers.changeStickerPosition,bot,BOT_MISSING STICKER_INVALID
-stickers.createStickerSet,bot,BOT_MISSING PACK_SHORT_NAME_INVALID PACK_SHORT_NAME_OCCUPIED PEER_ID_INVALID SHORTNAME_OCCUPY_FAILED STICKERS_EMPTY STICKER_EMOJI_INVALID STICKER_FILE_INVALID STICKER_PNG_DIMENSIONS USER_ID_INVALID
-stickers.removeStickerFromSet,bot,BOT_MISSING STICKER_INVALID
-updates.getChannelDifference,both,CHANNEL_INVALID CHANNEL_PRIVATE CHANNEL_PUBLIC_GROUP_NA HISTORY_GET_FAILED PERSISTENT_TIMESTAMP_EMPTY PERSISTENT_TIMESTAMP_INVALID PERSISTENT_TIMESTAMP_OUTDATED RANGES_INVALID Timeout
-updates.getDifference,both,AUTH_KEY_PERM_EMPTY CDN_METHOD_INVALID DATE_EMPTY NEED_MEMBER_INVALID PERSISTENT_TIMESTAMP_EMPTY PERSISTENT_TIMESTAMP_INVALID SESSION_PASSWORD_NEEDED STORE_INVALID_SCALAR_TYPE Timeout
-updates.getState,both,AUTH_KEY_DUPLICATED SESSION_PASSWORD_NEEDED Timeout
-upload.getCdnFile,user,UNKNOWN_METHOD
-upload.getCdnFileHashes,both,CDN_METHOD_INVALID RSA_DECRYPT_FAILED
-upload.getFile,both,AUTH_KEY_PERM_EMPTY FILE_ID_INVALID INPUT_FETCH_FAIL LIMIT_INVALID LOCATION_INVALID OFFSET_INVALID Timeout
-upload.getFileHashes,both,
-upload.getWebFile,user,LOCATION_INVALID
-upload.reuploadCdnFile,both,RSA_DECRYPT_FAILED
-upload.saveBigFilePart,both,FILE_PARTS_INVALID FILE_PART_EMPTY FILE_PART_INVALID FILE_PART_SIZE_INVALID Timeout
-upload.saveFilePart,both,FILE_PART_EMPTY FILE_PART_INVALID INPUT_FETCH_FAIL SESSION_PASSWORD_NEEDED
-users.getFullUser,both,Timeout USER_ID_INVALID
-users.getUsers,both,AUTH_KEY_PERM_EMPTY MEMBER_NO_LOCATION NEED_MEMBER_INVALID SESSION_PASSWORD_NEEDED Timeout
-users.setSecureValueErrors,bot,

+ 0 - 113
gramjs_generator/data/mtproto.tl

@@ -1,113 +0,0 @@
-// Core types (no need to gen)
-
-//vector#1cb5c415 {t:Type} # [ t ] = Vector t;
-
-///////////////////////////////
-/// Authorization key creation
-///////////////////////////////
-
-resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector<long> = ResPQ;
-
-p_q_inner_data#83c95aec pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data;
-p_q_inner_data_dc#a9f55f95 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data;
-p_q_inner_data_temp#3c6a84d4 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data;
-p_q_inner_data_temp_dc#56fddf88 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data;
-
-server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params;
-server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;
-
-server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:string g_a:string server_time:int = Server_DH_inner_data;
-
-client_DH_inner_data#6643b654 nonce:int128 server_nonce:int128 retry_id:long g_b:string = Client_DH_Inner_Data;
-
-dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer;
-dh_gen_retry#46dc1fb9 nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer;
-dh_gen_fail#a69dae02 nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer;
-
-destroy_auth_key_ok#f660e1d4 = DestroyAuthKeyRes;
-destroy_auth_key_none#0a9f2259 = DestroyAuthKeyRes;
-destroy_auth_key_fail#ea109b13 = DestroyAuthKeyRes;
-
----functions---
-
-req_pq#60469778 nonce:int128 = ResPQ;
-req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;
-
-req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params;
-
-set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:string = Set_client_DH_params_answer;
-
-destroy_auth_key#d1435160 = DestroyAuthKeyRes;
-
-///////////////////////////////
-////////////// System messages
-///////////////////////////////
-
----types---
-
-msgs_ack#62d6b459 msg_ids:Vector<long> = MsgsAck;
-
-bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification;
-bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification;
-
-msgs_state_req#da69fb52 msg_ids:Vector<long> = MsgsStateReq;
-msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
-msgs_all_info#8cc0d131 msg_ids:Vector<long> info:string = MsgsAllInfo;
-
-msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
-msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
-
-msg_resend_req#7d861a08 msg_ids:Vector<long> = MsgResendReq;
-
-//rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult; // parsed manually
-
-rpc_error#2144ca19 error_code:int error_message:string = RpcError;
-
-rpc_answer_unknown#5e2ad36e = RpcDropAnswer;
-rpc_answer_dropped_running#cd78e586 = RpcDropAnswer;
-rpc_answer_dropped#a43ad8b7 msg_id:long seq_no:int bytes:int = RpcDropAnswer;
-
-future_salt#0949d9dc valid_since:int valid_until:int salt:long = FutureSalt;
-future_salts#ae500895 req_msg_id:long now:int salts:vector<future_salt> = FutureSalts;
-
-pong#347773c5 msg_id:long ping_id:long = Pong;
-
-destroy_session_ok#e22045fc session_id:long = DestroySessionRes;
-destroy_session_none#62d350c9 session_id:long = DestroySessionRes;
-
-new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long = NewSession;
-
-//message msg_id:long seqno:int bytes:int body:Object = Message; // parsed manually
-//msg_container#73f1f8dc messages:vector<message> = MessageContainer; // parsed manually
-//msg_copy#e06046b2 orig_message:Message = MessageCopy; // parsed manually, not used - use msg_container
-//gzip_packed#3072cfa1 packed_data:string = Object; // parsed manually
-
-http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
-
-//ipPort ipv4:int port:int = IpPort;
-//help.configSimple#d997c3c5 date:int expires:int dc_id:int ip_port_list:Vector<ipPort> = help.ConfigSimple;
-
-ipPort#d433ad73 ipv4:int port:int = IpPort;
-ipPortSecret#37982646 ipv4:int port:int secret:bytes = IpPort;
-accessPointRule#4679b65f phone_prefix_rules:string dc_id:int ips:vector<IpPort> = AccessPointRule;
-help.configSimple#5a592a6c date:int expires:int rules:vector<AccessPointRule> = help.ConfigSimple;
-
-tlsClientHello blocks:vector<TlsBlock> = TlsClientHello;
-
-tlsBlockString data:string = TlsBlock;
-tlsBlockRandom length:int = TlsBlock;
-tlsBlockZero length:int = TlsBlock;
-tlsBlockDomain = TlsBlock;
-tlsBlockGrease seed:int = TlsBlock;
-tlsBlockScope entries:Vector<TlsBlock> = TlsBlock;
-
----functions---
-
-rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;
-
-get_future_salts#b921bd04 num:int = FutureSalts;
-
-ping#7abe77ec ping_id:long = Pong;
-ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;
-
-destroy_session#e7512126 session_id:long = DestroySessionRes;

+ 0 - 390
gramjs_generator/docswriter.js

@@ -1,390 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-const util = require('util')
-
-class DocsWriter {
-    /**
-     * Utility class used to write the HTML files used on the documentation.
-     *
-     * Initializes the writer to the specified output file,
-     * creating the parent directories when used if required.
-     */
-    constructor(filename, typeToPath) {
-        this.filename = filename
-        this._parent = path.join(this.filename, '..')
-        this.handle = null
-        this.title = ''
-
-        // Should be set before calling adding items to the menu
-        this.menuSeparatorTag = null
-
-        // Utility functions
-        this.typeToPath = (t) => this._rel(typeToPath(t))
-
-        // Control signals
-        this.menuBegan = false
-        this.tableColumns = 0
-        this.tableColumnsLeft = null
-        this.writeCopyScript = false
-        this._script = ''
-    }
-
-    /**
-     * Get the relative path for the given path from the current
-     * file by working around https://bugs.python.org/issue20012.
-     */
-    _rel(path_) {
-        return path
-            .relative(this._parent, path_)
-            .replace(new RegExp(`\\${path.sep}`, 'g'), '/')
-    }
-
-    /**
-     * Writes the head part for the generated document,
-     * with the given title and CSS
-     */
-    // High level writing
-    writeHead(title, cssPath, defaultCss) {
-        this.title = title
-        this.write(
-            `<!DOCTYPE html>
-<html>
-<head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <title>${title}</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link id="style" href="${this._rel(
-        cssPath
-    )}/docs.dark.css" rel="stylesheet">
-    <script>
-    document.getElementById("style").href = "${this._rel(cssPath)}/docs."
-        + (localStorage.getItem("theme") || "${defaultCss}")
-        + ".css";
-    </script>
-    <link href="https://fonts.googleapis.com/css?family=Nunito|Source+Code+Pro"
-          rel="stylesheet">
-</head>
-<body>
-<div id="main_div">`
-        )
-    }
-
-    /**
-     * Sets the menu separator.
-     * Must be called before adding entries to the menu
-     */
-    setMenuSeparator(img) {
-        if (img) {
-            this.menuSeparatorTag = `<img src="${this._rel(img)}" alt="/" />`
-        } else {
-            this.menuSeparatorTag = null
-        }
-    }
-
-    /**
-     * Adds a menu entry, will create it if it doesn't exist yet
-     */
-    addMenu(name, link) {
-        if (this.menuBegan) {
-            if (this.menuSeparatorTag) {
-                this.write(this.menuSeparatorTag)
-            }
-        } else {
-            // First time, create the menu tag
-            this.write('<ul class="horizontal">')
-            this.menuBegan = true
-        }
-
-        this.write('<li>')
-
-        if (link) {
-            this.write(`<a href="${this._rel(link)}">`)
-        }
-
-        // Write the real menu entry text
-        this.write(name)
-
-        if (link) {
-            this.write('</a>')
-        }
-
-        this.write('</li>')
-    }
-
-    /**
-     * Ends an opened menu
-     */
-    endMenu() {
-        if (!this.menuBegan) {
-            throw new Error('No menu had been started in the first place.')
-        }
-
-        this.write('</ul>')
-    }
-
-    /**
-     * Writes a title header in the document body,
-     * with an optional depth level
-     */
-    writeTitle(title, level, id) {
-        level = level || 1
-
-        if (id) {
-            this.write(`<h${level} id="${id}">${title}</h${level}>`)
-        } else {
-            this.write(`<h${level}>${title}</h${level}>`)
-        }
-    }
-
-    /**
-     * Writes the code for the given 'tlobject' properly
-     * formatted with hyperlinks
-     */
-    writeCode(tlobject) {
-        this.write(
-            `<pre>---${tlobject.isFunction ? 'functions' : 'types'}---\n`
-        )
-
-        // Write the function or type and its ID
-        if (tlobject.namespace) {
-            this.write(tlobject.namespace)
-            this.write('.')
-        }
-
-        this.write(
-            `${tlobject.name}#${tlobject.id.toString(16).padStart(8, '0')}`
-        )
-
-        // Write all the arguments (or do nothing if there's none)
-        for (const arg of tlobject.args) {
-            this.write(' ')
-            const addLink = !arg.genericDefinition && !arg.isGeneric
-
-            // "Opening" modifiers
-            if (arg.genericDefinition) {
-                this.write('{')
-            }
-
-            // Argument name
-            this.write(arg.name)
-            this.write(':')
-
-            // "Opening" modifiers
-            if (arg.isFlag) {
-                this.write(`flags.${arg.flagIndex}?`)
-            }
-
-            if (arg.isGeneric) {
-                this.write('!')
-            }
-
-            if (arg.isVector) {
-                this.write(
-                    `<a href="${this.typeToPath('vector')}">Vector</a>&lt;`
-                )
-            }
-
-            // Argument type
-            if (arg.type) {
-                if (addLink) {
-                    this.write(`<a href="${this.typeToPath(arg.type)}">`)
-                }
-
-                this.write(arg.type)
-
-                if (addLink) {
-                    this.write('</a>')
-                }
-            } else {
-                this.write('#')
-            }
-
-            // "Closing" modifiers
-            if (arg.isVector) {
-                this.write('&gt;')
-            }
-
-            if (arg.genericDefinition) {
-                this.write('}')
-            }
-        }
-
-        // Now write the resulting type (result from a function/type)
-        this.write(' = ')
-        const [genericName] = tlobject.args
-            .filter((arg) => arg.genericDefinition)
-            .map((arg) => arg.name)
-
-        if (tlobject.result === genericName) {
-            // Generic results cannot have any link
-            this.write(tlobject.result)
-        } else {
-            if (/^vector</i.test(tlobject.result)) {
-                // Notice that we don't simply make up the "Vector" part,
-                // because some requests (as of now, only FutureSalts),
-                // use a lower type name for it (see #81)
-                let [vector, inner] = tlobject.result.split('<')
-                inner = inner.replace(/>+$/, '')
-
-                this.write(
-                    `<a href="${this.typeToPath(vector)}">${vector}</a>&lt;`
-                )
-                this.write(
-                    `<a href="${this.typeToPath(inner)}">${inner}</a>&gt;`
-                )
-            } else {
-                this.write(
-                    `<a href="${this.typeToPath(tlobject.result)}">${
-                        tlobject.result
-                    }</a>`
-                )
-            }
-        }
-
-        this.write('</pre>')
-    }
-
-    /**
-     * Begins a table with the given 'column_count', required to automatically
-     * create the right amount of columns when adding items to the rows
-     */
-    beginTable(columnCount) {
-        this.tableColumns = columnCount
-        this.tableColumnsLeft = 0
-        this.write('<table>')
-    }
-
-    /**
-     * This will create a new row, or add text to the next column
-     * of the previously created, incomplete row, closing it if complete
-     */
-    addRow(text, link, bold, align) {
-        if (!this.tableColumnsLeft) {
-            // Starting a new row
-            this.write('<tr>')
-            this.tableColumnsLeft = this.tableColumns
-        }
-
-        this.write('<td')
-
-        if (align) {
-            this.write(` style="text-align: ${align}"`)
-        }
-
-        this.write('>')
-
-        if (bold) {
-            this.write('<b>')
-        }
-
-        if (link) {
-            this.write(`<a href="${this._rel(link)}">`)
-        }
-
-        // Finally write the real table data, the given text
-        this.write(text)
-
-        if (link) {
-            this.write('</a>')
-        }
-
-        if (bold) {
-            this.write('</b>')
-        }
-
-        this.write('</td>')
-
-        this.tableColumnsLeft -= 1
-        if (!this.tableColumnsLeft) {
-            this.write('</tr>')
-        }
-    }
-
-    endTable() {
-        if (this.tableColumnsLeft) {
-            this.write('</tr>')
-        }
-
-        this.write('</table>')
-    }
-
-    /**
-     * Writes a paragraph of text
-     */
-    writeText(text) {
-        this.write(`<p>${text}</p>`)
-    }
-
-    /**
-     * Writes a button with 'text' which can be used
-     * to copy 'textToCopy' to clipboard when it's clicked.
-     */
-    writeCopyButton(text, textToCopy) {
-        this.writeCopyScript = true
-        this.write(
-            `<button onclick="cp('${textToCopy.replace(
-                /'/g,
-                '\\\''
-            )}');">${text}</button>`
-        )
-    }
-
-    addScript(src, path) {
-        if (path) {
-            this._script += `<script src="${this._rel(path)}"></script>`
-        } else if (src) {
-            this._script += `<script>${src}</script>`
-        }
-    }
-
-    /**
-     * Ends the whole document. This should be called the last
-     */
-    endBody() {
-        if (this.writeCopyScript) {
-            this.write(
-                '<textarea id="c" class="invisible"></textarea>' +
-                    '<script>' +
-                    'function cp(t){' +
-                    'var c=document.getElementById("c");' +
-                    'c.value=t;' +
-                    'c.select();' +
-                    'try{document.execCommand("copy")}' +
-                    'catch(e){}}' +
-                    '</script>'
-            )
-        }
-
-        this.write(`</div>${this._script}</body></html>`)
-    }
-
-    /**
-     * Wrapper around handle.write
-     */
-    // "Low" level writing
-    write(s, ...args) {
-        if (args.length) {
-            fs.appendFileSync(this.handle, util.format(s, ...args))
-        } else {
-            fs.appendFileSync(this.handle, s)
-        }
-    }
-
-    open() {
-        // Sanity check
-        const parent = path.join(this.filename, '..')
-        fs.mkdirSync(parent, { recursive: true })
-
-        this.handle = fs.openSync(this.filename, 'w')
-
-        return this
-    }
-
-    close() {
-        fs.closeSync(this.handle)
-    }
-}
-
-module.exports = {
-    DocsWriter,
-}

+ 0 - 827
gramjs_generator/generators/docs.js

@@ -1,827 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-const format = require('string-format')
-const { DocsWriter } = require('../docswriter')
-const { TLObject, Usability } = require('../parsers')
-const { snakeToCamelCase } = require('../utils')
-
-const CORE_TYPES = new Set([
-    'int',
-    'long',
-    'int128',
-    'int256',
-    'double',
-    'vector',
-    'string',
-    'bool',
-    'true',
-    'bytes',
-    'date',
-])
-
-const mkdir = (path) => fs.mkdirSync(path, { recursive: true })
-
-const titleCase = (text) =>
-    text
-        .toLowerCase()
-        .split(/(\W)/)
-        .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)
-        .join('')
-
-/**
- * ``ClassName -> class_name.html``.
- */
-const getFileName = (tlobject) => {
-    const name = tlobject instanceof TLObject ? tlobject.name : tlobject
-    // Courtesy of http://stackoverflow.com/a/1176023/4759433
-    const s1 = name.replace(/(.)([A-Z][a-z]+)/, '$1_$2')
-    const result = s1.replace(/([a-z0-9])([A-Z])/, '$1_$2').toLowerCase()
-    return `${result}.html`
-}
-
-/**
- * ``TLObject -> const { ... } = require(...);``.
- */
-const getImportCode = (tlobject) => {
-    const kind = tlobject.isFunction ? 'functions' : 'types'
-    const ns = tlobject.namespace ? `/${tlobject.namespace}` : ''
-    return `const { ${tlobject.className} } = require('gramjs/tl/${kind}${ns}');`
-}
-
-/**
- * Returns the path for the given TLObject.
- */
-const getPathFor = (tlobject) => {
-    let outDir = tlobject.isFunction ? 'methods' : 'constructors'
-
-    if (tlobject.namespace) {
-        outDir += `/${tlobject.namespace}`
-    }
-
-    return `${outDir}/${getFileName(tlobject)}`
-}
-
-/**
- * Similar to `getPathFor` but for only type names.
- */
-const getPathForType = (type) => {
-    if (CORE_TYPES.has(type.toLowerCase())) {
-        return `index.html#${type.toLowerCase()}`
-    } else if (type.includes('.')) {
-        const [namespace, name] = type.split('.')
-        return `types/${namespace}/${getFileName(name)}`
-    } else {
-        return `types/${getFileName(type)}`
-    }
-}
-
-/**
- * Finds the <title> for the given HTML file, or (Unknown).
- */
-const findTitle = (htmlFile) => {
-    const f = fs.readFileSync(htmlFile, { encoding: 'utf-8' })
-
-    for (const line of f.split('\n')) {
-        if (line.includes('<title>')) {
-            // +7 to skip '<title>'.length
-            return line.slice(
-                line.indexOf('<title>') + 7,
-                line.indexOf('</title>')
-            )
-        }
-    }
-
-    return '(Unknown)'
-}
-
-/**
- * Builds the menu used for the current ``DocumentWriter``.
- */
-const buildMenu = (docs) => {
-    const paths = []
-    let current = docs.filename
-
-    while (current !== '.') {
-        current = path.join(current, '..')
-        paths.push(current)
-    }
-
-    for (const path_ of paths.reverse()) {
-        const name = path.parse(path_).name
-
-        docs.addMenu(
-            name === '.' ? 'API' : titleCase(name),
-            `${path_}/index.html`
-        )
-    }
-
-    if (path.parse(docs.filename).name !== 'index') {
-        docs.addMenu(docs.title, docs.filename)
-    }
-
-    docs.endMenu()
-}
-
-/**
- * Generates the index file for the specified folder
- */
-const generateIndex = (folder, paths, botsIndex, botsIndexPaths) => {
-    botsIndexPaths = botsIndexPaths || []
-
-    // Determine the namespaces listed here (as sub folders)
-    // and the files (.html files) that we should link to
-    const namespaces = []
-    const files = []
-    const INDEX = 'index.html'
-    const BOT_INDEX = 'botindex.html'
-
-    for (const item of botsIndexPaths.length ? botsIndexPaths : fs.readdirSync(folder)) {
-        const fullPath = botsIndexPaths.length ? item : `${folder}/${item}`
-
-        if (fs.statSync(fullPath).isDirectory()) {
-            namespaces.push(fullPath)
-        } else if (![INDEX, BOT_INDEX].includes(item)) {
-            files.push(fullPath)
-        }
-    }
-
-    // Now that everything is setup, write the index.html file
-    const filename = `${folder}/${botsIndex ? BOT_INDEX : INDEX}`
-    const docs = new DocsWriter(filename, getPathForType).open()
-
-    // Title should be the current folder name
-    docs.writeHead(
-        titleCase(folder.replace(new RegExp(`\\${path.sep}`, 'g'), '/')),
-        paths.css,
-        paths.defaultCss
-    )
-
-    docs.setMenuSeparator(paths.arrow)
-    buildMenu(docs)
-    docs.writeTitle(
-        titleCase(
-            path
-                .join(filename, '..')
-                .replace(new RegExp(`\\${path.sep}`, 'g'), '/')
-        )
-    )
-
-    if (botsIndex) {
-        docs.writeText(
-            `These are the methods that you may be able to use as a bot. Click <a href="${INDEX}">here</a> to view them all.`
-        )
-    } else {
-        docs.writeText(
-            `Click <a href="${BOT_INDEX}">here</a> to view the methods that you can use as a bot.`
-        )
-    }
-
-    if (namespaces.length) {
-        docs.writeTitle('Namespaces', 3)
-        docs.beginTable(4)
-        namespaces.sort()
-
-        for (const namespace of namespaces) {
-            // For every namespace, also write the index of it
-            const namespacePaths = []
-
-            if (botsIndex) {
-                for (const item of botsIndexPaths) {
-                    if (path.relative(item, '..') === namespace) {
-                        namespacePaths.push(item)
-                    }
-                }
-            }
-
-            generateIndex(namespace, paths, botsIndex, namespacePaths)
-
-            docs.addRow(
-                titleCase(path.parse(namespace).name),
-                `${namespace}/${botsIndex ? BOT_INDEX : INDEX}`
-            )
-        }
-
-        docs.endTable()
-    }
-
-    docs.writeTitle('Available items')
-    docs.beginTable(2)
-
-    files
-        .sort((x, y) => x.localeCompare(y))
-        .forEach((file) => {
-            docs.addRow(findTitle(file), file)
-        })
-
-    docs.endTable()
-    docs.endBody()
-    docs.close()
-}
-
-/**
- * Generates a proper description for the given argument.
- */
-const getDescription = (arg) => {
-    const desc = []
-    let otherwise = false
-
-    if (arg.canBeInferred) {
-        desc.push('If left unspecified, it will be inferred automatically.')
-        otherwise = true
-    } else if (arg.isFlag) {
-        desc.push(
-            'This argument defaults to <code>null</code> and can be omitted.'
-        )
-        otherwise = true
-    }
-
-    if (
-        [
-            'InputPeer',
-            'InputUser',
-            'InputChannel',
-            'InputNotifyPeer',
-            'InputDialogPeer',
-        ].includes(arg.type)
-    ) {
-        desc.push(
-            'Anything entity-like will work if the library can find its <code>Input</code> version (e.g., usernames, <code>Peer</code>, <code>User</code> or <code>Channel</code> objects, etc.).'
-        )
-    }
-
-    if (arg.isVector) {
-        if (arg.isGeneric) {
-            desc.push('A list of other Requests must be supplied.')
-        } else {
-            desc.push('A list must be supplied.')
-        }
-    } else if (arg.isGeneric) {
-        desc.push('A different Request must be supplied for this argument.')
-    } else {
-        otherwise = false // Always reset to false if no other text is added
-    }
-
-    if (otherwise) {
-        desc.splice(1, 0, 'Otherwise,')
-        desc[desc.length - 1] =
-            desc[desc.length - 1].slice(0, -1).toLowerCase() +
-            desc[desc.length - 1].slice(1)
-    }
-
-    return desc
-        .join(' ')
-        .replace(
-            /list/g,
-            '<span class="tooltip" title="Any iterable that supports .length will work too">list</span>'
-        )
-}
-
-/**
- * Copies the src file into dst applying the replacements dict
- */
-const copyReplace = (src, dst, replacements) => {
-    const infile = fs.readFileSync(src, { encoding: 'utf-8' })
-
-    fs.writeFileSync(
-        dst,
-        format(infile, replacements)
-        // infile.replace(
-        //     new RegExp(
-        //         Object.keys(replacements)
-        //             .map(k => escapeRegex(k))
-        //             .join('|')
-        //     ),
-        //     m => replacements[m].toString()
-        // )
-    )
-}
-
-/**
- * Generates the documentation HTML files from from ``scheme.tl``
- * to ``/methods`` and ``/constructors``, etc.
- */
-const writeHtmlPages = (tlobjects, methods, layer, inputRes) => {
-    // Save 'Type: [Constructors]' for use in both:
-    // * Seeing the return type or constructors belonging to the same type.
-    // * Generating the types documentation, showing available constructors.
-    const paths = {
-        '404': '404.html',
-        'css': 'css',
-        'arrow': 'img/arrow.svg',
-        'search.js': 'js/search.js',
-        'indexAll': 'index.html',
-        'botIndex': 'botindex.html',
-        'indexTypes': 'types/index.html',
-        'indexMethods': 'methods/index.html',
-        'indexConstructors': 'constructors/index.html',
-        'defaultCss': 'light',
-    }
-
-    const typeToConstructors = {}
-    const typeToFunctions = {}
-
-    for (const tlobject of tlobjects) {
-        const d = tlobject.isFunction ? typeToFunctions : typeToConstructors
-
-        if (!d[tlobject.innermostResult]) {
-            d[tlobject.innermostResult] = []
-        }
-
-        d[tlobject.innermostResult].push(tlobject)
-    }
-
-    for (const [t, cs] of Object.entries(typeToConstructors)) {
-        typeToConstructors[t] = cs.sort((x, y) => x.name.localeCompare(y.name))
-    }
-
-    methods = methods.reduce((x, m) => ({ ...x, [m.name]: m }), {})
-    const botDocsPath = []
-
-    for (const tlobject of tlobjects) {
-        const filename = getPathFor(tlobject)
-        const docs = new DocsWriter(filename, getPathForType).open()
-        docs.writeHead(tlobject.className, paths.css, paths.defaultCss)
-
-        // Create the menu (path to the current TLObject)
-        docs.setMenuSeparator(paths.arrow)
-        buildMenu(docs)
-
-        // Create the page title
-        docs.writeTitle(tlobject.className)
-
-        if (tlobject.isFunction) {
-            let start
-
-            if (tlobject.usability === Usability.USER) {
-                start = '<strong>Only users</strong> can'
-            } else if (tlobject.usability === Usability.BOT) {
-                botDocsPath.push(filename)
-                start = '<strong>Only bots</strong> can'
-            } else if (tlobject.usability === Usability.BOTH) {
-                botDocsPath.push(filename)
-                start = '<strong>Both users and bots</strong> can'
-            } else {
-                botDocsPath.push(filename)
-                start = 'Both users and bots <strong>may</strong> be able to'
-            }
-
-            docs.writeText(
-                `${start} use this method. <a href="#examples">See code examples.</a>`
-            )
-        }
-
-        // Write the code definition for this TLObject
-        docs.writeCode(tlobject)
-        docs.writeCopyButton(
-            'Copy import to clipboard',
-            getImportCode(tlobject)
-        )
-
-        // Write the return type (or constructors belonging to the same type)
-        docs.writeTitle(tlobject.isFunction ? 'Returns' : 'Belongs to', 3)
-
-        let [genericArg] = tlobject.args
-            .filter((arg) => arg.genericDefinition)
-            .map((arg) => arg.name)
-
-        if (tlobject.result === genericArg) {
-            //  We assume it's a function returning a generic type
-            [genericArg] = tlobject.args
-                .filter((arg) => arg.isGeneric)
-                .map((arg) => arg.name)
-
-            docs.writeText(
-                `This function returns the result of whatever the result from invoking the request passed through <i>${genericArg}</i> is.`
-            )
-        } else {
-            let inner = tlobject.result
-
-            if (/^vector</i.test(tlobject.result)) {
-                docs.writeText('A list of the following type is returned.')
-                inner = tlobject.innermostResult
-            }
-
-            docs.beginTable(1)
-            docs.addRow(inner, getPathForType(inner))
-            docs.endTable()
-
-            const cs = typeToConstructors[inner] || []
-            if (!cs.length) {
-                docs.writeText('This type has no instances available.')
-            } else if (cs.length === 1) {
-                docs.writeText('This type can only be an instance of:')
-            } else {
-                docs.writeText('This type can be an instance of either:')
-            }
-
-            docs.beginTable(2)
-
-            for (const constructor of cs) {
-                const link = getPathFor(constructor)
-                docs.addRow(constructor.className, link)
-            }
-
-            docs.endTable()
-        }
-
-        // Return (or similar types) written. Now parameters/members
-        docs.writeTitle(tlobject.isFunction ? 'Parameters' : 'Members', 3)
-
-        // Sort the arguments in the same way they're sorted
-        // on the generated code (flags go last)
-        const args = tlobject
-            .sortedArgs()
-            .filter((a) => !a.flagIndicator && !a.genericDefinition)
-
-        if (args.length) {
-            // Writing parameters
-            docs.beginTable(3)
-
-            for (const arg of args) {
-                // Name row
-                docs.addRow(arg.name, null, true)
-
-                // Type row
-                const friendlyType = arg.type === 'true' ? 'flag' : arg.type
-                if (arg.isGeneric) {
-                    docs.addRow(`!${friendlyType}`, null, null, 'center')
-                } else {
-                    docs.addRow(
-                        friendlyType,
-                        getPathForType(arg.type),
-                        null,
-                        'center'
-                    )
-                }
-
-                // Add a description for this argument
-                docs.addRow(getDescription(arg))
-            }
-
-            docs.endTable()
-        } else {
-            if (tlobject.isFunction) {
-                docs.writeText('This request takes no input parameters.')
-            } else {
-                docs.writeText('This type has no members.')
-            }
-        }
-
-        if (tlobject.isFunction) {
-            docs.writeTitle('Known RPC errors')
-            const methodInfo = methods[tlobject.fullname]
-            const errors = methodInfo && methodInfo.errors
-
-            if (!errors || !errors.length) {
-                docs.writeText(
-                    'This request can\'t cause any RPC error as far as we know.'
-                )
-            } else {
-                docs.writeText(
-                    `This request can cause ${errors.length} known error${
-                        errors.length === 1 ? '' : 's'
-                    }:`
-                )
-
-                docs.beginTable(2)
-
-                for (const error of errors) {
-                    docs.addRow(`<code>${error.name}</code>`)
-                    docs.addRow(`${error.description}.`)
-                }
-
-                docs.endTable()
-                docs.writeText(
-                    'You can import these from <code>gramjs/errors</code>.'
-                )
-            }
-
-            docs.writeTitle('Example', null, 'examples')
-            if (tlobject.friendly) {
-                const [ns, friendly] = tlobject.friendly
-                docs.writeText(
-                    `Please refer to the documentation of <a href="https://docs.telethon.dev/en/latest/modules/client.html#telethon.client.${ns}.${friendly}"><code>client.${friendly}()</code></a> to learn about the parameters and see several code examples on how to use it.`
-                )
-                docs.writeText(
-                    'The method above is the recommended way to do it. If you need more control over the parameters or want to learn how it is implemented, open the details by clicking on the "Details" text.'
-                )
-                docs.write('<details>')
-            }
-
-            docs.write(`<pre><strong>const</strong> { TelegramClient } <strong>=</strong> require('gramjs');
-<strong>const</strong> { functions, types } <strong>=</strong> require('gramjs/tl');
-
-(<strong>async</strong> () => {
-    <strong>const</strong> client <strong>=</strong> <strong>new</strong> TelegramClient(name, apiId, apiHash);
-    await client.start();
-
-    <strong>const</strong> result <strong>= await</strong> client.invoke(`)
-            tlobject.asExample(docs, 1)
-            docs.write(');\n')
-
-            if (tlobject.result.startsWith('Vector')) {
-                docs.write(
-                    `<strong>for</strong> x <strong>in</strong> result:
-        print(x`
-                )
-            } else {
-                docs.write('    console.log(result')
-                if (
-                    tlobject.result !== 'Bool' &&
-                    !tlobject.result.startsWith('Vector')
-                ) {
-                    docs.write('.stringify()')
-                }
-            }
-
-            docs.write(');\n})();</pre>')
-            if (tlobject.friendly) {
-                docs.write('</details>')
-            }
-
-            const depth = '../'.repeat(tlobject.namespace ? 2 : 1)
-            docs.addScript(`prependPath = "${depth}";`)
-            docs.addScript(null, paths['search.js'])
-            docs.endBody()
-        }
-
-        docs.close()
-    }
-
-    // Find all the available types (which are not the same as the constructors)
-    // Each type has a list of constructors associated to it, hence is a map
-    for (const [t, cs] of Object.entries(typeToConstructors)) {
-        const filename = getPathForType(t)
-        const outDir = path.join(filename, '..')
-
-        if (outDir) {
-            mkdir(outDir)
-        }
-
-        // Since we don't have access to the full TLObject, split the type
-        let name = t
-
-        if (t.includes('.')) {
-            [, name] = t.split('.')
-        }
-
-        const docs = new DocsWriter(filename, getPathForType).open()
-
-        docs.writeHead(snakeToCamelCase(name), paths.css, paths.defaultCss)
-        docs.setMenuSeparator(paths.arrow)
-        buildMenu(docs)
-
-        // Main file title
-        docs.writeTitle(snakeToCamelCase(name))
-
-        // List available constructors for this type
-        docs.writeTitle('Available constructors', 3)
-        if (!cs.length) {
-            docs.writeText('This type has no constructors available.')
-        } else if (cs.length === 1) {
-            docs.writeText('This type has one constructor available.')
-        } else {
-            docs.writeText(
-                `This type has ${cs.length} constructors available.`
-            )
-        }
-
-        docs.beginTable(2)
-
-        for (const constructor of cs) {
-            // Constructor full name
-            const link = getPathFor(constructor)
-            docs.addRow(constructor.className, link)
-        }
-
-        docs.endTable()
-
-        // List all the methods which return this type
-        docs.writeTitle('Methods returning this type', 3)
-        const functions = typeToFunctions[t] || []
-
-        if (!functions.length) {
-            docs.writeText('No method returns this type.')
-        } else if (functions.length === 1) {
-            docs.writeText('Only the following method returns this type.')
-        } else {
-            docs.writeText(
-                `The following ${functions.length} methods return this type as a result.`
-            )
-        }
-
-        docs.beginTable(2)
-
-        for (const func of functions) {
-            const link = getPathFor(func)
-            docs.addRow(func.className, link)
-        }
-
-        docs.endTable()
-
-        // List all the methods which take this type as input
-        docs.writeTitle('Methods accepting this type as input', 3)
-        const otherMethods = tlobjects
-            .filter((u) => u.isFunction && u.args.some((a) => a.type === t))
-            .sort((x, y) => x.name.localeCompare(y.name))
-
-        if (!otherMethods.length) {
-            docs.writeText(
-                'No methods accept this type as an input parameter.'
-            )
-        } else if (otherMethods.length === 1) {
-            docs.writeText('Only this method has a parameter with this type.')
-        } else {
-            docs.writeText(
-                `The following ${otherMethods.length} methods accept this type as an input parameter.`
-            )
-        }
-
-        docs.beginTable(2)
-
-        for (const ot of otherMethods) {
-            const link = getPathFor(ot)
-            docs.addRow(ot.className, link)
-        }
-
-        docs.endTable()
-
-        // List every other type which has this type as a member
-        docs.writeTitle('Other types containing this type', 3)
-        const otherTypes = tlobjects
-            .filter((u) => !u.isFunction && u.args.some((a) => a.type === t))
-            .sort((x, y) => x.name.localeCompare(y.name))
-
-        if (!otherTypes.length) {
-            docs.writeText('No other types have a member of this type.')
-        } else if (otherTypes.length === 1) {
-            docs.writeText(
-                'You can find this type as a member of this other type.'
-            )
-        } else {
-            docs.writeText(
-                `You can find this type as a member of any of the following ${otherTypes.length} types.`
-            )
-        }
-
-        docs.beginTable(2)
-
-        for (const ot of otherTypes) {
-            const link = getPathFor(ot)
-            docs.addRow(ot.className, link)
-        }
-
-        docs.endTable()
-        docs.endBody()
-        docs.close()
-    }
-
-    // After everything's been written, generate an index.html per folder.
-    // This will be done automatically and not taking into account any extra
-    // information that we have available, simply a file listing all the others
-    // accessible by clicking on their title
-    for (const folder of ['types', 'methods', 'constructors']) {
-        generateIndex(folder, paths)
-    }
-
-    generateIndex('methods', paths, true, botDocsPath)
-
-    // Write the final core index, the main index for the rest of files
-    const types = new Set()
-    const methods_ = []
-    const cs = []
-
-    for (const tlobject of tlobjects) {
-        if (tlobject.isFunction) {
-            methods_.push(tlobject)
-        } else {
-            cs.push(tlobject)
-        }
-
-        if (!CORE_TYPES.has(tlobject.result.toLowerCase())) {
-            if (/^vector</i.test(tlobject.result)) {
-                types.add(tlobject.innermostResult)
-            } else {
-                types.add(tlobject.result)
-            }
-        }
-    }
-
-    fs.copyFileSync(`${inputRes}/404.html`, paths['404'])
-    copyReplace(`${inputRes}/core.html`, paths.indexAll, {
-        typeCount: [...types].length,
-        methodCount: methods_.length,
-        constructorCount: tlobjects.length - methods_.length,
-        layer,
-    })
-
-    let fmt = (xs) => {
-        const zs = [] // create an object to hold those which have duplicated keys
-
-        for (const x of xs) {
-            zs[x.className] = x.className in zs
-        }
-
-        return xs
-            .map((x) =>
-                zs[x.className] && x.namespace ?
-                    `"${x.namespace}.${x.className}"` :
-                    `"${x.className}"`
-            )
-            .join(', ')
-    }
-
-    const requestNames = fmt(methods_)
-    const constructorNames = fmt(cs)
-
-    fmt = (xs, formatter) => {
-        return xs
-            .map(
-                (x) =>
-                    `"${formatter(x).replace(
-                        new RegExp(`\\${path.sep}`, 'g'),
-                        '/'
-                    )}"`
-            )
-            .join(', ')
-    }
-
-    const typeNames = fmt([...types], (x) => x)
-
-    const requestUrls = fmt(methods_, getPathFor)
-    const typeUrls = fmt([...types], getPathForType)
-    const constructorUrls = fmt(cs, getPathFor)
-
-    mkdir(path.join(paths['search.js'], '..'))
-    copyReplace(`${inputRes}/js/search.js`, paths['search.js'], {
-        requestNames,
-        typeNames,
-        constructorNames,
-        requestUrls,
-        typeUrls,
-        constructorUrls,
-    })
-}
-
-const copyResources = (resDir) => {
-    for (const [dirname, files] of [
-        ['css', ['docs.light.css', 'docs.dark.css']],
-        ['img', ['arrow.svg']],
-    ]) {
-        mkdir(dirname)
-
-        for (const file of files) {
-            fs.copyFileSync(
-                `${resDir}/${dirname}/${file}`,
-                `${dirname}/${file}`
-            )
-        }
-    }
-}
-
-/**
- * Pre-create the required directory structure.
- */
-const createStructure = (tlobjects) => {
-    const typeNs = new Set()
-    const methodsNs = new Set()
-
-    for (const obj of tlobjects) {
-        if (obj.namespace) {
-            if (obj.isFunction) {
-                methodsNs.add(obj.namespace)
-            } else {
-                typeNs.add(obj.namespace)
-            }
-        }
-    }
-
-    const outputDir = '.'
-    const typeDir = `${outputDir}/types`
-    mkdir(typeDir)
-
-    const consDir = `${outputDir}/constructors`
-    mkdir(consDir)
-
-    for (const ns of typeNs) {
-        mkdir(`${typeDir}/${ns}`)
-        mkdir(`${consDir}/${ns}`)
-    }
-
-    const methDir = `${outputDir}/methods`
-    mkdir(methDir)
-
-    for (const ns of typeNs) {
-        mkdir(`${methDir}/${ns}`)
-    }
-}
-
-const generateDocs = (tlobjects, methodsInfo, layer, inputRes) => {
-    createStructure(tlobjects)
-    writeHtmlPages(tlobjects, methodsInfo, layer, inputRes)
-    copyResources(inputRes)
-}
-
-module.exports = {
-    generateDocs,
-}

+ 0 - 95
gramjs_generator/generators/errors.js

@@ -1,95 +0,0 @@
-const generateErrors = (errors, f) => {
-    // Exact/regex match to create {CODE: ErrorClassName}
-    const exactMatch = []
-    const regexMatch = []
-
-    // Find out what subclasses to import and which to create
-    const importBase = new Set()
-    const createBase = {}
-
-    for (const error of errors) {
-        if (error.subclassExists) {
-            importBase.add(error.subclass)
-        } else {
-            createBase[error.subclass] = error.intCode
-        }
-
-        if (error.hasCaptures) {
-            regexMatch.push(error)
-        } else {
-            exactMatch.push(error)
-        }
-    }
-
-    // Imports and new subclass creation
-    f.write(`const { RPCError, ${[...importBase.values()].join(', ')} } = require('./RPCBaseErrors');`)
-
-    f.write('\nconst format = require(\'string-format\');')
-
-    for (const [cls, intCode] of Object.entries(createBase)) {
-        f.write(`\n\nclass ${cls} extends RPCError {\n    constructor() {\n        this.code = ${intCode};\n    }\n}`)
-    }
-
-    // Error classes generation
-    for (const error of errors) {
-        f.write(`\n\nclass ${error.name} extends ${error.subclass} {\n    constructor(args) {\n        `)
-
-        if (error.hasCaptures) {
-            f.write(`const ${error.captureName} = Number(args.capture || 0);\n        `)
-        }
-
-        const capture = error.description.replace(/'/g, '\\\'')
-
-        if (error.hasCaptures) {
-            f.write(`super(format('${capture}', {${error.captureName}})`)
-            f.write(' + RPCError._fmtRequest(args.request));\n')
-
-            f.write(`this.message = format('${capture}', {${error.captureName}})`)
-            f.write(' + RPCError._fmtRequest(args.request);\n')
-
-        } else {
-            f.write(`super('${capture}'`)
-            f.write(' + RPCError._fmtRequest(args.request));\n')
-
-            f.write(`this.message = '${capture}'`)
-            f.write(' + RPCError._fmtRequest(args.request);\n')
-
-        }
-
-
-        if (error.hasCaptures) {
-            f.write(`        this.${error.captureName} = ${error.captureName};\n`)
-        }
-
-        f.write('    }\n}\n')
-    }
-
-    f.write('\n\nconst rpcErrorsObject = {\n')
-
-    for (const error of exactMatch) {
-        f.write(`    ${error.pattern}: ${error.name},\n`)
-    }
-
-    f.write('};\n\nconst rpcErrorRe = [\n')
-
-    for (const error of regexMatch) {
-        f.write(`    [/${error.pattern}/, ${error.name}],\n`)
-    }
-
-    f.write('];')
-    f.write('module.exports = {')
-    for (const error of regexMatch) {
-        f.write(`     ${error.name},\n`)
-    }
-    for (const error of exactMatch) {
-        f.write(`     ${error.name},\n`)
-    }
-    f.write('     rpcErrorsObject,\n')
-    f.write('     rpcErrorRe,\n')
-
-    f.write('}')
-}
-
-module.exports = {
-    generateErrors,
-}

+ 0 - 10
gramjs_generator/generators/index.js

@@ -1,10 +0,0 @@
-const { generateErrors } = require('./errors')
-const { generateTLObjects, cleanTLObjects } = require('./tlobject')
-const { generateDocs } = require('./docs')
-
-module.exports = {
-    generateErrors,
-    generateTLObjects,
-    cleanTLObjects,
-    generateDocs,
-}

+ 0 - 916
gramjs_generator/generators/tlobject.js

@@ -1,916 +0,0 @@
-const fs = require('fs')
-const util = require('util')
-const { crc32 } = require('crc')
-const SourceBuilder = require('../sourcebuilder')
-const { snakeToCamelCase, variableSnakeToCamelCase } = require('../utils')
-
-const AUTO_GEN_NOTICE = '/*! File generated by TLObjects\' generator. All changes will be ERASED !*/'
-
-const AUTO_CASTS = {
-    InputPeer: 'utils.getInputPeer(await client.getInputEntity(%s))',
-    InputChannel: 'utils.getInputChannel(await client.getInputEntity(%s))',
-    InputUser: 'utils.getInputUser(await client.getInputEntity(%s))',
-    InputDialogPeer: 'await client._getInputDialog(%s)',
-    InputNotifyPeer: 'await client._getInputNotify(%s)',
-    InputMedia: 'utils.getInputMedia(%s)',
-    InputPhoto: 'utils.getInputPhoto(%s)',
-    InputMessage: 'utils.getInputMessage(%s)',
-    InputDocument: 'utils.getInputDocument(%s)',
-    InputChatPhoto: 'utils.getInputChatPhoto(%s)',
-}
-
-const NAMED_AUTO_CASTS = {
-    'chatId,int': 'await client.getPeerId(%s, add_mark=False)',
-}
-
-// Secret chats have a chat_id which may be negative.
-// With the named auto-cast above, we would break it.
-// However there are plenty of other legit requests
-// with `chat_id:int` where it is useful.
-//
-// NOTE: This works because the auto-cast is not recursive.
-//       There are plenty of types that would break if we
-//       did recurse into them to resolve them.
-const NAMED_BLACKLIST = new Set(['messages.discardEncryption'])
-
-// const BASE_TYPES = ['string', 'bytes', 'int', 'long', 'int128', 'int256', 'double', 'Bool', 'true'];
-
-// Patched types {fullname: custom.ns.Name}
-
-// No patches currently
-/**
- const PATCHED_TYPES = {
-    messageEmpty: 'message.Message',
-    message: 'message.Message',
-    messageService: 'message.Message',
-};*/
-const PATCHED_TYPES = {}
-
-const writeModules = (outDir, depth, kind, namespaceTlobjects, typeConstructors) => {
-    // namespace_tlobjects: {'namespace', [TLObject]}
-    fs.mkdirSync(outDir, { recursive: true })
-
-    for (const [ns, tlobjects] of Object.entries(namespaceTlobjects)) {
-        const file = `${outDir}/${ns === 'null' ? 'index' : ns}.js`
-        const stream = fs.createWriteStream(file)
-        const builder = new SourceBuilder(stream)
-        const dotDepth = '.'.repeat(depth || 1)
-
-        builder.writeln(AUTO_GEN_NOTICE)
-        builder.writeln(`const { TLObject } = require('${dotDepth}/tlobject');`)
-
-        if (kind !== 'TLObject') {
-            builder.writeln(`const { ${kind} } = require('${dotDepth}/tlobject');`)
-        }
-
-        // Add the relative imports to the namespaces,
-        // unless we already are in a namespace.
-        if (!ns) {
-            const imports = Object.keys(namespaceTlobjects)
-                .filter(Boolean)
-                .join(`, `)
-
-            builder.writeln(`const { ${imports} } = require('.');`)
-        }
-
-        // Import struct for the .__bytes__(self) serialization
-        builder.writeln('const struct = require(\'python-struct\');')
-        builder.writeln(`const { readBigIntFromBuffer, 
-        readBufferFromBigInt, generateRandomBytes } = require('../../Helpers')`)
-
-        const typeNames = new Set()
-        const typeDefs = []
-        /*
-        // Find all the types in this file and generate type definitions
-        // based on the types. The type definitions are written to the
-        // file at the end.
-        for (const t of tlobjects) {
-            if (!t.isFunction) {
-                let typeName = t.result;
-
-                if (typeName.includes('.')) {
-                    typeName = typeName.slice(typeName.lastIndexOf('.'));
-                }
-
-                if (typeNames.has(typeName)) {
-                    continue;
-                }
-
-                typeNames.add(typeName);
-
-                const constructors = typeConstructors[typeName];
-
-                if (!constructors) {
-                } else if (constructors.length === 1) {
-                    typeDefs.push(
-                        `Type${typeName} = ${constructors[0].className}`
-                    );
-                } else {
-                    typeDefs.push(
-                        `Type${typeName} = Union[${constructors
-                            .map(x => constructors.className)
-                            .join(',')}]`
-                    );
-                }
-            }
-        }*/
-
-        const imports = {}
-        const primitives = new Set(['int', 'long', 'int128', 'int256', 'double', 'string', 'bytes', 'Bool', 'true'])
-
-        // Find all the types in other files that are used in this file
-        // and generate the information required to import those types.
-        for (const t of tlobjects) {
-            for (const arg of t.args) {
-                let name = arg.type
-
-                if (!name || primitives.has(name)) {
-                    continue
-                }
-
-                let importSpace = `${dotDepth}/tl/types`
-
-                if (name.includes('.')) {
-                    const [namespace] = name.split('.')
-                    name = name.split('.')
-                    importSpace += `/${namespace}`
-                }
-
-                if (!typeNames.has(name)) {
-                    typeNames.add(name)
-
-                    if (name === 'date') {
-                        imports.datetime = ['datetime']
-                        continue
-                    } else if (!(importSpace in imports)) {
-                        imports[importSpace] = new Set()
-                    }
-
-                    imports[importSpace].add(`Type${name}`)
-                }
-            }
-        }
-
-        // Add imports required for type checking
-        /**
-         if (imports) {
-            builder.writeln('if (false) { // TYPE_CHECKING {');
-
-            for (const [namespace, names] of Object.entries(imports)) {
-                builder.writeln(
-                    `const { ${[...names.values()].join(
-                        ', '
-                    )} } =  require('${namespace}');`
-                );
-            }
-
-            builder.endBlock();
-        }*/
-
-        // Generate the class for every TLObject
-        for (const t of tlobjects) {
-            if (t.fullname in PATCHED_TYPES) {
-                builder.writeln(`const ${t.className} = null; // Patched`)
-            } else {
-                writeSourceCode(t, kind, builder, typeConstructors)
-                builder.currentIndent = 0
-            }
-        }
-
-        // Write the type definitions generated earlier.
-        builder.writeln()
-
-        for (const line of typeDefs) {
-            builder.writeln(line)
-        }
-        writeModuleExports(tlobjects, builder)
-        if (file.indexOf('index.js') > 0) {
-            for (const [ns] of Object.entries(namespaceTlobjects)) {
-                if (ns !== 'null') {
-                    builder.writeln('let %s = require(\'./%s\');', ns, ns)
-                }
-            }
-            for (const [ns] of Object.entries(namespaceTlobjects)) {
-                if (ns !== 'null') {
-                    builder.writeln('module.exports.%s = %s;', ns, ns)
-                }
-            }
-        }
-    }
-}
-
-const writeReadResult = (tlobject, builder) => {
-    // Only requests can have a different response that's not their
-    // serialized body, that is, we'll be setting their .result.
-    //
-    // The default behaviour is reading a TLObject too, so no need
-    // to override it unless necessary.
-    if (!tlobject.isFunction) {
-        return
-    }
-
-    // https://core.telegram.org/mtproto/serialize#boxed-and-bare-types
-    // TL;DR; boxed types start with uppercase always, so we can use
-    // this to check whether everything in it is boxed or not.
-    //
-    // Currently only un-boxed responses are Vector<int>/Vector<long>.
-    // If this weren't the case, we should check upper case after
-    // max(index('<'), index('.')) (and if it is, it's boxed, so return).
-    const m = tlobject.result.match(/Vector<(int|long)>/)
-    if (!m) {
-        return
-    }
-
-    // builder.endBlock();
-    builder.writeln('readResult(reader){')
-    builder.writeln('reader.readInt();  // Vector ID')
-    builder.writeln('let temp = [];')
-    builder.writeln('let len = reader.readInt(); //fix this')
-    builder.writeln('for (let i=0;i<len;i++){')
-    const read = m[1][0].toUpperCase() + m[1].slice(1)
-    builder.writeln('temp.push(reader.read%s())', read)
-    builder.endBlock()
-    builder.writeln('return temp')
-    builder.endBlock()
-}
-
-/**
- * Writes the source code corresponding to the given TLObject
- * by making use of the ``builder`` `SourceBuilder`.
- *
- * Additional information such as file path depth and
- * the ``Type: [Constructors]`` must be given for proper
- * importing and documentation strings.
- */
-const writeSourceCode = (tlobject, kind, builder, typeConstructors) => {
-    writeClassConstructor(tlobject, kind, typeConstructors, builder)
-    writeResolve(tlobject, builder)
-    // writeToJson(tlobject, builder);
-    writeToBytes(tlobject, builder)
-    builder.currentIndent--
-    writeFromReader(tlobject, builder)
-    writeReadResult(tlobject, builder)
-    builder.currentIndent--
-    builder.writeln('}')
-}
-
-const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
-    builder.writeln()
-    builder.writeln()
-    builder.writeln(`class ${tlobject.className} extends ${kind} {`)
-    builder.writeln(`static CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
-    builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)
-    builder.writeln()
-    // Write the __init__ function if it has any argument
-    if (!tlobject.realArgs.length) {
-        builder.writeln(`constructor() {`)
-        builder.writeln(`super();`)
-        builder.writeln(`this.CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
-        builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)
-
-        builder.writeln()
-        builder.currentIndent--
-        builder.writeln('}')
-        return
-    }
-
-    // Note : this is needed to be able to access them
-    // with or without an instance
-
-
-    builder.writeln('/**')
-
-    if (tlobject.isFunction) {
-        builder.write(`:returns ${tlobject.result}: `)
-    } else {
-        builder.write(`Constructor for ${tlobject.result}: `)
-    }
-
-    const constructors = typeConstructors[tlobject.result]
-
-    if (!constructors) {
-        builder.writeln('This type has no constructors.')
-    } else if (constructors.length === 1) {
-        builder.writeln(`Instance of ${constructors[0].className}`)
-    } else {
-        builder.writeln(`Instance of either ${constructors.map((c) => c.className).join(', ')}`)
-    }
-
-    builder.writeln('*/')
-    builder.writeln(`constructor(args) {`)
-    builder.writeln(`super();`)
-    builder.writeln(`args = args || {}`)
-    // Class-level variable to store its Telegram's constructor ID
-    builder.writeln(`this.CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
-    builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)
-
-    builder.writeln()
-
-    // Set the arguments
-    for (const arg of tlobject.realArgs) {
-        if (!arg.canBeInferred) {
-            builder.writeln(
-                `this.${variableSnakeToCamelCase(arg.name)} = args.${variableSnakeToCamelCase(
-                    arg.name,
-                )}${arg.isFlag || arg.canBeInferred ? ' || null' : ''};`,
-            )
-
-            // Currently the only argument that can be
-            // inferred are those called 'random_id'
-        } else if (arg.name === 'random_id') {
-            // Endianness doesn't really matter, and 'big' is shorter
-            let code = `readBigIntFromBuffer(generateRandomBytes(${
-                arg.type === 'long' ? 8 : 4
-            }),false,true)`
-
-            if (arg.isVector) {
-                // Currently for the case of "messages.forwardMessages"
-                // Ensure we can infer the length from id:Vector<>
-                if (!tlobject.realArgs.find((a) => a.name === 'id').isVector) {
-                    throw new Error(`Cannot infer list of random ids for ${tlobject}`)
-                }
-
-                code = `new Array(id.length).fill().map(_ => ${code})`
-            }
-
-            builder.writeln(`this.randomId = args.randomId !== undefined ? args.randomId : ${code};`)
-        } else {
-            throw new Error(`Cannot infer a value for ${arg}`)
-        }
-    }
-
-    builder.endBlock()
-}
-
-const writeResolve = (tlobject, builder) => {
-    if (
-        tlobject.isFunction &&
-        tlobject.realArgs.some(
-            (arg) =>
-                arg.type in AUTO_CASTS ||
-                (`${arg.name},${arg.type}` in NAMED_AUTO_CASTS && !NAMED_BLACKLIST.has(tlobject.fullname)),
-        )
-    ) {
-        builder.writeln('async resolve(client, utils) {')
-
-        for (const arg of tlobject.realArgs) {
-            let ac = AUTO_CASTS[arg.type]
-
-            if (!ac) {
-                ac = NAMED_AUTO_CASTS[`${variableSnakeToCamelCase(arg.name)},${arg.type}`]
-
-                if (!ac) {
-                    continue
-                }
-            }
-
-            if (arg.isFlag) {
-                builder.writeln(`if (this.${variableSnakeToCamelCase(arg.name)}) {`)
-            }
-
-            if (arg.isVector) {
-                builder.write(`const _tmp = [];`)
-                builder.writeln(`for (const _x of this.${variableSnakeToCamelCase(arg.name)}) {`)
-                builder.writeln(`_tmp.push(%s);`, util.format(ac, '_x'))
-                builder.endBlock()
-                builder.writeln(`this.${variableSnakeToCamelCase(arg.name)} = _tmp;`)
-            } else {
-                builder.writeln(`this.${arg.name} = %s`,
-                    util.format(ac, `this.${variableSnakeToCamelCase(arg.name)}`))
-            }
-
-            if (arg.isFlag) {
-                builder.currentIndent--
-                builder.writeln('}')
-            }
-        }
-
-        builder.endBlock()
-    }
-}
-/**
- const writeToJson = (tlobject, builder) => {
-    builder.writeln('toJson() {');
-    builder.writeln('return {');
-
-    builder.write("_: '%s'", tlobject.className);
-
-    for (const arg of tlobject.realArgs) {
-        builder.writeln(',');
-        builder.write('%s: ', arg.name);
-
-        if (BASE_TYPES.includes(arg.type)) {
-            if (arg.isVector) {
-                builder.write(
-                    'this.%s === null ? [] : this.%s.slice()',
-                    arg.name,
-                    arg.name
-                );
-            } else {
-                builder.write('this.%s', arg.name);
-            }
-        } else {
-            if (arg.isVector) {
-                builder.write(
-                    'this.%s === null ? [] : this.%s.map(x => x instanceof TLObject ? x.toJson() : x)',
-                    arg.name,
-                    arg.name
-                );
-            } else {
-                builder.write(
-                    'this.%s instanceof TLObject ? this.%s.toJson() : this.%s',
-                    arg.name,
-                    arg.name,
-                    arg.name
-                );
-            }
-        }
-    }
-
-    builder.writeln();
-    builder.endBlock();
-    builder.currentIndent--;
-    builder.writeln('}');
-};
- */
-const writeToBytes = (tlobject, builder) => {
-    builder.writeln('getBytes() {')
-
-    // Some objects require more than one flag parameter to be set
-    // at the same time. In this case, add an assertion.
-    const repeatedArgs = {}
-    for (const arg of tlobject.args) {
-        if (arg.isFlag) {
-            if (!repeatedArgs[arg.flagIndex]) {
-                repeatedArgs[arg.flagIndex] = []
-            }
-            repeatedArgs[arg.flagIndex].push(arg)
-        }
-    }
-
-    for (const ra of Object.values(repeatedArgs)) {
-        if (ra.length > 1) {
-            const cnd1 = []
-            const cnd2 = []
-            const names = []
-
-            for (const a of ra) {
-                cnd1.push(`this.${a.name} || this.${a.name}!==null`)
-                cnd2.push(`this.${a.name}===null || this.${a.name}===false`)
-                names.push(a.name)
-            }
-            builder.writeln(
-                'if (!((%s) && (%s)))\n\t throw new Error(\'%s paramaters must all be false-y or all true\')',
-                cnd1.join(' && '),
-                cnd2.join(' && '),
-                names.join(', '),
-            )
-        }
-    }
-    builder.writeln('return Buffer.concat([')
-    builder.currentIndent++
-    const b = Buffer.alloc(4)
-    b.writeUInt32LE(tlobject.id, 0)
-    // First constructor code, we already know its bytes
-    builder.writeln('Buffer.from("%s","hex"),', b.toString('hex'))
-    for (const arg of tlobject.args) {
-        if (writeArgToBytes(builder, arg, tlobject.args)) {
-            builder.writeln(',')
-        }
-    }
-    builder.writeln('])')
-    builder.endBlock()
-}
-
-// writeFromReader
-const writeFromReader = (tlobject, builder) => {
-    builder.writeln('static fromReader(reader) {')
-    for (const arg of tlobject.args) {
-        if (arg.name !== 'flag') {
-            if (arg.name !== 'x') {
-                builder.writeln('let %s', '_' + arg.name + ';')
-            }
-        }
-    }
-
-    // TODO fix this really
-    builder.writeln('let _x;')
-    builder.writeln('let len;')
-
-    for (const arg of tlobject.args) {
-        writeArgReadCode(builder, arg, tlobject.args, '_' + arg.name)
-    }
-    const temp = []
-    for (const a of tlobject.realArgs) {
-        temp.push(`${variableSnakeToCamelCase(a.name)}:_${a.name}`)
-    }
-    builder.writeln('return new this({%s})', temp.join(',\n\t'))
-    builder.endBlock()
-}
-// writeReadResult
-
-/**
- * Writes the .__bytes__() code for the given argument
- * @param builder: The source code builder
- * @param arg: The argument to write
- * @param args: All the other arguments in TLObject same __bytes__.
- *              This is required to determine the flags value
- * @param name: The name of the argument. Defaults to "self.argname"
- *              This argument is an option because it's required when
- *              writing Vectors<>
- */
-const writeArgToBytes = (builder, arg, args, name = null) => {
-    if (arg.genericDefinition) {
-        return // Do nothing, this only specifies a later type
-    }
-
-    if (name === null) {
-        name = `this.${arg.name}`
-    }
-
-    name = variableSnakeToCamelCase(name)
-    // The argument may be a flag, only write if it's not None AND
-    // if it's not a True type.
-    // True types are not actually sent, but instead only used to
-    // determine the flags.
-    if (arg.isFlag) {
-        if (arg.type === 'true') {
-            return // Exit, since true type is never written
-        } else if (arg.isVector) {
-            // Vector flags are special since they consist of 3 values,
-            // so we need an extra join here. Note that empty vector flags
-            // should NOT be sent either!
-            builder.write(
-                '(%s === undefined || %s === false || %s ===null) ? Buffer.alloc(0) :Buffer.concat([',
-                name,
-                name,
-                name,
-            )
-        } else {
-            builder.write('(%s === undefined || %s === false || %s ===null) ? Buffer.alloc(0) : [', name, name, name)
-        }
-    }
-
-    if (arg.isVector) {
-        if (arg.useVectorId) {
-            builder.write('Buffer.from(\'15c4b51c\', \'hex\'),')
-        }
-
-        builder.write('struct.pack(\'<i\', %s.length),', name)
-
-        // Cannot unpack the values for the outer tuple through *[(
-        // since that's a Python >3.5 feature, so add another join.
-        builder.write('Buffer.concat(%s.map(x => ', name)
-        // Temporary disable .is_vector, not to enter this if again
-        // Also disable .is_flag since it's not needed per element
-        const oldFlag = arg.isFlag
-        arg.isVector = arg.isFlag = false
-        writeArgToBytes(builder, arg, args, 'x')
-        arg.isVector = true
-        arg.isFlag = oldFlag
-
-        builder.write('))')
-    } else if (arg.flagIndicator) {
-        // Calculate the flags with those items which are not None
-        if (!args.some((f) => f.isFlag)) {
-            // There's a flag indicator, but no flag arguments so it's 0
-            builder.write('Buffer.alloc(4)')
-        } else {
-            builder.write('struct.pack(\'<I\', ')
-            builder.write(
-                args
-                    .filter((flag) => flag.isFlag)
-                    .map(
-                        (flag) =>
-                            `(this.${variableSnakeToCamelCase(
-                                flag.name,
-                            )} === undefined || this.${variableSnakeToCamelCase(
-                                flag.name,
-                            )} === false || this.${variableSnakeToCamelCase(flag.name)} === null) ? 0 : ${1 <<
-                            flag.flagIndex}`,
-                    )
-                    .join(' | '),
-            )
-            builder.write(')')
-        }
-    } else if (arg.type === 'int') {
-        builder.write('struct.pack(\'<i\', %s)', name)
-    } else if (arg.type === 'long') {
-        builder.write('readBufferFromBigInt(%s,8,true,true)', name)
-    } else if (arg.type === 'int128') {
-        builder.write('readBufferFromBigInt(%s,16,true,true)', name)
-    } else if (arg.type === 'int256') {
-        builder.write('readBufferFromBigInt(%s,32,true,true)', name)
-    } else if (arg.type === 'double') {
-        builder.write('struct.pack(\'<d\', %s.toString())', name)
-    } else if (arg.type === 'string') {
-        builder.write('TLObject.serializeBytes(%s)', name)
-    } else if (arg.type === 'Bool') {
-        builder.write('%s ? 0xb5757299 : 0x379779bc', name)
-    } else if (arg.type === 'true') {
-        // These are actually NOT written! Only used for flags
-    } else if (arg.type === 'bytes') {
-        builder.write('TLObject.serializeBytes(%s)', name)
-    } else if (arg.type === 'date') {
-        builder.write('TLObject.serializeDatetime(%s)', name)
-    } else {
-        // Else it may be a custom type
-        builder.write('%s.getBytes()', name)
-
-        // If the type is not boxed (i.e. starts with lowercase) we should
-        // not serialize the constructor ID (so remove its first 4 bytes).
-        let boxed = arg.type.charAt(arg.type.indexOf('.') + 1)
-        boxed = boxed === boxed.toUpperCase()
-
-        if (!boxed) {
-            builder.write('.slice(4)')
-        }
-    }
-
-    if (arg.isFlag) {
-        builder.write(']')
-
-        if (arg.isVector) {
-            builder.write(')')
-        }
-    }
-
-    return true
-}
-
-/**
- * Writes the read code for the given argument, setting the
- * arg.name variable to its read value.
- * @param builder The source code builder
- * @param arg The argument to write
- * @param args All the other arguments in TLObject same on_send.
- * This is required to determine the flags value
- * @param name The name of the argument. Defaults to "self.argname"
- * This argument is an option because it's required when
- * writing Vectors<>
- */
-const writeArgReadCode = (builder, arg, args, name) => {
-    if (arg.genericDefinition) {
-        return // Do nothing, this only specifies a later type
-    }
-    // The argument may be a flag, only write that flag was given!
-    let wasFlag = false
-    if (arg.isFlag) {
-        // Treat 'true' flags as a special case, since they're true if
-        // they're set, and nothing else needs to actually be read.
-        if (arg.type === 'true') {
-            builder.writeln('%s = Boolean(flags & %s);', name, 1 << arg.flagIndex)
-            return
-        }
-
-        wasFlag = true
-        builder.writeln('if (flags & %s) {', 1 << arg.flagIndex)
-        // Temporary disable .is_flag not to enter this if
-        // again when calling the method recursively
-        arg.isFlag = false
-    }
-
-    if (arg.isVector) {
-        if (arg.useVectorId) {
-            // We have to read the vector's constructor ID
-            builder.writeln('reader.readInt();')
-        }
-
-        builder.writeln('%s = [];', name)
-        builder.writeln('len = reader.readInt();')
-        builder.writeln('for (let i=0;i<len;i++){')
-
-        // Temporary disable .is_vector, not to enter this if again
-        arg.isVector = false
-        writeArgReadCode(builder, arg, args, '_x')
-        builder.writeln('%s.push(_x);', name)
-        arg.isVector = true
-    } else if (arg.flagIndicator) {
-        // Read the flags, which will indicate what items we should read next
-        builder.writeln('let flags = reader.readInt();')
-        builder.writeln()
-    } else if (arg.type === 'int') {
-        builder.writeln('%s = reader.readInt();', name)
-    } else if (arg.type === 'long') {
-        builder.writeln('%s = reader.readLong();', name)
-    } else if (arg.type === 'int128') {
-        builder.writeln('%s = reader.readLargeInt(128);', name)
-    } else if (arg.type === 'int256') {
-        builder.writeln('%s = reader.readLargeInt(256);', name)
-    } else if (arg.type === 'double') {
-        builder.writeln('%s = reader.readDouble();', name)
-    } else if (arg.type === 'string') {
-        builder.writeln('%s = reader.tgReadString();', name)
-    } else if (arg.type === 'Bool') {
-        builder.writeln('%s = reader.tgReadBool();', name)
-    } else if (arg.type === 'true') {
-        builder.writeln('%s = true;', name)
-    } else if (arg.type === 'bytes') {
-        builder.writeln('%s = reader.tgReadBytes();', name)
-    } else if (arg.type === 'date') {
-        builder.writeln('%s = reader.tgReadDate();', name)
-    } else {
-        // Else it may be a custom type
-        if (!arg.skipConstructorId) {
-            builder.writeln('%s = reader.tgReadObject();', name)
-        } else {
-            // Import the correct type inline to avoid cyclic imports.
-            // There may be better solutions so that we can just access
-            // all the types before the files have been parsed, but I
-            // don't know of any.
-            const sepIndex = arg.type.indexOf('.')
-            let ns
-            let t
-
-            if (sepIndex === -1) {
-                ns = '.'
-                t = arg.type
-            } else {
-                ns = '.' + arg.type.slice(0, sepIndex)
-                t = arg.type.slice(sepIndex + 1)
-            }
-
-            const className = snakeToCamelCase(t)
-
-            // There would be no need to import the type if we're in the
-            // file with the same namespace, but since it does no harm
-            // and we don't have information about such thing in the
-            // method we just ignore that case.
-            builder.writeln('let %s = require("%s");', className, ns)
-            builder.writeln('%s = %s.fromReader(reader);', name, className)
-        }
-    }
-
-    // End vector and flag blocks if required (if we opened them before)
-    if (arg.isVector) {
-        builder.writeln('}')
-    }
-
-    if (wasFlag) {
-        builder.endBlock()
-        builder.writeln('else {')
-        builder.writeln('%s = null', name)
-        builder.endBlock()
-        // Restore .isFlag;
-        arg.isFlag = true
-    }
-}
-
-const writePatched = (outDir, namespaceTlobjects) => {
-    fs.mkdirSync(outDir, { recursive: true })
-
-    for (const [ns, tlobjects] of Object.entries(namespaceTlobjects)) {
-        const file = `${outDir}/${ns === 'null' ? 'index' : ns}.js`
-        const stream = fs.createWriteStream(file)
-        const builder = new SourceBuilder(stream)
-
-        builder.writeln(AUTO_GEN_NOTICE)
-        builder.writeln('const struct = require(\'python-struct\');')
-        builder.writeln(`const { TLObject, types, custom } = require('..');`)
-
-        builder.writeln()
-
-        for (const t of tlobjects) {
-            builder.writeln('class %s extends custom.%s {', t.className, PATCHED_TYPES[t.fullname])
-            builder.writeln(`static CONSTRUCTOR_ID = 0x${t.id.toString(16)}`)
-            builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(t.result).toString('16')}`)
-            builder.writeln()
-            builder.writeln('constructor() {')
-            builder.writeln('super();')
-            builder.writeln(`this.CONSTRUCTOR_ID = 0x${t.id.toString(16)}`)
-            builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(t.result).toString('16')}`)
-
-            builder.endBlock()
-
-            // writeToJson(t, builder);
-            writeToBytes(t, builder)
-            writeFromReader(t, builder)
-
-            builder.writeln()
-            builder.endBlock()
-            builder.currentIndent = 0
-            builder.writeln('types.%s%s = %s', t.namespace ? `${t.namespace}.` : '', t.className, t.className)
-            builder.writeln()
-        }
-    }
-}
-
-const writeAllTLObjects = (tlobjects, layer, builder) => {
-    builder.writeln(AUTO_GEN_NOTICE)
-    builder.writeln()
-
-    builder.writeln('const { types, functions, patched } = require(\'.\');')
-    builder.writeln()
-
-    // Create a constant variable to indicate which layer this is
-    builder.writeln(`const LAYER = %s;`, layer)
-    builder.writeln()
-
-    // Then create the dictionary containing constructor_id: class
-    builder.writeln('const tlobjects = {')
-
-    // Fill the dictionary (0x1a2b3c4f: tl.full.type.path.Class)
-    for (const tlobject of tlobjects) {
-        builder.write('0x0%s: ', tlobject.id.toString(16).padStart(8, '0'))
-
-        if (tlobject.fullname in PATCHED_TYPES) {
-            builder.write('patched')
-        } else {
-            builder.write(tlobject.isFunction ? 'functions' : 'types')
-        }
-
-        if (tlobject.namespace) {
-            builder.write('.%s', tlobject.namespace)
-        }
-
-        builder.writeln('.%s,', tlobject.className)
-    }
-
-    builder.endBlock(true)
-    builder.writeln('')
-    builder.writeln('module.exports = {')
-    builder.writeln('LAYER,')
-    builder.writeln('tlobjects')
-    builder.endBlock(true)
-}
-
-const generateTLObjects = (tlobjects, layer, importDepth, outputDir) => {
-    // Group everything by {namespace :[tlobjects]} to generate index.js
-    const namespaceFunctions = {}
-    const namespaceTypes = {}
-    const namespacePatched = {}
-
-    // Group {type: [constructors]} to generate the documentation
-    const typeConstructors = {}
-
-    for (const tlobject of tlobjects) {
-        if (tlobject.isFunction) {
-            if (!namespaceFunctions[tlobject.namespace]) {
-                namespaceFunctions[tlobject.namespace] = []
-            }
-
-            namespaceFunctions[tlobject.namespace].push(tlobject)
-        } else {
-            if (!namespaceTypes[tlobject.namespace]) {
-                namespaceTypes[tlobject.namespace] = []
-            }
-
-            if (!typeConstructors[tlobject.result]) {
-                typeConstructors[tlobject.result] = []
-            }
-
-            namespaceTypes[tlobject.namespace].push(tlobject)
-            typeConstructors[tlobject.result].push(tlobject)
-
-            if (tlobject.fullname in PATCHED_TYPES) {
-                if (!namespacePatched[tlobject.namespace]) {
-                    namespacePatched[tlobject.namespace] = []
-                }
-
-                namespacePatched[tlobject.namespace].push(tlobject)
-            }
-        }
-    }
-
-    writeModules(`${outputDir}/functions`, importDepth, 'TLRequest', namespaceFunctions, typeConstructors)
-    writeModules(`${outputDir}/types`, importDepth, 'TLObject', namespaceTypes, typeConstructors)
-    writePatched(`${outputDir}/patched`, namespacePatched)
-
-    const filename = `${outputDir}/AllTLObjects.js`
-    const stream = fs.createWriteStream(filename)
-    const builder = new SourceBuilder(stream)
-
-    writeAllTLObjects(tlobjects, layer, builder)
-}
-
-const cleanTLObjects = (outputDir) => {
-    for (let d of ['functions', 'types', 'patched']) {
-        d = `${outputDir}/d`
-
-        if (fs.statSync(d).isDirectory()) {
-            fs.rmdirSync(d)
-        }
-    }
-
-    const tl = `${outputDir}/AllTLObjects.js`
-
-    if (fs.statSync(tl).isFile()) {
-        fs.unlinkSync(tl)
-    }
-}
-
-const writeModuleExports = (tlobjects, builder) => {
-    builder.writeln('module.exports = {')
-
-    for (const t of tlobjects) {
-        builder.writeln(`${t.className},`)
-    }
-
-    builder.currentIndent--
-    builder.writeln('};')
-}
-
-module.exports = {
-    generateTLObjects,
-    cleanTLObjects,
-}

+ 0 - 92
gramjs_generator/parsers/errors.js

@@ -1,92 +0,0 @@
-const fs = require('fs')
-const csvParse = require('csv-parse/lib/sync')
-const { snakeToCamelCase, variableSnakeToCamelCase } = require('../utils')
-
-const KNOWN_BASE_CLASSES = {
-    303: 'InvalidDCError',
-    400: 'BadRequestError',
-    401: 'UnauthorizedError',
-    403: 'ForbiddenError',
-    404: 'NotFoundError',
-    406: 'AuthKeyError',
-    420: 'FloodError',
-    500: 'ServerError',
-    503: 'TimedOutError',
-}
-
-/**
- * Gets the corresponding class name for the given error code,
- * this either being an integer (thus base error name) or str.
- */
-const getClassName = (errorCode) => {
-    if (typeof errorCode === 'number') {
-        return KNOWN_BASE_CLASSES[Math.abs(errorCode)] || 'RPCError' + errorCode.toString().replace('-', 'Neg')
-    }
-
-    return snakeToCamelCase(
-        errorCode
-            .replace('FIRSTNAME', 'FIRST_NAME')
-            .replace('SLOWMODE', 'SLOW_MODE')
-            .toLowerCase(),
-        'Error',
-    )
-}
-
-class TelegramError {
-    constructor(codes, name, description) {
-        // TODO Some errors have the same name but different integer codes
-        // Should these be split into different files or doesn't really matter?
-        // Telegram isn't exactly consistent with returned errors anyway.
-        [this.intCode] = codes
-        this.stringCode = name
-        this.subclass = getClassName(codes[0])
-        this.subclassExists = Math.abs(codes[0]) in KNOWN_BASE_CLASSES
-        this.description = description
-        this.hasCaptures = name.includes('_X')
-
-        if (this.hasCaptures) {
-            this.name = variableSnakeToCamelCase(getClassName(name.replace('_X', '')))
-            this.pattern = variableSnakeToCamelCase(name.replace('_X', '_(\\d+)'))
-            this.captureName = variableSnakeToCamelCase(description.match(/{(\w+)}/)[1])
-        } else {
-            this.name = variableSnakeToCamelCase(getClassName(name))
-            this.pattern = variableSnakeToCamelCase(name)
-            this.captureName = null
-        }
-    }
-}
-
-/**
- * Parses the input CSV file with columns (name, error codes, description)
- * and yields `Error` instances as a result.
- */
-const parseErrors = function* (csvFile) {
-    const f = csvParse(fs.readFileSync(csvFile, { encoding: 'utf-8' })).slice(1)
-
-    for (let line = 0; line < f.length; line++) {
-        if (f[line].length !== 3) {
-            throw new Error(`Columns count mismatch, unquoted comma in desc? (line ${line + 2})`)
-        }
-
-        let [name, codes, description] = f[line]
-
-        codes =
-            codes === '' ?
-                [400] :
-                codes.split(' ').map((x) => {
-                    if (isNaN(x)) {
-                        throw new Error(`Not all codes are integers (line ${line + 2})`)
-                    }
-
-                    return Number(x)
-                })
-
-        yield new TelegramError(codes, name, description)
-    }
-}
-
-module.exports = {
-    KNOWN_BASE_CLASSES,
-    TelegramError,
-    parseErrors,
-}

+ 0 - 14
gramjs_generator/parsers/index.js

@@ -1,14 +0,0 @@
-const { TelegramError, parseErrors } = require('./errors')
-const { MethodInfo, Usability, parseMethods } = require('./methods')
-const { TLObject, parseTl, findLayer } = require('./tlobject')
-
-module.exports = {
-    TelegramError,
-    parseErrors,
-    MethodInfo,
-    Usability,
-    parseMethods,
-    TLObject,
-    parseTl,
-    findLayer,
-}

+ 0 - 65
gramjs_generator/parsers/methods.js

@@ -1,65 +0,0 @@
-const fs = require('fs')
-const csvParse = require('csv-parse/lib/sync')
-
-const Usability = {
-    UNKNOWN: 0,
-    USER: 1,
-    BOT: 2,
-    BOTH: 4,
-}
-
-class MethodInfo {
-    constructor(name, usability, errors, friendly) {
-        this.name = name
-        this.errors = errors
-        this.friendly = friendly
-
-        if (usability.toUpperCase() in Usability) {
-            this.usability = Usability[usability.toUpperCase()]
-        } else {
-            throw new Error(`Usability must be either user, bot, both or unknown, not ${usability}`)
-        }
-    }
-}
-
-/**
- * Parses the input CSV file with columns (method, usability, errors)
- * and yields `MethodInfo` instances as a result.
- */
-const parseMethods = function* (csvFile, friendlyCsvFile, errorsDict) {
-    const rawToFriendly = {}
-    const f1 = csvParse(fs.readFileSync(friendlyCsvFile, { encoding: 'utf-8' }))
-
-    for (const [ns, friendly, rawList] of f1.slice(1)) {
-        for (const raw of rawList.split(' ')) {
-            rawToFriendly[raw] = [ns, friendly]
-        }
-    }
-
-    const f2 = csvParse(fs.readFileSync(csvFile, { encoding: 'utf-8' })).slice(1)
-
-    for (let line = 0; line < f2.length; line++) {
-        let [method, usability, errors] = f2[line]
-
-        errors = errors
-            .split(' ')
-            .filter(Boolean)
-            .map((x) => {
-                if (x && !(x in errorsDict)) {
-                    throw new Error(`Method ${method} references unknown errors ${errors}`)
-                }
-
-                return errorsDict[x]
-            })
-
-        const friendly = rawToFriendly[method]
-        delete rawToFriendly[method]
-        yield new MethodInfo(method, usability, errors, friendly)
-    }
-}
-
-module.exports = {
-    Usability,
-    MethodInfo,
-    parseMethods,
-}

+ 0 - 10
gramjs_generator/parsers/tlobject/index.js

@@ -1,10 +0,0 @@
-const { TLArg } = require('./tlarg')
-const { TLObject } = require('./tlobject')
-const { parseTl, findLayer } = require('./parser')
-
-module.exports = {
-    TLArg,
-    TLObject,
-    parseTl,
-    findLayer,
-}

+ 0 - 188
gramjs_generator/parsers/tlobject/parser.js

@@ -1,188 +0,0 @@
-const fs = require('fs')
-const { TLArg } = require('./tlarg')
-const { TLObject } = require('./tlobject')
-const { Usability } = require('../methods')
-
-const CORE_TYPES = new Set([
-    0xbc799737, // boolFalse#bc799737 = Bool;
-    0x997275b5, // boolTrue#997275b5 = Bool;
-    0x3fedd339, // true#3fedd339 = True;
-    0xc4b9f9bb, // error#c4b9f9bb code:int text:string = Error;
-    0x56730bcc, // null#56730bcc = Null;
-])
-
-// Telegram Desktop (C++) doesn't care about string/bytes, and the .tl files
-// don't either. However in Python we *do*, and we want to deal with bytes
-// for the authorization key process, not UTF-8 strings (they won't be).
-//
-// Every type with an ID that's in here should get their attribute types
-// with string being replaced with bytes.
-const AUTH_KEY_TYPES = new Set([
-    0x05162463, // resPQ,
-    0x83c95aec, // p_q_inner_data
-    0xa9f55f95, // p_q_inner_data_dc
-    0x3c6a84d4, // p_q_inner_data_temp
-    0x56fddf88, // p_q_inner_data_temp_dc
-    0xd0e8075c, // server_DH_params_ok
-    0xb5890dba, // server_DH_inner_data
-    0x6643b654, // client_DH_inner_data
-    0xd712e4be, // req_DH_params
-    0xf5045f1f, // set_client_DH_params
-    0x3072cfa1, // gzip_packed
-])
-
-const findall = (regex, str, matches) => {
-    if (!matches) {
-        matches = []
-    }
-
-    if (!regex.flags.includes(`g`)) {
-        regex = new RegExp(regex.source, `g`)
-    }
-
-    const res = regex.exec(str)
-
-    if (res) {
-        matches.push(res.slice(1))
-        findall(regex, str, matches)
-    }
-
-    return matches
-}
-
-const fromLine = (line, isFunction, methodInfo, layer) => {
-    const match = line.match(/([\w.]+)(?:#([0-9a-fA-F]+))?(?:\s{?\w+:[\w\d<>#.?!]+}?)*\s=\s([\w\d<>#.?]+);$/)
-
-    if (!match) {
-        // Probably "vector#1cb5c415 {t:Type} # [ t ] = Vector t;"
-        throw new Error(`Cannot parse TLObject ${line}`)
-    }
-
-    const argsMatch = findall(/({)?(\w+):([\w\d<>#.?!]+)}?/, line)
-    const [, name] = match
-    methodInfo = methodInfo[name]
-
-    let usability
-    let friendly
-
-    if (methodInfo) {
-        usability = methodInfo.usability
-        friendly = methodInfo.friendly
-    } else {
-        usability = Usability.UNKNOWN
-        friendly = null
-    }
-
-    return new TLObject(
-        name,
-        match[2],
-        argsMatch.map(([brace, name, argType]) => new TLArg(name, argType, brace !== undefined)),
-        match[3],
-        isFunction,
-        usability,
-        friendly,
-        layer,
-    )
-}
-
-/**
- * This method yields TLObjects from a given .tl file.
- *
- * Note that the file is parsed completely before the function yields
- * because references to other objects may appear later in the file.
- */
-const parseTl = function* (filePath, layer, methods, ignoreIds = CORE_TYPES) {
-    const methodInfo = (methods || []).reduce((o, m) => ({ ...o, [m.name]: m }), {})
-    const objAll = []
-    const objByName = {}
-    const objByType = {}
-
-    const file = fs.readFileSync(filePath, { encoding: 'utf-8' })
-
-    let isFunction = false
-
-    for (let line of file.split('\n')) {
-        const commentIndex = line.indexOf('//')
-
-        if (commentIndex !== -1) {
-            line = line.slice(0, commentIndex)
-        }
-
-        line = line.trim()
-
-        if (!line) {
-            continue
-        }
-
-        const match = line.match(/---(\w+)---/)
-
-        if (match) {
-            const [, followingTypes] = match
-            isFunction = followingTypes === 'functions'
-            continue
-        }
-
-        try {
-            const result = fromLine(line, isFunction, methodInfo, layer)
-
-            if (ignoreIds.has(result.id)) {
-                continue
-            }
-
-            objAll.push(result)
-
-            if (!result.isFunction) {
-                if (!objByType[result.result]) {
-                    objByType[result.result] = []
-                }
-
-                objByName[result.fullname] = result
-                objByType[result.result].push(result)
-            }
-        } catch (e) {
-            if (!e.toString().includes('vector#1cb5c415')) {
-                throw e
-            }
-        }
-    }
-
-    // Once all objects have been parsed, replace the
-    // string type from the arguments with references
-    for (const obj of objAll) {
-        if (AUTH_KEY_TYPES.has(obj.id)) {
-            for (const arg of obj.args) {
-                if (arg.type === 'string') {
-                    arg.type = 'bytes'
-                }
-            }
-        }
-
-        for (const arg of obj.args) {
-            arg.cls = objByType[arg.type] || (arg.type in objByName ? [objByName[arg.type]] : [])
-        }
-    }
-
-    for (const obj of objAll) {
-        yield obj
-    }
-}
-
-/**
- * Finds the layer used on the specified scheme.tl file.
- */
-const findLayer = (filePath) => {
-    const layerRegex = /^\/\/\s*LAYER\s*(\d+)/
-
-    const file = fs.readFileSync(filePath, { encoding: 'utf-8' })
-    for (const line of file.split('\n')) {
-        const match = line.match(layerRegex)
-        if (match) {
-            return Number(match[1])
-        }
-    }
-}
-
-module.exports = {
-    parseTl,
-    findLayer,
-}

+ 0 - 287
gramjs_generator/parsers/tlobject/tlarg.js

@@ -1,287 +0,0 @@
-const fmtStrings = (...objects) => {
-    for (const object of objects) {
-        for (const [k, v] of Object.entries(object)) {
-            if (['null', 'true', 'false'].includes(v)) {
-                object[k] = `<strong>${v}</strong>`
-            } else {
-                object[k] = v.replace(/((['"]).*\2)/, (_, g) => `<em>${g}</em>`)
-            }
-        }
-    }
-}
-
-const KNOWN_NAMED_EXAMPLES = {
-    'message,string': '\'Hello there!\'',
-    'expires_at,date': 'datetime.timedelta(minutes=5)',
-    'until_date,date': 'datetime.timedelta(days=14)',
-    'view_messages,true': 'None',
-    'send_messages,true': 'None',
-    'limit,int': '100',
-    'hash,int': '0',
-    'hash,string': '\'A4LmkR23G0IGxBE71zZfo1\'',
-    'min_id,int': '0',
-    'max_id,int': '0',
-    'min_id,long': '0',
-    'max_id,long': '0',
-    'add_offset,int': '0',
-    'title,string': '\'My awesome title\'',
-    'device_model,string': '\'ASUS Laptop\'',
-    'system_version,string': '\'Arch Linux\'',
-    'app_version,string': '\'1.0\'',
-    'system_lang_code,string': '\'en\'',
-    'lang_pack,string': '\'\'',
-    'lang_code,string': '\'en\'',
-    'chat_id,int': '478614198',
-    'client_id,long': 'random.randrange(-2**63, 2**63)',
-}
-
-const KNOWN_TYPED_EXAMPLES = {
-    int128: 'int.from_bytes(crypto.randomBytes(16), \'big\')',
-    bytes: 'b\'arbitrary\\x7f data \\xfa here\'',
-    long: '-12398745604826',
-    string: '\'some string here\'',
-    int: '42',
-    date: 'datetime.datetime(2018, 6, 25)',
-    double: '7.13',
-    Bool: 'False',
-    true: 'True',
-    InputChatPhoto: 'client.upload_file(\'/path/to/photo.jpg\')',
-    InputFile: 'client.upload_file(\'/path/to/file.jpg\')',
-    InputPeer: '\'username\'',
-}
-
-fmtStrings(KNOWN_NAMED_EXAMPLES, KNOWN_TYPED_EXAMPLES)
-
-const SYNONYMS = {
-    InputUser: 'InputPeer',
-    InputChannel: 'InputPeer',
-    InputDialogPeer: 'InputPeer',
-    InputNotifyPeer: 'InputPeer',
-    InputMessage: 'int',
-}
-
-// These are flags that are cleaner to leave off
-const OMITTED_EXAMPLES = [
-    'silent',
-    'background',
-    'clear_draft',
-    'reply_to_msg_id',
-    'random_id',
-    'reply_markup',
-    'entities',
-    'embed_links',
-    'hash',
-    'min_id',
-    'max_id',
-    'add_offset',
-    'grouped',
-    'broadcast',
-    'admins',
-    'edit',
-    'delete',
-]
-
-/**
- * Initializes a new .tl argument
- * :param name: The name of the .tl argument
- * :param argType: The type of the .tl argument
- * :param genericDefinition: Is the argument a generic definition?
- *                           (i.e. {X:Type})
- */
-class TLArg {
-    constructor(name, argType, genericDefinition) {
-        this.name = name === 'self' ? 'is_self' : name
-
-        // Default values
-        this.isVector = false
-        this.isFlag = false
-        this.skipConstructorId = false
-        this.flagIndex = -1
-        this.cls = null
-
-        // Special case: some types can be inferred, which makes it
-        // less annoying to type. Currently the only type that can
-        // be inferred is if the name is 'random_id', to which a
-        // random ID will be assigned if left as None (the default)
-        this.canBeInferred = name === 'random_id'
-
-        // The type can be an indicator that other arguments will be flags
-        if (argType === '#') {
-            this.flagIndicator = true
-            this.type = null
-            this.isGeneric = false
-        } else {
-            this.flagIndicator = false
-            this.isGeneric = argType.startsWith('!')
-            // Strip the exclamation mark always to have only the name
-            this.type = argType.replace(/^!+/, '')
-
-            // The type may be a flag (flags.IDX?REAL_TYPE)
-            // Note that 'flags' is NOT the flags name; this
-            // is determined by a previous argument
-            // However, we assume that the argument will always be called 'flags'
-            const flagMatch = this.type.match(/flags.(\d+)\?([\w<>.]+)/)
-
-            if (flagMatch) {
-                this.isFlag = true
-                this.flagIndex = Number(flagMatch[1]);
-                // Update the type to match the exact type, not the "flagged" one
-                [, , this.type] = flagMatch
-            }
-
-            // Then check if the type is a Vector<REAL_TYPE>
-            const vectorMatch = this.type.match(/[Vv]ector<([\w\d.]+)>/)
-
-            if (vectorMatch) {
-                this.isVector = true
-
-                // If the type's first letter is not uppercase, then
-                // it is a constructor and we use (read/write) its ID.
-                this.useVectorId = this.type.charAt(0) === 'V';
-
-                // Update the type to match the one inside the vector
-                [, this.type] = vectorMatch
-            }
-
-            // See use_vector_id. An example of such case is ipPort in
-            // help.configSpecial
-            if (
-                /^[a-z]$/.test(
-                    this.type
-                        .split('.')
-                        .pop()
-                        .charAt(0),
-                )
-            ) {
-                this.skipConstructorId = true
-            }
-
-            // The name may contain "date" in it, if this is the case and
-            // the type is "int", we can safely assume that this should be
-            // treated as a "date" object. Note that this is not a valid
-            // Telegram object, but it's easier to work with
-            // if (
-            //     this.type === 'int' &&
-            //     (/(\b|_)([dr]ate|until|since)(\b|_)/.test(name) ||
-            //         ['expires', 'expires_at', 'was_online'].includes(name))
-            // ) {
-            //     this.type = 'date';
-            // }
-        }
-
-        this.genericDefinition = genericDefinition
-    }
-
-    typeHint() {
-        let cls = this.type
-
-        if (cls.includes('.')) {
-            [, cls] = cls.split('.')
-        }
-
-        let result = {
-            int: 'int',
-            long: 'int',
-            int128: 'int',
-            int256: 'int',
-            double: 'float',
-            string: 'str',
-            date: 'Optional[datetime]', // None date = 0 timestamp
-            bytes: 'bytes',
-            Bool: 'bool',
-            true: 'bool',
-        }
-
-        result = result[cls] || `'Type${cls}'`
-
-        if (this.isVector) {
-            result = `List[${result}]`
-        }
-
-        if (this.isFlag && cls !== 'date') {
-            result = `Optional[${result}]`
-        }
-
-        return result
-    }
-
-    realType() {
-        // Find the real type representation by updating it as required
-        let realType = this.flagIndicator ? '#' : this.type
-
-        if (this.isVector) {
-            if (this.useVectorId) {
-                realType = `Vector<${realType}>`
-            } else {
-                realType = `vector<${realType}>`
-            }
-        }
-
-        if (this.isGeneric) {
-            realType = `!${realType}`
-        }
-
-        if (this.isFlag) {
-            realType = `flags.${this.flagIndex}?${realType}`
-        }
-
-        return realType
-    }
-
-    toString() {
-        if (this.genericDefinition) {
-            return `{${this.name}:${this.realType()}}`
-        } else {
-            return `${this.name}:${this.realType()}`
-        }
-    }
-
-    toJson() {
-        return {
-            name: this.name.replace('is_self', 'self'),
-            type: this.realType().replace(/\bdate$/, 'int'),
-        }
-    }
-
-    asExample(f, indent) {
-        if (this.isGeneric) {
-            f.write('other_request')
-            return
-        }
-
-        const known =
-            KNOWN_NAMED_EXAMPLES[`${this.name},${this.type}`] ||
-            KNOWN_TYPED_EXAMPLES[this.type] ||
-            KNOWN_TYPED_EXAMPLES[SYNONYMS[this.type]]
-
-        if (known) {
-            f.write(known)
-            return
-        }
-
-        // assert self.omit_example() or self.cls, 'TODO handle ' + str(self)
-
-        // Pick an interesting example if any
-        for (const cls of this.cls) {
-            if (cls.isGoodExample()) {
-                cls.asExample(f, indent || 0)
-                return
-            }
-        }
-
-        // If no example is good, just pick the first
-        this.cls[0].asExample(f, indent || 0)
-    }
-
-    omitExample() {
-        return this.isFlag || (this.canBeInferred && OMITTED_EXAMPLES.includes(this.name))
-    }
-}
-
-module.exports = {
-    KNOWN_NAMED_EXAMPLES,
-    KNOWN_TYPED_EXAMPLES,
-    SYNONYMS,
-    OMITTED_EXAMPLES,
-    TLArg,
-}

+ 0 - 191
gramjs_generator/parsers/tlobject/tlobject.js

@@ -1,191 +0,0 @@
-const { crc32 } = require('crc')
-const struct = require('python-struct')
-const { snakeToCamelCase } = require('../../utils')
-
-// https://github.com/telegramdesktop/tdesktop/blob/4bf66cb6e93f3965b40084771b595e93d0b11bcd/Telegram/SourceFiles/codegen/scheme/codegen_scheme.py#L57-L62
-const WHITELISTED_MISMATCHING_IDS = {
-    // 0 represents any layer
-    0: new Set([
-        'channel', // Since layer 77, there seems to be no going back...
-        'ipPortSecret',
-        'accessPointRule',
-        'help.configSimple',
-    ]),
-}
-
-/**
- * Initializes a new TLObject, given its properties.
- *
- * :param fullname: The fullname of the TL object (namespace.name)
- *                  The namespace can be omitted.
- * :param object_id: The hexadecimal string representing the object ID
- * :param args: The arguments, if any, of the TL object
- * :param result: The result type of the TL object
- * :param is_function: Is the object a function or a type?
- * :param usability: The usability for this method.
- * :param friendly: A tuple (namespace, friendly method name) if known.
- * :param layer: The layer this TLObject belongs to.
- */
-class TLObject {
-    constructor(fullname, objectId, args, result, isFunction, usability, friendly, layer) {
-        // The name can or not have a namespace
-        this.fullname = fullname
-
-        if (fullname.includes('.')) {
-            [this.namespace, this.name] = fullname.split(/\.(.+)/)
-            // console.log(fullname.split(/\.(.+)/));
-            // const [namespace, ...name] = fullname.split('.');
-            // this.namespace = namespace;
-            // this.name = name.join('.');
-        } else {
-            this.namespace = null
-            this.name = fullname
-        }
-
-        this.args = args
-        this.result = result
-        this.isFunction = isFunction
-        this.usability = usability
-        this.friendly = friendly
-        this.id = null
-
-        if (!objectId) {
-            this.id = this.inferId()
-        } else {
-            this.id = parseInt(objectId, 16)
-
-            const whitelist = new Set([
-                ...WHITELISTED_MISMATCHING_IDS[0],
-                ...(WHITELISTED_MISMATCHING_IDS[layer] || []),
-            ])
-
-            if (!whitelist.has(this.fullname)) {
-                if (this.id !== this.inferId()) {
-                    throw new Error(`Invalid inferred ID for ${this.repr()}`)
-                }
-            }
-        }
-
-        this.className = snakeToCamelCase(this.name, this.isFunction ? 'Request' : '')
-
-        this.realArgs = this.sortedArgs().filter((a) => !(a.flagIndicator || a.genericDefinition))
-    }
-
-    get innermostResult() {
-        const index = this.result.indexOf('<')
-        return index === -1 ? this.result : this.result.slice(index + 1, -1)
-    }
-
-    /**
-     * Returns the arguments properly sorted and ready to plug-in
-     * into a Python's method header (i.e., flags and those which
-     * can be inferred will go last so they can default =None)
-     */
-    sortedArgs() {
-        return this.args.sort((x) => x.isFlag || x.canBeInferred)
-    }
-
-    repr(ignoreId) {
-        let hexId
-        let args
-
-        if (this.id === null || ignoreId) {
-            hexId = ''
-        } else {
-            hexId = `#${this.id.toString(16).padStart(8, '0')}`
-        }
-
-        if (this.args.length) {
-            args = ` ${this.args.map((arg) => arg.toString()).join(' ')}`
-        } else {
-            args = ''
-        }
-
-        return `${this.fullname}${hexId}${args} = ${this.result}`
-    }
-
-    inferId() {
-        const representation = this.repr(true)
-            .replace(/(:|\?)bytes /g, '$1string ')
-            .replace(/</g, ' ')
-            .replace(/>|{|}/g, '')
-            .replace(/ \w+:flags\.\d+\?true/g, '')
-
-        if (this.fullname === 'inputMediaInvoice') {
-            // eslint-disable-next-line no-empty
-            if (this.fullname === 'inputMediaInvoice') {
-            }
-        }
-
-        return crc32(Buffer.from(representation, 'utf8'))
-    }
-
-    toJson() {
-        return {
-            id: struct.unpack('i', struct.pack('I', this.id))[0].toString(),
-            [this.isFunction ? 'method' : 'predicate']: this.fullname,
-            param: this.args.filter((x) => !x.genericDefinition).map((x) => x.toJson()),
-            type: this.result,
-        }
-    }
-
-    isGoodExample() {
-        return !this.className.endsWith('Empty')
-    }
-
-    asExample(f, indent) {
-        f.write('<strong>new</strong> ')
-        f.write(this.isFunction ? 'functions' : 'types')
-
-        if (this.namespace) {
-            f.write('.')
-            f.write(this.namespace)
-        }
-
-        f.write('.')
-        f.write(this.className)
-        f.write('(')
-
-        const args = this.realArgs.filter((arg) => !arg.omitExample())
-
-        if (!args.length) {
-            f.write(')')
-            return
-        }
-
-        f.write('\n')
-        indent++
-        let remaining = args.length
-
-        for (const arg of args) {
-            remaining--
-            f.write('    '.repeat(indent))
-            f.write(arg.name)
-            f.write('=')
-
-            if (arg.isVector) {
-                f.write('[')
-            }
-
-            arg.asExample(f, indent || 0)
-
-            if (arg.isVector) {
-                f.write(']')
-            }
-
-            if (remaining) {
-                f.write(',')
-            }
-
-            f.write('\n')
-        }
-
-        indent--
-        f.write('    '.repeat(indent))
-        f.write(')')
-    }
-}
-
-module.exports = {
-    TLObject,
-}

+ 0 - 77
gramjs_generator/sourcebuilder.js

@@ -1,77 +0,0 @@
-const util = require('util')
-
-/**
- * This class should be used to build .py source files
- */
-class SourceBuilder {
-    constructor(stream, indentSize) {
-        this.currentIndent = 0
-        this.onNewLine = false
-        this.indentSize = indentSize || 4
-        this.stream = stream
-
-        // Was a new line added automatically before? If so, avoid it
-        this.autoAddedLine = false
-    }
-
-    /**
-     * Indents the current source code line
-     * by the current indentation level
-     */
-    indent() {
-        this.write(' '.repeat(Math.abs(this.currentIndent * this.indentSize)))
-    }
-
-    /**
-     * Writes a string into the source code,
-     * applying indentation if required
-     */
-    write(string, ...args) {
-        if (this.onNewLine) {
-            this.onNewLine = false // We're not on a new line anymore
-
-            // If the string was not empty, indent; Else probably a new line
-            if (string.trim()) {
-                this.indent()
-            }
-        }
-
-        if (args.length) {
-            this.stream.write(util.format(string, ...args))
-        } else {
-            this.stream.write(string)
-        }
-    }
-
-    /**
-     * Writes a string into the source code _and_ appends a new line,
-     * applying indentation if required
-     */
-    writeln(string, ...args) {
-        this.write(`${string || ''}\n`, ...args)
-        this.onNewLine = true
-
-        // If we're writing a block, increment indent for the next time
-        if (string && string.endsWith('{')) {
-            this.currentIndent++
-        }
-
-        // Clear state after the user adds a new line
-        this.autoAddedLine = false
-    }
-
-    /**
-     * Ends an indentation block, leaving an empty line afterwards
-     */
-    endBlock(semiColon = false) {
-        this.currentIndent--
-
-        // If we did not add a new line automatically yet, now it's the time!
-        if (!this.autoAddedLine) {
-            this.writeln('}%s', semiColon ? ';' : '')
-            this.autoAddedLine = true
-        }
-    }
-}
-
-module.exports = SourceBuilder

+ 0 - 16
gramjs_generator/utils.js

@@ -1,16 +0,0 @@
-const snakeToCamelCase = (name, suffix) => {
-    const result = name.replace(/(?:^|_)([a-z])/g, (_, g) => g.toUpperCase())
-    return result.replace(/_/g, '') + (suffix || '')
-}
-const variableSnakeToCamelCase = (str) => str.replace(
-    /([-_][a-z])/g,
-    (group) => group.toUpperCase()
-        .replace('-', '')
-        .replace('_', '')
-)
-
-
-module.exports = {
-    snakeToCamelCase,
-    variableSnakeToCamelCase,
-}

+ 0 - 186
index.js

@@ -1,186 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-const glob = require('glob')
-
-class TempWorkDir {
-    /**
-     * Switches the working directory to be the one on which this file lives.
-     */
-    constructor(dir) {
-        this.original = null
-        this.dir = dir || path.join(__filename, '..')
-    }
-
-    open() {
-        this.original = __dirname
-        fs.mkdirSync(this.dir, { recursive: true })
-        process.chdir(this.dir)
-        return this
-    }
-
-    close() {
-        process.chdir(this.original)
-    }
-}
-
-const GENERATOR_DIR = './gramjs_generator'
-const LIBRARY_DIR = './gramjs'
-
-const ERRORS_IN = `${GENERATOR_DIR}/data/errors.csv`
-const ERRORS_OUT = `${LIBRARY_DIR}/errors/RPCErrorList.js`
-
-const METHODS_IN = `${GENERATOR_DIR}/data/methods.csv`
-
-// Which raw API methods are covered by *friendly* methods in the client?
-const FRIENDLY_IN = `${GENERATOR_DIR}/data/friendly.csv`
-
-const TLOBJECT_IN_TLS = glob.sync(`${GENERATOR_DIR}/data/*.tl`)
-const TLOBJECT_OUT = `${LIBRARY_DIR}/tl`
-const IMPORT_DEPTH = 2
-
-const DOCS_IN_RES = `../${GENERATOR_DIR}/data/html`
-const DOCS_OUT = `./docs`
-
-const generate = (which, action = 'gen') => {
-    const {
-        parseErrors,
-        parseMethods,
-        parseTl,
-        findLayer,
-    } = require('./gramjs_generator/parsers')
-
-    const {
-        generateErrors,
-        generateTLObjects,
-        generateDocs,
-        cleanTLObjects,
-    } = require('./gramjs_generator/generators')
-
-    const [layer] = TLOBJECT_IN_TLS.map(findLayer).filter(Boolean)
-    const errors = [...parseErrors(ERRORS_IN)]
-    const methods = [
-        ...parseMethods(
-            METHODS_IN,
-            FRIENDLY_IN,
-            errors.reduce((errors, error) => {
-                errors[error.stringCode] = error
-                return errors
-            }, {})
-        ),
-    ]
-
-    const tlobjects = TLOBJECT_IN_TLS.reduce(
-        (files, file) => [...files, ...parseTl(file, layer, methods)],
-        []
-    )
-
-    if (!which || which.length === 0) {
-        which.push('tl', 'errors')
-    }
-
-    const clean = action === 'clean'
-    action = clean ? 'Cleaning' : 'Generating'
-
-    if (which.includes('all')) {
-        which.splice(which.indexOf('all'), 1)
-
-        for (const x of ['tl', 'errors', 'docs']) {
-            if (!which.includes(x)) {
-                which.push(x)
-            }
-        }
-    }
-
-    if (which.includes('tl')) {
-        which.splice(which.indexOf('tl'), 1)
-        console.log(action, 'TLObjects...')
-
-        if (clean) {
-            cleanTLObjects(TLOBJECT_OUT)
-        } else {
-            generateTLObjects(tlobjects, layer, IMPORT_DEPTH, TLOBJECT_OUT)
-        }
-    }
-
-    if (which.includes('errors')) {
-        which.splice(which.indexOf('errors'), 1)
-        console.log(action, 'RPCErrors...')
-
-        if (clean) {
-            if (fs.statSync(ERRORS_OUT).isFile()) {
-                fs.unlinkSync(ERRORS_OUT)
-            }
-        } else {
-            const file = fs.createWriteStream(ERRORS_OUT)
-            generateErrors(errors, file)
-        }
-    }
-
-    if (which.includes('docs')) {
-        which.splice(which.indexOf('docs'), 1)
-        console.log(action, 'documentation...')
-
-        if (clean) {
-            if (fs.statSync(DOCS_OUT)) {
-                fs.rmdirSync(DOCS_OUT)
-            }
-        } else {
-            const tmp = new TempWorkDir(DOCS_OUT).open()
-            generateDocs(tlobjects, methods, layer, DOCS_IN_RES)
-            tmp.close()
-        }
-    }
-
-    if (which.includes('json')) {
-        which.splice(which.indexOf('json'), 1)
-        console.log(action, 'JSON schema...')
-
-        const jsonFiles = TLOBJECT_IN_TLS.map(
-            (x) => x.slice(0, x.lastIndexOf('.')) + '.json'
-        )
-
-        if (clean) {
-            for (const file of jsonFiles) {
-                if (fs.statSync(file).isFile()) {
-                    fs.unlinkSync(file)
-                }
-            }
-        } else {
-            const genJson = (fin, fout) => {
-                const meths = []
-                const constructors = []
-
-                for (const tl of parseTl(fin, layer)) {
-                    if (tl.isFunction) {
-                        meths.push(tl.toJson())
-                    } else {
-                        constructors.push(tl.toJson())
-                    }
-                }
-
-                const what = { constructors, methods }
-                fs.writeFileSync(fout, JSON.stringify(what, null, 2))
-            }
-
-            for (let i = 0; i < TLOBJECT_IN_TLS.length; i++) {
-                const fin = TLOBJECT_IN_TLS[i]
-                const fout = jsonFiles[i]
-                genJson(fin, fout)
-            }
-        }
-    }
-
-    if (which.length) {
-        console.log('The following items were not understood:', which)
-        console.log('  Consider using only "tl", "errors" and/or "docs".')
-        console.log(
-            '  Using only "clean" will clean them. "all" to act on all.'
-        )
-        console.log('  For instance "gen tl errors".')
-    }
-}
-
-const { argv } = process
-if (argv.length > 2 && argv[2] === 'gen') {
-    generate(argv.slice(3))
-}

+ 0 - 31
webpack.config.babel.js

@@ -1,31 +0,0 @@
-module.exports = {
-    entry: './gramjs/index.js',
-    mode: 'development',
-    node: {
-        fs: 'empty',
-    },
-    module: {
-        rules: [{
-            test: /\.js$/,
-            use: {
-
-                loader: 'babel-loader',
-                options: {
-                    presets: [
-                        '@babel/preset-env',
-                    ],
-                    plugins: [
-                        '@babel/plugin-proposal-class-properties',
-                    ],
-                },
-            },
-        },
-        ],
-    },
-    output: {
-        path: __dirname + '/browser',
-        filename: 'gramjs.js',
-        libraryTarget: 'var',
-        library: 'gramjs',
-    },
-}

部分文件因为文件数量过多而无法显示