(function webpackUniversalModuleDefinition(root, factory) {
/* istanbul ignore next */
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
        define([], factory);
/* istanbul ignore next */
    else if(typeof exports === 'object')
        exports["esprima"] = factory();
    else
        root["esprima"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/     // The module cache
/******/     var installedModules = {};

/******/     // The require function
/******/     function __webpack_require__(moduleId) {

/******/         // Check if module is in cache
/* istanbul ignore if */
/******/         if(installedModules[moduleId])
/******/             return installedModules[moduleId].exports;

/******/         // Create a new module (and put it into the cache)
/******/         var module = installedModules[moduleId] = {
/******/             exports: {},
/******/             id: moduleId,
/******/             loaded: false
/******/         };

/******/         // Execute the module function
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/         // Flag the module as loaded
/******/         module.loaded = true;

/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }


/******/     // expose the modules object (__webpack_modules__)
/******/     __webpack_require__.m = modules;

/******/     // expose the module cache
/******/     __webpack_require__.c = installedModules;

/******/     // __webpack_public_path__
/******/     __webpack_require__.p = "";

/******/     // Load entry module and return exports
/******/     return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    /*
      Copyright JS Foundation and other contributors, https://js.foundation/

      Redistribution and use in source and binary forms, with or without
      modification, are permitted provided that the following conditions are met:

        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
          notice, this list of conditions and the following disclaimer in the
          documentation and/or other materials provided with the distribution.

      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
      DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    Object.defineProperty(exports, "__esModule", { value: true });
    const comment_handler_1 = __webpack_require__(1);
    const jsx_parser_1 = __webpack_require__(3);
    const parser_1 = __webpack_require__(8);
    const tokenizer_1 = __webpack_require__(15);
    function parse(code, options, delegate) {
        let commentHandler = null;
        const proxyDelegate = (node, metadata) => {
            if (delegate) {
                delegate(node, metadata);
            }
            if (commentHandler) {
                commentHandler.visit(node, metadata);
            }
        };
        let parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null;
        let collectComment = false;
        if (options) {
            collectComment = (typeof options.comment === 'boolean' && options.comment);
            const attachComment = (typeof options.attachComment === 'boolean' && options.attachComment);
            if (collectComment || attachComment) {
                commentHandler = new comment_handler_1.CommentHandler();
                commentHandler.attach = attachComment;
                options.comment = true;
                parserDelegate = proxyDelegate;
            }
        }
        let isModule = false;
        if (options && typeof options.sourceType === 'string') {
            isModule = (options.sourceType === 'module');
        }
        let parser;
        if (options && typeof options.jsx === 'boolean' && options.jsx) {
            parser = new jsx_parser_1.JSXParser(code, options, parserDelegate);
        }
        else {
            parser = new parser_1.Parser(code, options, parserDelegate);
        }
        const program = isModule ? parser.parseModule() : parser.parseScript();
        const ast = program;
        if (collectComment && commentHandler) {
            ast.comments = commentHandler.comments;
        }
        if (parser.config.tokens) {
            ast.tokens = parser.tokens;
        }
        if (parser.config.tolerant) {
            ast.errors = parser.errorHandler.errors;
        }
        return ast;
    }
    exports.parse = parse;
    function parseModule(code, options, delegate) {
        const parsingOptions = options || {};
        parsingOptions.sourceType = 'module';
        return parse(code, parsingOptions, delegate);
    }
    exports.parseModule = parseModule;
    function parseScript(code, options, delegate) {
        const parsingOptions = options || {};
        parsingOptions.sourceType = 'script';
        return parse(code, parsingOptions, delegate);
    }
    exports.parseScript = parseScript;
    function tokenize(code, options, delegate) {
        const tokenizer = new tokenizer_1.Tokenizer(code, options);
        let tokens;
        tokens = [];
        try {
            while (true) {
                let token = tokenizer.getNextToken();
                if (!token) {
                    break;
                }
                if (delegate) {
                    token = delegate(token);
                }
                tokens.push(token);
            }
        }
        catch (e) {
            tokenizer.errorHandler.tolerate(e);
        }
        if (tokenizer.errorHandler.tolerant) {
            tokens.errors = tokenizer.errors();
        }
        return tokens;
    }
    exports.tokenize = tokenize;
    var syntax_1 = __webpack_require__(2);
    exports.Syntax = syntax_1.Syntax;
    // Sync with *.json manifests.
    exports.version = '4.0.0-dev';


/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const syntax_1 = __webpack_require__(2);
    class CommentHandler {
        constructor() {
            this.attach = false;
            this.comments = [];
            this.stack = [];
            this.leading = [];
            this.trailing = [];
        }
        insertInnerComments(node, metadata) {
            //  innnerComments for properties empty block
            //  `function a() {/** comments **\/}`
            if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) {
                const innerComments = [];
                for (let i = this.leading.length - 1; i >= 0; --i) {
                    const entry = this.leading[i];
                    if (metadata.end.offset >= entry.start) {
                        innerComments.unshift(entry.comment);
                        this.leading.splice(i, 1);
                        this.trailing.splice(i, 1);
                    }
                }
                if (innerComments.length) {
                    node.innerComments = innerComments;
                }
            }
        }
        findTrailingComments(metadata) {
            let trailingComments = [];
            if (this.trailing.length > 0) {
                for (let i = this.trailing.length - 1; i >= 0; --i) {
                    const entry = this.trailing[i];
                    if (entry.start >= metadata.end.offset) {
                        trailingComments.unshift(entry.comment);
                    }
                }
                this.trailing.length = 0;
                return trailingComments;
            }
            const last = this.stack[this.stack.length - 1];
            if (last && last.node.trailingComments) {
                const firstComment = last.node.trailingComments[0];
                if (firstComment && firstComment.range[0] >= metadata.end.offset) {
                    trailingComments = last.node.trailingComments;
                    delete last.node.trailingComments;
                }
            }
            return trailingComments;
        }
        findLeadingComments(metadata) {
            const leadingComments = [];
            let target;
            while (this.stack.length > 0) {
                const entry = this.stack[this.stack.length - 1];
                if (entry && entry.start >= metadata.start.offset) {
                    target = entry.node;
                    this.stack.pop();
                }
                else {
                    break;
                }
            }
            if (target) {
                const count = target.leadingComments ? target.leadingComments.length : 0;
                for (let i = count - 1; i >= 0; --i) {
                    const comment = target.leadingComments[i];
                    if (comment.range[1] <= metadata.start.offset) {
                        leadingComments.unshift(comment);
                        target.leadingComments.splice(i, 1);
                    }
                }
                if (target.leadingComments && target.leadingComments.length === 0) {
                    delete target.leadingComments;
                }
                return leadingComments;
            }
            for (let i = this.leading.length - 1; i >= 0; --i) {
                const entry = this.leading[i];
                if (entry.start <= metadata.start.offset) {
                    leadingComments.unshift(entry.comment);
                    this.leading.splice(i, 1);
                }
            }
            return leadingComments;
        }
        visitNode(node, metadata) {
            if (node.type === syntax_1.Syntax.Program && node.body.length > 0) {
                return;
            }
            this.insertInnerComments(node, metadata);
            const trailingComments = this.findTrailingComments(metadata);
            const leadingComments = this.findLeadingComments(metadata);
            if (leadingComments.length > 0) {
                node.leadingComments = leadingComments;
            }
            if (trailingComments.length > 0) {
                node.trailingComments = trailingComments;
            }
            this.stack.push({
                node: node,
                start: metadata.start.offset
            });
        }
        visitComment(node, metadata) {
            const type = (node.type[0] === 'L') ? 'Line' : 'Block';
            const comment = {
                type: type,
                value: node.value
            };
            if (node.range) {
                comment.range = node.range;
            }
            if (node.loc) {
                comment.loc = node.loc;
            }
            this.comments.push(comment);
            if (this.attach) {
                const entry = {
                    comment: {
                        type: type,
                        value: node.value,
                        range: [metadata.start.offset, metadata.end.offset]
                    },
                    start: metadata.start.offset
                };
                if (node.loc) {
                    entry.comment.loc = node.loc;
                }
                node.type = type;
                this.leading.push(entry);
                this.trailing.push(entry);
            }
        }
        visit(node, metadata) {
            if (node.type === 'LineComment') {
                this.visitComment(node, metadata);
            }
            else if (node.type === 'BlockComment') {
                this.visitComment(node, metadata);
            }
            else if (this.attach) {
                this.visitNode(node, metadata);
            }
        }
    }
    exports.CommentHandler = CommentHandler;


/***/ },
/* 2 */
/***/ function(module, exports) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.Syntax = {
        AssignmentExpression: 'AssignmentExpression',
        AssignmentPattern: 'AssignmentPattern',
        ArrayExpression: 'ArrayExpression',
        ArrayPattern: 'ArrayPattern',
        ArrowFunctionExpression: 'ArrowFunctionExpression',
        AwaitExpression: 'AwaitExpression',
        BlockStatement: 'BlockStatement',
        BinaryExpression: 'BinaryExpression',
        BreakStatement: 'BreakStatement',
        CallExpression: 'CallExpression',
        CatchClause: 'CatchClause',
        ClassBody: 'ClassBody',
        ClassDeclaration: 'ClassDeclaration',
        ClassExpression: 'ClassExpression',
        ConditionalExpression: 'ConditionalExpression',
        ContinueStatement: 'ContinueStatement',
        DoWhileStatement: 'DoWhileStatement',
        DebuggerStatement: 'DebuggerStatement',
        EmptyStatement: 'EmptyStatement',
        ExportAllDeclaration: 'ExportAllDeclaration',
        ExportDefaultDeclaration: 'ExportDefaultDeclaration',
        ExportNamedDeclaration: 'ExportNamedDeclaration',
        ExportSpecifier: 'ExportSpecifier',
        ExpressionStatement: 'ExpressionStatement',
        ForStatement: 'ForStatement',
        ForOfStatement: 'ForOfStatement',
        ForInStatement: 'ForInStatement',
        FunctionDeclaration: 'FunctionDeclaration',
        FunctionExpression: 'FunctionExpression',
        Identifier: 'Identifier',
        IfStatement: 'IfStatement',
        Import: 'Import',
        ImportDeclaration: 'ImportDeclaration',
        ImportDefaultSpecifier: 'ImportDefaultSpecifier',
        ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
        ImportSpecifier: 'ImportSpecifier',
        Literal: 'Literal',
        LabeledStatement: 'LabeledStatement',
        LogicalExpression: 'LogicalExpression',
        MemberExpression: 'MemberExpression',
        MetaProperty: 'MetaProperty',
        MethodDefinition: 'MethodDefinition',
        NewExpression: 'NewExpression',
        ObjectExpression: 'ObjectExpression',
        ObjectPattern: 'ObjectPattern',
        Program: 'Program',
        Property: 'Property',
        RestElement: 'RestElement',
        ReturnStatement: 'ReturnStatement',
        SequenceExpression: 'SequenceExpression',
        SpreadElement: 'SpreadElement',
        Super: 'Super',
        SwitchCase: 'SwitchCase',
        SwitchStatement: 'SwitchStatement',
        TaggedTemplateExpression: 'TaggedTemplateExpression',
        TemplateElement: 'TemplateElement',
        TemplateLiteral: 'TemplateLiteral',
        ThisExpression: 'ThisExpression',
        ThrowStatement: 'ThrowStatement',
        TryStatement: 'TryStatement',
        UnaryExpression: 'UnaryExpression',
        UpdateExpression: 'UpdateExpression',
        VariableDeclaration: 'VariableDeclaration',
        VariableDeclarator: 'VariableDeclarator',
        WhileStatement: 'WhileStatement',
        WithStatement: 'WithStatement',
        YieldExpression: 'YieldExpression'
    };


/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const character_1 = __webpack_require__(4);
    const JSXNode = __webpack_require__(5);
    const jsx_syntax_1 = __webpack_require__(6);
    const Node = __webpack_require__(7);
    const parser_1 = __webpack_require__(8);
    const token_1 = __webpack_require__(13);
    const xhtml_entities_1 = __webpack_require__(14);
    token_1.TokenName[100 /* Identifier */] = 'JSXIdentifier';
    token_1.TokenName[101 /* Text */] = 'JSXText';
    // Fully qualified element name, e.g. <svg:path> returns "svg:path"
    function getQualifiedElementName(elementName) {
        let qualifiedName;
        switch (elementName.type) {
            case jsx_syntax_1.JSXSyntax.JSXIdentifier:
                const id = elementName;
                qualifiedName = id.name;
                break;
            case jsx_syntax_1.JSXSyntax.JSXNamespacedName:
                const ns = elementName;
                qualifiedName = getQualifiedElementName(ns.namespace) + ':' +
                    getQualifiedElementName(ns.name);
                break;
            case jsx_syntax_1.JSXSyntax.JSXMemberExpression:
                const expr = elementName;
                qualifiedName = getQualifiedElementName(expr.object) + '.' +
                    getQualifiedElementName(expr.property);
                break;
            /* istanbul ignore next */
            default:
                break;
        }
        return qualifiedName;
    }
    class JSXParser extends parser_1.Parser {
        constructor(code, options, delegate) {
            super(code, options, delegate);
        }
        parsePrimaryExpression() {
            return this.match('<') ? this.parseJSXRoot() : super.parsePrimaryExpression();
        }
        startJSX() {
            // Unwind the scanner before the lookahead token.
            this.scanner.index = this.startMarker.index;
            this.scanner.lineNumber = this.startMarker.line;
            this.scanner.lineStart = this.startMarker.index - this.startMarker.column;
        }
        finishJSX() {
            // Prime the next lookahead.
            this.nextToken();
        }
        reenterJSX() {
            this.startJSX();
            this.expectJSX('}');
            // Pop the closing '}' added from the lookahead.
            if (this.config.tokens) {
                this.tokens.pop();
            }
        }
        createJSXNode() {
            this.collectComments();
            return {
                index: this.scanner.index,
                line: this.scanner.lineNumber,
                column: this.scanner.index - this.scanner.lineStart
            };
        }
        createJSXChildNode() {
            return {
                index: this.scanner.index,
                line: this.scanner.lineNumber,
                column: this.scanner.index - this.scanner.lineStart
            };
        }
        scanXHTMLEntity(quote) {
            let result = '&';
            let valid = true;
            let terminated = false;
            let numeric = false;
            let hex = false;
            while (!this.scanner.eof() && valid && !terminated) {
                const ch = this.scanner.source[this.scanner.index];
                if (ch === quote) {
                    break;
                }
                terminated = (ch === ';');
                result += ch;
                ++this.scanner.index;
                if (!terminated) {
                    switch (result.length) {
                        case 2:
                            // e.g. '&#123;'
                            numeric = (ch === '#');
                            break;
                        case 3:
                            if (numeric) {
                                // e.g. '&#x41;'
                                hex = (ch === 'x');
                                valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0));
                                numeric = numeric && !hex;
                            }
                            break;
                        default:
                            valid = valid && !(numeric && !character_1.Character.isDecimalDigit(ch.charCodeAt(0)));
                            valid = valid && !(hex && !character_1.Character.isHexDigit(ch.charCodeAt(0)));
                            break;
                    }
                }
            }
            if (valid && terminated && result.length > 2) {
                // e.g. '&#x41;' becomes just '#x41'
                const str = result.substr(1, result.length - 2);
                if (numeric && str.length > 1) {
                    result = String.fromCharCode(parseInt(str.substr(1), 10));
                }
                else if (hex && str.length > 2) {
                    result = String.fromCharCode(parseInt('0' + str.substr(1), 16));
                }
                else if (!numeric && !hex && xhtml_entities_1.XHTMLEntities[str]) {
                    result = xhtml_entities_1.XHTMLEntities[str];
                }
            }
            return result;
        }
        // Scan the next JSX token. This replaces Scanner#lex when in JSX mode.
        lexJSX() {
            const cp = this.scanner.source.charCodeAt(this.scanner.index);
            // < > / : = { }
            if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) {
                const value = this.scanner.source[this.scanner.index++];
                return {
                    type: 7 /* Punctuator */,
                    value: value,
                    lineNumber: this.scanner.lineNumber,
                    lineStart: this.scanner.lineStart,
                    start: this.scanner.index - 1,
                    end: this.scanner.index
                };
            }
            // " '
            if (cp === 34 || cp === 39) {
                const start = this.scanner.index;
                const quote = this.scanner.source[this.scanner.index++];
                let str = '';
                while (!this.scanner.eof()) {
                    const ch = this.scanner.source[this.scanner.index++];
                    if (ch === quote) {
                        break;
                    }
                    else if (ch === '&') {
                        str += this.scanXHTMLEntity(quote);
                    }
                    else {
                        str += ch;
                    }
                }
                return {
                    type: 8 /* StringLiteral */,
                    value: str,
                    lineNumber: this.scanner.lineNumber,
                    lineStart: this.scanner.lineStart,
                    start: start,
                    end: this.scanner.index
                };
            }
            // ... or .
            if (cp === 46) {
                const n1 = this.scanner.source.charCodeAt(this.scanner.index + 1);
                const n2 = this.scanner.source.charCodeAt(this.scanner.index + 2);
                const value = (n1 === 46 && n2 === 46) ? '...' : '.';
                const start = this.scanner.index;
                this.scanner.index += value.length;
                return {
                    type: 7 /* Punctuator */,
                    value: value,
                    lineNumber: this.scanner.lineNumber,
                    lineStart: this.scanner.lineStart,
                    start: start,
                    end: this.scanner.index
                };
            }
            // `
            if (cp === 96) {
                // Only placeholder, since it will be rescanned as a real assignment expression.
                return {
                    type: 10 /* Template */,
                    value: '',
                    lineNumber: this.scanner.lineNumber,
                    lineStart: this.scanner.lineStart,
                    start: this.scanner.index,
                    end: this.scanner.index
                };
            }
            // Identifer can not contain backslash (char code 92).
            if (character_1.Character.isIdentifierStart(cp) && (cp !== 92)) {
                const start = this.scanner.index;
                ++this.scanner.index;
                while (!this.scanner.eof()) {
                    const ch = this.scanner.source.charCodeAt(this.scanner.index);
                    if (character_1.Character.isIdentifierPart(ch) && (ch !== 92)) {
                        ++this.scanner.index;
                    }
                    else if (ch === 45) {
                        // Hyphen (char code 45) can be part of an identifier.
                        ++this.scanner.index;
                    }
                    else {
                        break;
                    }
                }
                const id = this.scanner.source.slice(start, this.scanner.index);
                return {
                    type: 100 /* Identifier */,
                    value: id,
                    lineNumber: this.scanner.lineNumber,
                    lineStart: this.scanner.lineStart,
                    start: start,
                    end: this.scanner.index
                };
            }
            return this.scanner.lex();
        }
        nextJSXToken() {
            this.collectComments();
            this.startMarker.index = this.scanner.index;
            this.startMarker.line = this.scanner.lineNumber;
            this.startMarker.column = this.scanner.index - this.scanner.lineStart;
            const token = this.lexJSX();
            this.lastMarker.index = this.scanner.index;
            this.lastMarker.line = this.scanner.lineNumber;
            this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
            if (this.config.tokens) {
                this.tokens.push(this.convertToken(token));
            }
            return token;
        }
        nextJSXText() {
            this.startMarker.index = this.scanner.index;
            this.startMarker.line = this.scanner.lineNumber;
            this.startMarker.column = this.scanner.index - this.scanner.lineStart;
            const start = this.scanner.index;
            let text = '';
            while (!this.scanner.eof()) {
                const ch = this.scanner.source[this.scanner.index];
                if (ch === '{' || ch === '<') {
                    break;
                }
                ++this.scanner.index;
                text += ch;
                if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                    ++this.scanner.lineNumber;
                    if (ch === '\r' && this.scanner.source[this.scanner.index] === '\n') {
                        ++this.scanner.index;
                    }
                    this.scanner.lineStart = this.scanner.index;
                }
            }
            this.lastMarker.index = this.scanner.index;
            this.lastMarker.line = this.scanner.lineNumber;
            this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
            const token = {
                type: 101 /* Text */,
                value: text,
                lineNumber: this.scanner.lineNumber,
                lineStart: this.scanner.lineStart,
                start: start,
                end: this.scanner.index
            };
            if ((text.length > 0) && this.config.tokens) {
                this.tokens.push(this.convertToken(token));
            }
            return token;
        }
        peekJSXToken() {
            const state = this.scanner.saveState();
            this.scanner.scanComments();
            const next = this.lexJSX();
            this.scanner.restoreState(state);
            return next;
        }
        // Expect the next JSX token to match the specified punctuator.
        // If not, an exception will be thrown.
        expectJSX(value) {
            const token = this.nextJSXToken();
            if (token.type !== 7 /* Punctuator */ || token.value !== value) {
                this.throwUnexpectedToken(token);
            }
        }
        // Return true if the next JSX token matches the specified punctuator.
        matchJSX(value) {
            const next = this.peekJSXToken();
            return next.type === 7 /* Punctuator */ && next.value === value;
        }
        parseJSXIdentifier() {
            const node = this.createJSXNode();
            const token = this.nextJSXToken();
            if (token.type !== 100 /* Identifier */) {
                this.throwUnexpectedToken(token);
            }
            return this.finalize(node, new JSXNode.JSXIdentifier(token.value));
        }
        parseJSXElementName() {
            const node = this.createJSXNode();
            let elementName = this.parseJSXIdentifier();
            if (this.matchJSX(':')) {
                const namespace = elementName;
                this.expectJSX(':');
                const name = this.parseJSXIdentifier();
                elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name));
            }
            else if (this.matchJSX('.')) {
                while (this.matchJSX('.')) {
                    const object = elementName;
                    this.expectJSX('.');
                    const property = this.parseJSXIdentifier();
                    elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property));
                }
            }
            return elementName;
        }
        parseJSXAttributeName() {
            const node = this.createJSXNode();
            let attributeName;
            const identifier = this.parseJSXIdentifier();
            if (this.matchJSX(':')) {
                const namespace = identifier;
                this.expectJSX(':');
                const name = this.parseJSXIdentifier();
                attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name));
            }
            else {
                attributeName = identifier;
            }
            return attributeName;
        }
        parseJSXStringLiteralAttribute() {
            const node = this.createJSXNode();
            const token = this.nextJSXToken();
            if (token.type !== 8 /* StringLiteral */) {
                this.throwUnexpectedToken(token);
            }
            const raw = this.getTokenRaw(token);
            return this.finalize(node, new Node.Literal(token.value, raw));
        }
        parseJSXExpressionAttribute() {
            const node = this.createJSXNode();
            this.expectJSX('{');
            this.finishJSX();
            if (this.match('}')) {
                this.tolerateError('JSX attributes must only be assigned a non-empty expression');
            }
            const expression = this.parseAssignmentExpression();
            this.reenterJSX();
            return this.finalize(node, new JSXNode.JSXExpressionContainer(expression));
        }
        parseJSXAttributeValue() {
            return this.matchJSX('{') ? this.parseJSXExpressionAttribute() :
                this.matchJSX('<') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute();
        }
        parseJSXNameValueAttribute() {
            const node = this.createJSXNode();
            const name = this.parseJSXAttributeName();
            let value = null;
            if (this.matchJSX('=')) {
                this.expectJSX('=');
                value = this.parseJSXAttributeValue();
            }
            return this.finalize(node, new JSXNode.JSXAttribute(name, value));
        }
        parseJSXSpreadAttribute() {
            const node = this.createJSXNode();
            this.expectJSX('{');
            this.expectJSX('...');
            this.finishJSX();
            const argument = this.parseAssignmentExpression();
            this.reenterJSX();
            return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument));
        }
        parseJSXAttributes() {
            const attributes = [];
            while (!this.matchJSX('/') && !this.matchJSX('>')) {
                const attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() :
                    this.parseJSXNameValueAttribute();
                attributes.push(attribute);
            }
            return attributes;
        }
        parseJSXOpeningElement() {
            const node = this.createJSXNode();
            this.expectJSX('<');
            const name = this.parseJSXElementName();
            const attributes = this.parseJSXAttributes();
            const selfClosing = this.matchJSX('/');
            if (selfClosing) {
                this.expectJSX('/');
            }
            this.expectJSX('>');
            return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes));
        }
        parseJSXBoundaryElement() {
            const node = this.createJSXNode();
            this.expectJSX('<');
            if (this.matchJSX('/')) {
                this.expectJSX('/');
                const elementName = this.parseJSXElementName();
                this.expectJSX('>');
                return this.finalize(node, new JSXNode.JSXClosingElement(elementName));
            }
            const name = this.parseJSXElementName();
            const attributes = this.parseJSXAttributes();
            const selfClosing = this.matchJSX('/');
            if (selfClosing) {
                this.expectJSX('/');
            }
            this.expectJSX('>');
            return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes));
        }
        parseJSXEmptyExpression() {
            const node = this.createJSXChildNode();
            this.collectComments();
            this.lastMarker.index = this.scanner.index;
            this.lastMarker.line = this.scanner.lineNumber;
            this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
            return this.finalize(node, new JSXNode.JSXEmptyExpression());
        }
        parseJSXExpressionContainer() {
            const node = this.createJSXNode();
            this.expectJSX('{');
            let expression;
            if (this.matchJSX('}')) {
                expression = this.parseJSXEmptyExpression();
                this.expectJSX('}');
            }
            else {
                this.finishJSX();
                expression = this.parseAssignmentExpression();
                this.reenterJSX();
            }
            return this.finalize(node, new JSXNode.JSXExpressionContainer(expression));
        }
        parseJSXChildren() {
            const children = [];
            while (!this.scanner.eof()) {
                const node = this.createJSXChildNode();
                const token = this.nextJSXText();
                if (token.start < token.end) {
                    const raw = this.getTokenRaw(token);
                    const child = this.finalize(node, new JSXNode.JSXText(token.value, raw));
                    children.push(child);
                }
                if (this.scanner.source[this.scanner.index] === '{') {
                    const container = this.parseJSXExpressionContainer();
                    children.push(container);
                }
                else {
                    break;
                }
            }
            return children;
        }
        parseComplexJSXElement(el) {
            const stack = [];
            while (!this.scanner.eof()) {
                el.children = el.children.concat(this.parseJSXChildren());
                const node = this.createJSXChildNode();
                const element = this.parseJSXBoundaryElement();
                if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) {
                    const opening = element;
                    if (opening.selfClosing) {
                        const child = this.finalize(node, new JSXNode.JSXElement(opening, [], null));
                        el.children.push(child);
                    }
                    else {
                        stack.push(el);
                        el = { node, opening, closing: null, children: [] };
                    }
                }
                if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) {
                    el.closing = element;
                    const open = getQualifiedElementName(el.opening.name);
                    const close = getQualifiedElementName(el.closing.name);
                    if (open !== close) {
                        this.tolerateError('Expected corresponding JSX closing tag for %0', open);
                    }
                    if (stack.length > 0) {
                        const child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing));
                        el = stack[stack.length - 1];
                        el.children.push(child);
                        stack.pop();
                    }
                    else {
                        break;
                    }
                }
            }
            return el;
        }
        parseJSXElement() {
            const node = this.createJSXNode();
            const opening = this.parseJSXOpeningElement();
            let children = [];
            let closing = null;
            if (!opening.selfClosing) {
                const el = this.parseComplexJSXElement({ node, opening, closing, children });
                children = el.children;
                closing = el.closing;
            }
            return this.finalize(node, new JSXNode.JSXElement(opening, children, closing));
        }
        parseJSXRoot() {
            // Pop the opening '<' added from the lookahead.
            if (this.config.tokens) {
                this.tokens.pop();
            }
            this.startJSX();
            const element = this.parseJSXElement();
            this.finishJSX();
            return element;
        }
        isStartOfExpression() {
            return super.isStartOfExpression() || this.match('<');
        }
    }
    exports.JSXParser = JSXParser;


/***/ },
/* 4 */
/***/ function(module, exports) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    // See also tools/generate-unicode-regex.js.
    const Regex = {
        // Unicode v12.1.0 NonAsciiIdentifierStart:
        NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7C6\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB67\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDEC0-\uDEEB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,
        // Unicode v12.1.0 NonAsciiIdentifierPart:
        NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05EF-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u07FD\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D3-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u09FE\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1878\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CD0-\u1CD2\u1CD4-\u1CFA\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7C6\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB67\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD27\uDD30-\uDD39\uDF00-\uDF1C\uDF27\uDF30-\uDF50\uDFE0-\uDFF6]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD44-\uDD46\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDC9-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3B-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC5E\uDC5F\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDC00-\uDC3A\uDCA0-\uDCE9\uDCFF\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDE1\uDDE3\uDDE4\uDE00-\uDE3E\uDE47\uDE50-\uDE99\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF6]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD00-\uDD2C\uDD30-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4B\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
    };
    exports.Character = {
        /* tslint:disable:no-bitwise */
        fromCodePoint(cp) {
            return (cp < 0x10000) ? String.fromCharCode(cp) :
                String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) +
                    String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023));
        },
        // https://tc39.github.io/ecma262/#sec-white-space
        isWhiteSpace(cp) {
            return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) ||
                (cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0);
        },
        // https://tc39.github.io/ecma262/#sec-line-terminators
        isLineTerminator(cp) {
            return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029);
        },
        // https://tc39.github.io/ecma262/#sec-names-and-keywords
        isIdentifierStart(cp) {
            return (cp === 0x24) || (cp === 0x5F) || // $ (dollar) and _ (underscore)
                (cp >= 0x41 && cp <= 0x5A) || // A..Z
                (cp >= 0x61 && cp <= 0x7A) || // a..z
                (cp === 0x5C) || // \ (backslash)
                ((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(cp)));
        },
        isIdentifierPart(cp) {
            return (cp === 0x24) || (cp === 0x5F) || // $ (dollar) and _ (underscore)
                (cp >= 0x41 && cp <= 0x5A) || // A..Z
                (cp >= 0x61 && cp <= 0x7A) || // a..z
                (cp >= 0x30 && cp <= 0x39) || // 0..9
                (cp === 0x5C) || // \ (backslash)
                ((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp)));
        },
        // https://tc39.github.io/ecma262/#sec-literals-numeric-literals
        isDecimalDigit(cp) {
            return (cp >= 0x30 && cp <= 0x39); // 0..9
        },
        isHexDigit(cp) {
            return (cp >= 0x30 && cp <= 0x39) || // 0..9
                (cp >= 0x41 && cp <= 0x46) || // A..F
                (cp >= 0x61 && cp <= 0x66); // a..f
        },
        isOctalDigit(cp) {
            return (cp >= 0x30 && cp <= 0x37); // 0..7
        }
    };


/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const jsx_syntax_1 = __webpack_require__(6);
    /* tslint:disable:max-classes-per-file */
    class JSXClosingElement {
        constructor(name) {
            this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement;
            this.name = name;
        }
    }
    exports.JSXClosingElement = JSXClosingElement;
    class JSXElement {
        constructor(openingElement, children, closingElement) {
            this.type = jsx_syntax_1.JSXSyntax.JSXElement;
            this.openingElement = openingElement;
            this.children = children;
            this.closingElement = closingElement;
        }
    }
    exports.JSXElement = JSXElement;
    class JSXEmptyExpression {
        constructor() {
            this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression;
        }
    }
    exports.JSXEmptyExpression = JSXEmptyExpression;
    class JSXExpressionContainer {
        constructor(expression) {
            this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer;
            this.expression = expression;
        }
    }
    exports.JSXExpressionContainer = JSXExpressionContainer;
    class JSXIdentifier {
        constructor(name) {
            this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier;
            this.name = name;
        }
    }
    exports.JSXIdentifier = JSXIdentifier;
    class JSXMemberExpression {
        constructor(object, property) {
            this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression;
            this.object = object;
            this.property = property;
        }
    }
    exports.JSXMemberExpression = JSXMemberExpression;
    class JSXAttribute {
        constructor(name, value) {
            this.type = jsx_syntax_1.JSXSyntax.JSXAttribute;
            this.name = name;
            this.value = value;
        }
    }
    exports.JSXAttribute = JSXAttribute;
    class JSXNamespacedName {
        constructor(namespace, name) {
            this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName;
            this.namespace = namespace;
            this.name = name;
        }
    }
    exports.JSXNamespacedName = JSXNamespacedName;
    class JSXOpeningElement {
        constructor(name, selfClosing, attributes) {
            this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement;
            this.name = name;
            this.selfClosing = selfClosing;
            this.attributes = attributes;
        }
    }
    exports.JSXOpeningElement = JSXOpeningElement;
    class JSXSpreadAttribute {
        constructor(argument) {
            this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute;
            this.argument = argument;
        }
    }
    exports.JSXSpreadAttribute = JSXSpreadAttribute;
    class JSXText {
        constructor(value, raw) {
            this.type = jsx_syntax_1.JSXSyntax.JSXText;
            this.value = value;
            this.raw = raw;
        }
    }
    exports.JSXText = JSXText;


/***/ },
/* 6 */
/***/ function(module, exports) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.JSXSyntax = {
        JSXAttribute: 'JSXAttribute',
        JSXClosingElement: 'JSXClosingElement',
        JSXElement: 'JSXElement',
        JSXEmptyExpression: 'JSXEmptyExpression',
        JSXExpressionContainer: 'JSXExpressionContainer',
        JSXIdentifier: 'JSXIdentifier',
        JSXMemberExpression: 'JSXMemberExpression',
        JSXNamespacedName: 'JSXNamespacedName',
        JSXOpeningElement: 'JSXOpeningElement',
        JSXSpreadAttribute: 'JSXSpreadAttribute',
        JSXText: 'JSXText'
    };


/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const syntax_1 = __webpack_require__(2);
    /* tslint:disable:max-classes-per-file */
    class ArrayExpression {
        constructor(elements) {
            this.type = syntax_1.Syntax.ArrayExpression;
            this.elements = elements;
        }
    }
    exports.ArrayExpression = ArrayExpression;
    class ArrayPattern {
        constructor(elements) {
            this.type = syntax_1.Syntax.ArrayPattern;
            this.elements = elements;
        }
    }
    exports.ArrayPattern = ArrayPattern;
    class ArrowFunctionExpression {
        constructor(params, body, expression) {
            this.type = syntax_1.Syntax.ArrowFunctionExpression;
            this.id = null;
            this.params = params;
            this.body = body;
            this.generator = false;
            this.expression = expression;
            this.async = false;
        }
    }
    exports.ArrowFunctionExpression = ArrowFunctionExpression;
    class AssignmentExpression {
        constructor(operator, left, right) {
            this.type = syntax_1.Syntax.AssignmentExpression;
            this.operator = operator;
            this.left = left;
            this.right = right;
        }
    }
    exports.AssignmentExpression = AssignmentExpression;
    class AssignmentPattern {
        constructor(left, right) {
            this.type = syntax_1.Syntax.AssignmentPattern;
            this.left = left;
            this.right = right;
        }
    }
    exports.AssignmentPattern = AssignmentPattern;
    class AsyncArrowFunctionExpression {
        constructor(params, body, expression) {
            this.type = syntax_1.Syntax.ArrowFunctionExpression;
            this.id = null;
            this.params = params;
            this.body = body;
            this.generator = false;
            this.expression = expression;
            this.async = true;
        }
    }
    exports.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression;
    class AsyncFunctionDeclaration {
        constructor(id, params, body, generator) {
            this.type = syntax_1.Syntax.FunctionDeclaration;
            this.id = id;
            this.params = params;
            this.body = body;
            this.generator = generator;
            this.expression = false;
            this.async = true;
        }
    }
    exports.AsyncFunctionDeclaration = AsyncFunctionDeclaration;
    class AsyncFunctionExpression {
        constructor(id, params, body, generator) {
            this.type = syntax_1.Syntax.FunctionExpression;
            this.id = id;
            this.params = params;
            this.body = body;
            this.generator = generator;
            this.expression = false;
            this.async = true;
        }
    }
    exports.AsyncFunctionExpression = AsyncFunctionExpression;
    class AwaitExpression {
        constructor(argument) {
            this.type = syntax_1.Syntax.AwaitExpression;
            this.argument = argument;
        }
    }
    exports.AwaitExpression = AwaitExpression;
    class BigIntLiteral {
        constructor(value, bigint, raw) {
            this.type = syntax_1.Syntax.Literal;
            this.value = value;
            this.bigint = bigint;
            this.raw = raw;
        }
    }
    exports.BigIntLiteral = BigIntLiteral;
    class BinaryExpression {
        constructor(operator, left, right) {
            const logical = (operator === '||' || operator === '&&');
            this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression;
            this.operator = operator;
            this.left = left;
            this.right = right;
        }
    }
    exports.BinaryExpression = BinaryExpression;
    class BlockStatement {
        constructor(body) {
            this.type = syntax_1.Syntax.BlockStatement;
            this.body = body;
        }
    }
    exports.BlockStatement = BlockStatement;
    class BreakStatement {
        constructor(label) {
            this.type = syntax_1.Syntax.BreakStatement;
            this.label = label;
        }
    }
    exports.BreakStatement = BreakStatement;
    class CallExpression {
        constructor(callee, args) {
            this.type = syntax_1.Syntax.CallExpression;
            this.callee = callee;
            this.arguments = args;
        }
    }
    exports.CallExpression = CallExpression;
    class CatchClause {
        constructor(param, body) {
            this.type = syntax_1.Syntax.CatchClause;
            this.param = param;
            this.body = body;
        }
    }
    exports.CatchClause = CatchClause;
    class ClassBody {
        constructor(body) {
            this.type = syntax_1.Syntax.ClassBody;
            this.body = body;
        }
    }
    exports.ClassBody = ClassBody;
    class ClassDeclaration {
        constructor(id, superClass, body) {
            this.type = syntax_1.Syntax.ClassDeclaration;
            this.id = id;
            this.superClass = superClass;
            this.body = body;
        }
    }
    exports.ClassDeclaration = ClassDeclaration;
    class ClassExpression {
        constructor(id, superClass, body) {
            this.type = syntax_1.Syntax.ClassExpression;
            this.id = id;
            this.superClass = superClass;
            this.body = body;
        }
    }
    exports.ClassExpression = ClassExpression;
    class ComputedMemberExpression {
        constructor(object, property) {
            this.type = syntax_1.Syntax.MemberExpression;
            this.computed = true;
            this.object = object;
            this.property = property;
        }
    }
    exports.ComputedMemberExpression = ComputedMemberExpression;
    class ConditionalExpression {
        constructor(test, consequent, alternate) {
            this.type = syntax_1.Syntax.ConditionalExpression;
            this.test = test;
            this.consequent = consequent;
            this.alternate = alternate;
        }
    }
    exports.ConditionalExpression = ConditionalExpression;
    class ContinueStatement {
        constructor(label) {
            this.type = syntax_1.Syntax.ContinueStatement;
            this.label = label;
        }
    }
    exports.ContinueStatement = ContinueStatement;
    class DebuggerStatement {
        constructor() {
            this.type = syntax_1.Syntax.DebuggerStatement;
        }
    }
    exports.DebuggerStatement = DebuggerStatement;
    class Directive {
        constructor(expression, directive) {
            this.type = syntax_1.Syntax.ExpressionStatement;
            this.expression = expression;
            this.directive = directive;
        }
    }
    exports.Directive = Directive;
    class DoWhileStatement {
        constructor(body, test) {
            this.type = syntax_1.Syntax.DoWhileStatement;
            this.body = body;
            this.test = test;
        }
    }
    exports.DoWhileStatement = DoWhileStatement;
    class EmptyStatement {
        constructor() {
            this.type = syntax_1.Syntax.EmptyStatement;
        }
    }
    exports.EmptyStatement = EmptyStatement;
    class ExportAllDeclaration {
        constructor(source) {
            this.type = syntax_1.Syntax.ExportAllDeclaration;
            this.source = source;
        }
    }
    exports.ExportAllDeclaration = ExportAllDeclaration;
    class ExportDefaultDeclaration {
        constructor(declaration) {
            this.type = syntax_1.Syntax.ExportDefaultDeclaration;
            this.declaration = declaration;
        }
    }
    exports.ExportDefaultDeclaration = ExportDefaultDeclaration;
    class ExportNamedDeclaration {
        constructor(declaration, specifiers, source) {
            this.type = syntax_1.Syntax.ExportNamedDeclaration;
            this.declaration = declaration;
            this.specifiers = specifiers;
            this.source = source;
        }
    }
    exports.ExportNamedDeclaration = ExportNamedDeclaration;
    class ExportSpecifier {
        constructor(local, exported) {
            this.type = syntax_1.Syntax.ExportSpecifier;
            this.exported = exported;
            this.local = local;
        }
    }
    exports.ExportSpecifier = ExportSpecifier;
    class ExpressionStatement {
        constructor(expression) {
            this.type = syntax_1.Syntax.ExpressionStatement;
            this.expression = expression;
        }
    }
    exports.ExpressionStatement = ExpressionStatement;
    class ForInStatement {
        constructor(left, right, body) {
            this.type = syntax_1.Syntax.ForInStatement;
            this.left = left;
            this.right = right;
            this.body = body;
            this.each = false;
        }
    }
    exports.ForInStatement = ForInStatement;
    class ForOfStatement {
        constructor(left, right, body, isAwait) {
            this.type = syntax_1.Syntax.ForOfStatement;
            this.left = left;
            this.right = right;
            this.body = body;
            this.await = isAwait;
        }
    }
    exports.ForOfStatement = ForOfStatement;
    class ForStatement {
        constructor(init, test, update, body) {
            this.type = syntax_1.Syntax.ForStatement;
            this.init = init;
            this.test = test;
            this.update = update;
            this.body = body;
        }
    }
    exports.ForStatement = ForStatement;
    class FunctionDeclaration {
        constructor(id, params, body, generator) {
            this.type = syntax_1.Syntax.FunctionDeclaration;
            this.id = id;
            this.params = params;
            this.body = body;
            this.generator = generator;
            this.expression = false;
            this.async = false;
        }
    }
    exports.FunctionDeclaration = FunctionDeclaration;
    class FunctionExpression {
        constructor(id, params, body, generator) {
            this.type = syntax_1.Syntax.FunctionExpression;
            this.id = id;
            this.params = params;
            this.body = body;
            this.generator = generator;
            this.expression = false;
            this.async = false;
        }
    }
    exports.FunctionExpression = FunctionExpression;
    class Identifier {
        constructor(name) {
            this.type = syntax_1.Syntax.Identifier;
            this.name = name;
        }
    }
    exports.Identifier = Identifier;
    class IfStatement {
        constructor(test, consequent, alternate) {
            this.type = syntax_1.Syntax.IfStatement;
            this.test = test;
            this.consequent = consequent;
            this.alternate = alternate;
        }
    }
    exports.IfStatement = IfStatement;
    class Import {
        constructor() {
            this.type = syntax_1.Syntax.Import;
        }
    }
    exports.Import = Import;
    class ImportDeclaration {
        constructor(specifiers, source) {
            this.type = syntax_1.Syntax.ImportDeclaration;
            this.specifiers = specifiers;
            this.source = source;
        }
    }
    exports.ImportDeclaration = ImportDeclaration;
    class ImportDefaultSpecifier {
        constructor(local) {
            this.type = syntax_1.Syntax.ImportDefaultSpecifier;
            this.local = local;
        }
    }
    exports.ImportDefaultSpecifier = ImportDefaultSpecifier;
    class ImportNamespaceSpecifier {
        constructor(local) {
            this.type = syntax_1.Syntax.ImportNamespaceSpecifier;
            this.local = local;
        }
    }
    exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier;
    class ImportSpecifier {
        constructor(local, imported) {
            this.type = syntax_1.Syntax.ImportSpecifier;
            this.local = local;
            this.imported = imported;
        }
    }
    exports.ImportSpecifier = ImportSpecifier;
    class LabeledStatement {
        constructor(label, body) {
            this.type = syntax_1.Syntax.LabeledStatement;
            this.label = label;
            this.body = body;
        }
    }
    exports.LabeledStatement = LabeledStatement;
    class Literal {
        constructor(value, raw) {
            this.type = syntax_1.Syntax.Literal;
            this.value = value;
            this.raw = raw;
        }
    }
    exports.Literal = Literal;
    class MetaProperty {
        constructor(meta, property) {
            this.type = syntax_1.Syntax.MetaProperty;
            this.meta = meta;
            this.property = property;
        }
    }
    exports.MetaProperty = MetaProperty;
    class MethodDefinition {
        constructor(key, computed, value, kind, isStatic) {
            this.type = syntax_1.Syntax.MethodDefinition;
            this.key = key;
            this.computed = computed;
            this.value = value;
            this.kind = kind;
            this.static = isStatic;
        }
    }
    exports.MethodDefinition = MethodDefinition;
    class Module {
        constructor(body) {
            this.type = syntax_1.Syntax.Program;
            this.body = body;
            this.sourceType = 'module';
        }
    }
    exports.Module = Module;
    class NewExpression {
        constructor(callee, args) {
            this.type = syntax_1.Syntax.NewExpression;
            this.callee = callee;
            this.arguments = args;
        }
    }
    exports.NewExpression = NewExpression;
    class ObjectExpression {
        constructor(properties) {
            this.type = syntax_1.Syntax.ObjectExpression;
            this.properties = properties;
        }
    }
    exports.ObjectExpression = ObjectExpression;
    class ObjectPattern {
        constructor(properties) {
            this.type = syntax_1.Syntax.ObjectPattern;
            this.properties = properties;
        }
    }
    exports.ObjectPattern = ObjectPattern;
    class Property {
        constructor(kind, key, computed, value, method, shorthand) {
            this.type = syntax_1.Syntax.Property;
            this.key = key;
            this.computed = computed;
            this.value = value;
            this.kind = kind;
            this.method = method;
            this.shorthand = shorthand;
        }
    }
    exports.Property = Property;
    class RegexLiteral {
        constructor(value, raw, pattern, flags) {
            this.type = syntax_1.Syntax.Literal;
            this.value = value;
            this.raw = raw;
            this.regex = { pattern, flags };
        }
    }
    exports.RegexLiteral = RegexLiteral;
    class RestElement {
        constructor(argument) {
            this.type = syntax_1.Syntax.RestElement;
            this.argument = argument;
        }
    }
    exports.RestElement = RestElement;
    class ReturnStatement {
        constructor(argument) {
            this.type = syntax_1.Syntax.ReturnStatement;
            this.argument = argument;
        }
    }
    exports.ReturnStatement = ReturnStatement;
    class Script {
        constructor(body) {
            this.type = syntax_1.Syntax.Program;
            this.body = body;
            this.sourceType = 'script';
        }
    }
    exports.Script = Script;
    class SequenceExpression {
        constructor(expressions) {
            this.type = syntax_1.Syntax.SequenceExpression;
            this.expressions = expressions;
        }
    }
    exports.SequenceExpression = SequenceExpression;
    class SpreadElement {
        constructor(argument) {
            this.type = syntax_1.Syntax.SpreadElement;
            this.argument = argument;
        }
    }
    exports.SpreadElement = SpreadElement;
    class StaticMemberExpression {
        constructor(object, property) {
            this.type = syntax_1.Syntax.MemberExpression;
            this.computed = false;
            this.object = object;
            this.property = property;
        }
    }
    exports.StaticMemberExpression = StaticMemberExpression;
    class Super {
        constructor() {
            this.type = syntax_1.Syntax.Super;
        }
    }
    exports.Super = Super;
    class SwitchCase {
        constructor(test, consequent) {
            this.type = syntax_1.Syntax.SwitchCase;
            this.test = test;
            this.consequent = consequent;
        }
    }
    exports.SwitchCase = SwitchCase;
    class SwitchStatement {
        constructor(discriminant, cases) {
            this.type = syntax_1.Syntax.SwitchStatement;
            this.discriminant = discriminant;
            this.cases = cases;
        }
    }
    exports.SwitchStatement = SwitchStatement;
    class TaggedTemplateExpression {
        constructor(tag, quasi) {
            this.type = syntax_1.Syntax.TaggedTemplateExpression;
            this.tag = tag;
            this.quasi = quasi;
        }
    }
    exports.TaggedTemplateExpression = TaggedTemplateExpression;
    class TemplateElement {
        constructor(value, tail) {
            this.type = syntax_1.Syntax.TemplateElement;
            this.value = value;
            this.tail = tail;
        }
    }
    exports.TemplateElement = TemplateElement;
    class TemplateLiteral {
        constructor(quasis, expressions) {
            this.type = syntax_1.Syntax.TemplateLiteral;
            this.quasis = quasis;
            this.expressions = expressions;
        }
    }
    exports.TemplateLiteral = TemplateLiteral;
    class ThisExpression {
        constructor() {
            this.type = syntax_1.Syntax.ThisExpression;
        }
    }
    exports.ThisExpression = ThisExpression;
    class ThrowStatement {
        constructor(argument) {
            this.type = syntax_1.Syntax.ThrowStatement;
            this.argument = argument;
        }
    }
    exports.ThrowStatement = ThrowStatement;
    class TryStatement {
        constructor(block, handler, finalizer) {
            this.type = syntax_1.Syntax.TryStatement;
            this.block = block;
            this.handler = handler;
            this.finalizer = finalizer;
        }
    }
    exports.TryStatement = TryStatement;
    class UnaryExpression {
        constructor(operator, argument) {
            this.type = syntax_1.Syntax.UnaryExpression;
            this.operator = operator;
            this.argument = argument;
            this.prefix = true;
        }
    }
    exports.UnaryExpression = UnaryExpression;
    class UpdateExpression {
        constructor(operator, argument, prefix) {
            this.type = syntax_1.Syntax.UpdateExpression;
            this.operator = operator;
            this.argument = argument;
            this.prefix = prefix;
        }
    }
    exports.UpdateExpression = UpdateExpression;
    class VariableDeclaration {
        constructor(declarations, kind) {
            this.type = syntax_1.Syntax.VariableDeclaration;
            this.declarations = declarations;
            this.kind = kind;
        }
    }
    exports.VariableDeclaration = VariableDeclaration;
    class VariableDeclarator {
        constructor(id, init) {
            this.type = syntax_1.Syntax.VariableDeclarator;
            this.id = id;
            this.init = init;
        }
    }
    exports.VariableDeclarator = VariableDeclarator;
    class WhileStatement {
        constructor(test, body) {
            this.type = syntax_1.Syntax.WhileStatement;
            this.test = test;
            this.body = body;
        }
    }
    exports.WhileStatement = WhileStatement;
    class WithStatement {
        constructor(object, body) {
            this.type = syntax_1.Syntax.WithStatement;
            this.object = object;
            this.body = body;
        }
    }
    exports.WithStatement = WithStatement;
    class YieldExpression {
        constructor(argument, delegate) {
            this.type = syntax_1.Syntax.YieldExpression;
            this.argument = argument;
            this.delegate = delegate;
        }
    }
    exports.YieldExpression = YieldExpression;


/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const assert_1 = __webpack_require__(9);
    const error_handler_1 = __webpack_require__(10);
    const messages_1 = __webpack_require__(11);
    const Node = __webpack_require__(7);
    const scanner_1 = __webpack_require__(12);
    const syntax_1 = __webpack_require__(2);
    const token_1 = __webpack_require__(13);
    const ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder';
    class Parser {
        constructor(code, options = {}, delegate) {
            this.config = {
                range: (typeof options.range === 'boolean') && options.range,
                loc: (typeof options.loc === 'boolean') && options.loc,
                source: null,
                tokens: (typeof options.tokens === 'boolean') && options.tokens,
                comment: (typeof options.comment === 'boolean') && options.comment,
                tolerant: (typeof options.tolerant === 'boolean') && options.tolerant
            };
            if (this.config.loc && options.source && options.source !== null) {
                this.config.source = String(options.source);
            }
            this.delegate = delegate;
            this.errorHandler = new error_handler_1.ErrorHandler();
            this.errorHandler.tolerant = this.config.tolerant;
            this.scanner = new scanner_1.Scanner(code, this.errorHandler);
            this.scanner.trackComment = this.config.comment;
            this.operatorPrecedence = {
                ')': 0,
                ';': 0,
                ',': 0,
                '=': 0,
                ']': 0,
                '||': 1,
                '&&': 2,
                '|': 3,
                '^': 4,
                '&': 5,
                '==': 6,
                '!=': 6,
                '===': 6,
                '!==': 6,
                '<': 7,
                '>': 7,
                '<=': 7,
                '>=': 7,
                '<<': 8,
                '>>': 8,
                '>>>': 8,
                '+': 9,
                '-': 9,
                '*': 11,
                '/': 11,
                '%': 11
            };
            this.lookahead = {
                type: 2 /* EOF */,
                value: '',
                lineNumber: this.scanner.lineNumber,
                lineStart: 0,
                start: 0,
                end: 0
            };
            this.hasLineTerminator = false;
            this.context = {
                isModule: false,
                await: false,
                allowIn: true,
                allowStrictDirective: true,
                allowYield: true,
                firstCoverInitializedNameError: null,
                isAssignmentTarget: false,
                isBindingElement: false,
                inFunctionBody: false,
                inIteration: false,
                inSwitch: false,
                labelSet: {},
                strict: false
            };
            this.tokens = [];
            this.startMarker = {
                index: 0,
                line: this.scanner.lineNumber,
                column: 0
            };
            this.lastMarker = {
                index: 0,
                line: this.scanner.lineNumber,
                column: 0
            };
            this.nextToken();
            this.lastMarker = {
                index: this.scanner.index,
                line: this.scanner.lineNumber,
                column: this.scanner.index - this.scanner.lineStart
            };
        }
        throwError(messageFormat, ...values) {
            const args = Array.prototype.slice.call(arguments, 1);
            const msg = messageFormat.replace(/%(\d)/g, (whole, idx) => {
                assert_1.assert(idx < args.length, 'Message reference must be in range');
                return args[idx];
            });
            const index = this.lastMarker.index;
            const line = this.lastMarker.line;
            const column = this.lastMarker.column + 1;
            throw this.errorHandler.createError(index, line, column, msg);
        }
        tolerateError(messageFormat, ...values) {
            const args = Array.prototype.slice.call(arguments, 1);
            const msg = messageFormat.replace(/%(\d)/g, (whole, idx) => {
                assert_1.assert(idx < args.length, 'Message reference must be in range');
                return args[idx];
            });
            const index = this.lastMarker.index;
            const line = this.scanner.lineNumber;
            const column = this.lastMarker.column + 1;
            this.errorHandler.tolerateError(index, line, column, msg);
        }
        // Throw an exception because of the token.
        unexpectedTokenError(token, message) {
            let msg = message || messages_1.Messages.UnexpectedToken;
            let value;
            if (token) {
                if (!message) {
                    msg = (token.type === 2 /* EOF */) ? messages_1.Messages.UnexpectedEOS :
                        (token.type === 3 /* Identifier */) ? messages_1.Messages.UnexpectedIdentifier :
                            (token.type === 6 /* NumericLiteral */) ? messages_1.Messages.UnexpectedNumber :
                                (token.type === 8 /* StringLiteral */) ? messages_1.Messages.UnexpectedString :
                                    (token.type === 10 /* Template */) ? messages_1.Messages.UnexpectedTemplate :
                                        messages_1.Messages.UnexpectedToken;
                    if (token.type === 4 /* Keyword */) {
                        if (this.scanner.isFutureReservedWord(token.value)) {
                            msg = messages_1.Messages.UnexpectedReserved;
                        }
                        else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) {
                            msg = messages_1.Messages.StrictReservedWord;
                        }
                    }
                }
                value = token.value;
            }
            else {
                value = 'ILLEGAL';
            }
            msg = msg.replace('%0', value);
            if (token && typeof token.lineNumber === 'number') {
                const index = token.start;
                const line = token.lineNumber;
                const lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column;
                const column = token.start - lastMarkerLineStart + 1;
                return this.errorHandler.createError(index, line, column, msg);
            }
            else {
                const index = this.lastMarker.index;
                const line = this.lastMarker.line;
                const column = this.lastMarker.column + 1;
                return this.errorHandler.createError(index, line, column, msg);
            }
        }
        throwUnexpectedToken(token, message) {
            throw this.unexpectedTokenError(token, message);
        }
        tolerateUnexpectedToken(token, message) {
            this.errorHandler.tolerate(this.unexpectedTokenError(token, message));
        }
        collectComments() {
            if (!this.config.comment) {
                this.scanner.scanComments();
            }
            else {
                const comments = this.scanner.scanComments();
                if (comments.length > 0 && this.delegate) {
                    for (let i = 0; i < comments.length; ++i) {
                        const e = comments[i];
                        let node;
                        node = {
                            type: e.multiLine ? 'BlockComment' : 'LineComment',
                            value: this.scanner.source.slice(e.slice[0], e.slice[1])
                        };
                        if (this.config.range) {
                            node.range = e.range;
                        }
                        if (this.config.loc) {
                            node.loc = e.loc;
                        }
                        const metadata = {
                            start: {
                                line: e.loc.start.line,
                                column: e.loc.start.column,
                                offset: e.range[0]
                            },
                            end: {
                                line: e.loc.end.line,
                                column: e.loc.end.column,
                                offset: e.range[1]
                            }
                        };
                        this.delegate(node, metadata);
                    }
                }
            }
        }
        // From internal representation to an external structure
        getTokenRaw(token) {
            return this.scanner.source.slice(token.start, token.end);
        }
        convertToken(token) {
            const t = {
                type: token_1.TokenName[token.type],
                value: this.getTokenRaw(token)
            };
            if (this.config.range) {
                t.range = [token.start, token.end];
            }
            if (this.config.loc) {
                t.loc = {
                    start: {
                        line: this.startMarker.line,
                        column: this.startMarker.column
                    },
                    end: {
                        line: this.scanner.lineNumber,
                        column: this.scanner.index - this.scanner.lineStart
                    }
                };
            }
            if (token.type === 9 /* RegularExpression */) {
                const pattern = token.pattern;
                const flags = token.flags;
                t.regex = { pattern, flags };
            }
            return t;
        }
        nextToken() {
            const token = this.lookahead;
            this.lastMarker.index = this.scanner.index;
            this.lastMarker.line = this.scanner.lineNumber;
            this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
            this.collectComments();
            if (this.scanner.index !== this.startMarker.index) {
                this.startMarker.index = this.scanner.index;
                this.startMarker.line = this.scanner.lineNumber;
                this.startMarker.column = this.scanner.index - this.scanner.lineStart;
            }
            const next = this.scanner.lex();
            this.hasLineTerminator = (token.lineNumber !== next.lineNumber);
            if (next && this.context.strict && next.type === 3 /* Identifier */) {
                if (this.scanner.isStrictModeReservedWord(next.value)) {
                    next.type = 4 /* Keyword */;
                }
            }
            this.lookahead = next;
            if (this.config.tokens && next.type !== 2 /* EOF */) {
                this.tokens.push(this.convertToken(next));
            }
            return token;
        }
        nextRegexToken() {
            this.collectComments();
            const token = this.scanner.scanRegExp();
            if (this.config.tokens) {
                // Pop the previous token, '/' or '/='
                // This is added from the lookahead token.
                this.tokens.pop();
                this.tokens.push(this.convertToken(token));
            }
            // Prime the next lookahead.
            this.lookahead = token;
            this.nextToken();
            return token;
        }
        createNode() {
            return {
                index: this.startMarker.index,
                line: this.startMarker.line,
                column: this.startMarker.column
            };
        }
        startNode(token, lastLineStart = 0) {
            let column = token.start - token.lineStart;
            let line = token.lineNumber;
            if (column < 0) {
                column += lastLineStart;
                line--;
            }
            return {
                index: token.start,
                line: line,
                column: column
            };
        }
        finalize(marker, node) {
            if (this.config.range) {
                node.range = [marker.index, this.lastMarker.index];
            }
            if (this.config.loc) {
                node.loc = {
                    start: {
                        line: marker.line,
                        column: marker.column,
                    },
                    end: {
                        line: this.lastMarker.line,
                        column: this.lastMarker.column
                    }
                };
                if (this.config.source) {
                    node.loc.source = this.config.source;
                }
            }
            if (this.delegate) {
                const metadata = {
                    start: {
                        line: marker.line,
                        column: marker.column,
                        offset: marker.index
                    },
                    end: {
                        line: this.lastMarker.line,
                        column: this.lastMarker.column,
                        offset: this.lastMarker.index
                    }
                };
                this.delegate(node, metadata);
            }
            return node;
        }
        // Expect the next token to match the specified punctuator.
        // If not, an exception will be thrown.
        expect(value) {
            const token = this.nextToken();
            if (token.type !== 7 /* Punctuator */ || token.value !== value) {
                this.throwUnexpectedToken(token);
            }
        }
        // Quietly expect a comma when in tolerant mode, otherwise delegates to expect().
        expectCommaSeparator() {
            if (this.config.tolerant) {
                const token = this.lookahead;
                if (token.type === 7 /* Punctuator */ && token.value === ',') {
                    this.nextToken();
                }
                else if (token.type === 7 /* Punctuator */ && token.value === ';') {
                    this.nextToken();
                    this.tolerateUnexpectedToken(token);
                }
                else {
                    this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken);
                }
            }
            else {
                this.expect(',');
            }
        }
        // Expect the next token to match the specified keyword.
        // If not, an exception will be thrown.
        expectKeyword(keyword) {
            const token = this.nextToken();
            if (token.type !== 4 /* Keyword */ || token.value !== keyword) {
                this.throwUnexpectedToken(token);
            }
        }
        // Return true if the next token matches the specified punctuator.
        match(value) {
            return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value;
        }
        // Return true if the next token matches the specified keyword
        matchKeyword(keyword) {
            return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword;
        }
        // Return true if the next token matches the specified contextual keyword
        // (where an identifier is sometimes a keyword depending on the context)
        matchContextualKeyword(keyword) {
            return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword;
        }
        // Return true if the next token is an assignment operator
        matchAssign() {
            if (this.lookahead.type !== 7 /* Punctuator */) {
                return false;
            }
            const op = this.lookahead.value;
            return op === '=' ||
                op === '*=' ||
                op === '**=' ||
                op === '/=' ||
                op === '%=' ||
                op === '+=' ||
                op === '-=' ||
                op === '<<=' ||
                op === '>>=' ||
                op === '>>>=' ||
                op === '&=' ||
                op === '^=' ||
                op === '|=';
        }
        // Cover grammar support.
        //
        // When an assignment expression position starts with an left parenthesis, the determination of the type
        // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
        // or the first comma. This situation also defers the determination of all the expressions nested in the pair.
        //
        // There are three productions that can be parsed in a parentheses pair that needs to be determined
        // after the outermost pair is closed. They are:
        //
        //   1. AssignmentExpression
        //   2. BindingElements
        //   3. AssignmentTargets
        //
        // In order to avoid exponential backtracking, we use two flags to denote if the production can be
        // binding element or assignment target.
        //
        // The three productions have the relationship:
        //
        //   BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression
        //
        // with a single exception that CoverInitializedName when used directly in an Expression, generates
        // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
        // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
        //
        // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
        // effect the current flags. This means the production the parser parses is only used as an expression. Therefore
        // the CoverInitializedName check is conducted.
        //
        // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
        // the flags outside of the parser. This means the production the parser parses is used as a part of a potential
        // pattern. The CoverInitializedName check is deferred.
        isolateCoverGrammar(parseFunction) {
            const previousIsBindingElement = this.context.isBindingElement;
            const previousIsAssignmentTarget = this.context.isAssignmentTarget;
            const previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError;
            this.context.isBindingElement = true;
            this.context.isAssignmentTarget = true;
            this.context.firstCoverInitializedNameError = null;
            const result = parseFunction.call(this);
            if (this.context.firstCoverInitializedNameError !== null) {
                this.throwUnexpectedToken(this.context.firstCoverInitializedNameError);
            }
            this.context.isBindingElement = previousIsBindingElement;
            this.context.isAssignmentTarget = previousIsAssignmentTarget;
            this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError;
            return result;
        }
        inheritCoverGrammar(parseFunction) {
            const previousIsBindingElement = this.context.isBindingElement;
            const previousIsAssignmentTarget = this.context.isAssignmentTarget;
            const previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError;
            this.context.isBindingElement = true;
            this.context.isAssignmentTarget = true;
            this.context.firstCoverInitializedNameError = null;
            const result = parseFunction.call(this);
            this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement;
            this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget;
            this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError;
            return result;
        }
        consumeSemicolon() {
            if (this.match(';')) {
                this.nextToken();
            }
            else if (!this.hasLineTerminator) {
                if (this.lookahead.type !== 2 /* EOF */ && !this.match('}')) {
                    this.throwUnexpectedToken(this.lookahead);
                }
                this.lastMarker.index = this.startMarker.index;
                this.lastMarker.line = this.startMarker.line;
                this.lastMarker.column = this.startMarker.column;
            }
        }
        // https://tc39.github.io/ecma262/#sec-primary-expression
        parsePrimaryExpression() {
            const node = this.createNode();
            let expr;
            let token, raw;
            switch (this.lookahead.type) {
                case 3 /* Identifier */:
                    if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') {
                        this.tolerateUnexpectedToken(this.lookahead);
                    }
                    expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value));
                    break;
                case 6 /* NumericLiteral */:
                case 8 /* StringLiteral */:
                    if (this.context.strict && this.lookahead.octal) {
                        this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral);
                    }
                    this.context.isAssignmentTarget = false;
                    this.context.isBindingElement = false;
                    token = this.nextToken();
                    raw = this.getTokenRaw(token);
                    if (token.bigint) {
                        const bigintString = token.value !== null ? token.value.toString() : /* istanbul ignore next */ this.scanner.source.slice(token.start, token.end - 1);
                        expr = this.finalize(node, new Node.BigIntLiteral(token.value, bigintString, raw));
                    }
                    else {
                        expr = this.finalize(node, new Node.Literal(token.value, raw));
                    }
                    break;
                case 1 /* BooleanLiteral */:
                    this.context.isAssignmentTarget = false;
                    this.context.isBindingElement = false;
                    token = this.nextToken();
                    raw = this.getTokenRaw(token);
                    expr = this.finalize(node, new Node.Literal(token.value === 'true', raw));
                    break;
                case 5 /* NullLiteral */:
                    this.context.isAssignmentTarget = false;
                    this.context.isBindingElement = false;
                    token = this.nextToken();
                    raw = this.getTokenRaw(token);
                    expr = this.finalize(node, new Node.Literal(null, raw));
                    break;
                case 10 /* Template */:
                    expr = this.parseTemplateLiteral();
                    break;
                case 7 /* Punctuator */:
                    switch (this.lookahead.value) {
                        case '(':
                            this.context.isBindingElement = false;
                            expr = this.inheritCoverGrammar(this.parseGroupExpression);
                            break;
                        case '[':
                            expr = this.inheritCoverGrammar(this.parseArrayInitializer);
                            break;
                        case '{':
                            expr = this.inheritCoverGrammar(this.parseObjectInitializer);
                            break;
                        case '/':
                        case '/=':
                            this.context.isAssignmentTarget = false;
                            this.context.isBindingElement = false;
                            this.scanner.index = this.startMarker.index;
                            token = this.nextRegexToken();
                            raw = this.getTokenRaw(token);
                            expr = this.finalize(node, new Node.RegexLiteral(token.regex, raw, token.pattern, token.flags));
                            break;
                        default:
                            expr = this.throwUnexpectedToken(this.nextToken());
                    }
                    break;
                case 4 /* Keyword */:
                    if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) {
                        expr = this.parseIdentifierName();
                    }
                    else if (!this.context.strict && this.matchKeyword('let')) {
                        expr = this.finalize(node, new Node.Identifier(this.nextToken().value));
                    }
                    else {
                        this.context.isAssignmentTarget = false;
                        this.context.isBindingElement = false;
                        if (this.matchKeyword('function')) {
                            expr = this.parseFunctionExpression();
                        }
                        else if (this.matchKeyword('this')) {
                            this.nextToken();
                            expr = this.finalize(node, new Node.ThisExpression());
                        }
                        else if (this.matchKeyword('class')) {
                            expr = this.parseClassExpression();
                        }
                        else if (this.matchImportCall()) {
                            expr = this.parseImportCall();
                        }
                        else {
                            expr = this.throwUnexpectedToken(this.nextToken());
                        }
                    }
                    break;
                default:
                    expr = this.throwUnexpectedToken(this.nextToken());
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-array-initializer
        parseSpreadElement() {
            const node = this.createNode();
            this.expect('...');
            const arg = this.inheritCoverGrammar(this.parseAssignmentExpression);
            return this.finalize(node, new Node.SpreadElement(arg));
        }
        parseArrayInitializer() {
            const node = this.createNode();
            const elements = [];
            this.expect('[');
            while (!this.match(']')) {
                if (this.match(',')) {
                    this.nextToken();
                    elements.push(null);
                }
                else if (this.match('...')) {
                    const element = this.parseSpreadElement();
                    if (!this.match(']')) {
                        this.context.isAssignmentTarget = false;
                        this.context.isBindingElement = false;
                        this.expect(',');
                    }
                    elements.push(element);
                }
                else {
                    elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
                    if (!this.match(']')) {
                        this.expect(',');
                    }
                }
            }
            this.expect(']');
            return this.finalize(node, new Node.ArrayExpression(elements));
        }
        // https://tc39.github.io/ecma262/#sec-object-initializer
        parsePropertyMethod(params) {
            this.context.isAssignmentTarget = false;
            this.context.isBindingElement = false;
            const previousStrict = this.context.strict;
            const previousAllowStrictDirective = this.context.allowStrictDirective;
            this.context.allowStrictDirective = params.simple;
            const body = this.isolateCoverGrammar(this.parseFunctionSourceElements);
            if (this.context.strict && params.firstRestricted) {
                this.tolerateUnexpectedToken(params.firstRestricted, params.message);
            }
            if (this.context.strict && params.stricted) {
                this.tolerateUnexpectedToken(params.stricted, params.message);
            }
            this.context.strict = previousStrict;
            this.context.allowStrictDirective = previousAllowStrictDirective;
            return body;
        }
        parsePropertyMethodFunction() {
            const isGenerator = false;
            const node = this.createNode();
            const previousAllowYield = this.context.allowYield;
            this.context.allowYield = true;
            const params = this.parseFormalParameters();
            const method = this.parsePropertyMethod(params);
            this.context.allowYield = previousAllowYield;
            return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
        }
        parsePropertyMethodAsyncFunction(isGenerator) {
            const node = this.createNode();
            const previousAllowYield = this.context.allowYield;
            const previousAwait = this.context.await;
            this.context.allowYield = false;
            this.context.await = true;
            const params = this.parseFormalParameters();
            const method = this.parsePropertyMethod(params);
            this.context.allowYield = previousAllowYield;
            this.context.await = previousAwait;
            return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method, isGenerator));
        }
        parseObjectPropertyKey() {
            const node = this.createNode();
            const token = this.nextToken();
            let key;
            switch (token.type) {
                case 8 /* StringLiteral */:
                case 6 /* NumericLiteral */:
                    if (this.context.strict && token.octal) {
                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral);
                    }
                    const raw = this.getTokenRaw(token);
                    key = this.finalize(node, new Node.Literal(token.value, raw));
                    break;
                case 3 /* Identifier */:
                case 1 /* BooleanLiteral */:
                case 5 /* NullLiteral */:
                case 4 /* Keyword */:
                    key = this.finalize(node, new Node.Identifier(token.value));
                    break;
                case 7 /* Punctuator */:
                    if (token.value === '[') {
                        key = this.isolateCoverGrammar(this.parseAssignmentExpression);
                        this.expect(']');
                    }
                    else {
                        key = this.throwUnexpectedToken(token);
                    }
                    break;
                default:
                    key = this.throwUnexpectedToken(token);
            }
            return key;
        }
        isPropertyKey(key, value) {
            return (key.type === syntax_1.Syntax.Identifier && key.name === value) ||
                (key.type === syntax_1.Syntax.Literal && key.value === value);
        }
        parseObjectProperty(hasProto) {
            const node = this.createNode();
            const token = this.lookahead;
            let kind;
            let key = null;
            let value = null;
            let computed = false;
            let method = false;
            let shorthand = false;
            let isAsync = false;
            let isAsyncGenerator = false;
            if (token.type === 3 /* Identifier */) {
                const id = token.value;
                this.nextToken();
                computed = this.match('[');
                isAsync = !this.hasLineTerminator && (id === 'async') && !this.match(':') && !this.match('(') && !this.match(',');
                isAsyncGenerator = this.match('*');
                if (isAsyncGenerator) {
                    this.nextToken();
                }
                key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Node.Identifier(id));
            }
            else if (this.match('*')) {
                this.nextToken();
            }
            else {
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
            }
            const lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead);
            if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'get' && lookaheadPropertyKey) {
                kind = 'get';
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
                this.context.allowYield = false;
                value = this.parseGetterMethod();
            }
            else if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'set' && lookaheadPropertyKey) {
                kind = 'set';
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
                value = this.parseSetterMethod();
            }
            else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) {
                kind = 'init';
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
                value = this.parseGeneratorMethod();
                method = true;
            }
            else {
                if (!key) {
                    this.throwUnexpectedToken(this.lookahead);
                }
                kind = 'init';
                if (this.match(':') && !isAsync) {
                    if (!computed && this.isPropertyKey(key, '__proto__')) {
                        if (hasProto.value) {
                            this.tolerateError(messages_1.Messages.DuplicateProtoProperty);
                        }
                        hasProto.value = true;
                    }
                    this.nextToken();
                    value = this.inheritCoverGrammar(this.parseAssignmentExpression);
                }
                else if (this.match('(')) {
                    value = isAsync ? this.parsePropertyMethodAsyncFunction(isAsyncGenerator) : this.parsePropertyMethodFunction();
                    method = true;
                }
                else if (token.type === 3 /* Identifier */) {
                    const id = this.finalize(node, new Node.Identifier(token.value));
                    if (this.match('=')) {
                        this.context.firstCoverInitializedNameError = this.lookahead;
                        this.nextToken();
                        shorthand = true;
                        const init = this.isolateCoverGrammar(this.parseAssignmentExpression);
                        value = this.finalize(node, new Node.AssignmentPattern(id, init));
                    }
                    else {
                        shorthand = true;
                        value = id;
                    }
                }
                else {
                    this.throwUnexpectedToken(this.nextToken());
                }
            }
            return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand));
        }
        parseObjectInitializer() {
            const node = this.createNode();
            this.expect('{');
            const properties = [];
            const hasProto = { value: false };
            while (!this.match('}')) {
                properties.push(this.match('...') ? this.parseSpreadElement() : this.parseObjectProperty(hasProto));
                if (!this.match('}')) {
                    this.expectCommaSeparator();
                }
            }
            this.expect('}');
            return this.finalize(node, new Node.ObjectExpression(properties));
        }
        // https://tc39.github.io/ecma262/#sec-template-literals
        parseTemplateHead() {
            assert_1.assert(this.lookahead.head, 'Template literal must start with a template head');
            const node = this.createNode();
            const token = this.nextToken();
            const raw = token.value;
            const cooked = token.cooked;
            return this.finalize(node, new Node.TemplateElement({ raw, cooked }, token.tail));
        }
        parseTemplateElement() {
            if (this.lookahead.type !== 10 /* Template */) {
                this.throwUnexpectedToken();
            }
            const node = this.createNode();
            const token = this.nextToken();
            const raw = token.value;
            const cooked = token.cooked;
            return this.finalize(node, new Node.TemplateElement({ raw, cooked }, token.tail));
        }
        parseTemplateLiteral() {
            const node = this.createNode();
            const expressions = [];
            const quasis = [];
            let quasi = this.parseTemplateHead();
            quasis.push(quasi);
            while (!quasi.tail) {
                expressions.push(this.parseExpression());
                quasi = this.parseTemplateElement();
                quasis.push(quasi);
            }
            return this.finalize(node, new Node.TemplateLiteral(quasis, expressions));
        }
        // https://tc39.github.io/ecma262/#sec-grouping-operator
        reinterpretExpressionAsPattern(expr) {
            switch (expr.type) {
                case syntax_1.Syntax.Identifier:
                case syntax_1.Syntax.MemberExpression:
                case syntax_1.Syntax.RestElement:
                case syntax_1.Syntax.AssignmentPattern:
                    break;
                case syntax_1.Syntax.SpreadElement:
                    expr.type = syntax_1.Syntax.RestElement;
                    this.reinterpretExpressionAsPattern(expr.argument);
                    break;
                case syntax_1.Syntax.ArrayExpression:
                    expr.type = syntax_1.Syntax.ArrayPattern;
                    for (let i = 0; i < expr.elements.length; i++) {
                        if (expr.elements[i] !== null) {
                            this.reinterpretExpressionAsPattern(expr.elements[i]);
                        }
                    }
                    break;
                case syntax_1.Syntax.ObjectExpression:
                    expr.type = syntax_1.Syntax.ObjectPattern;
                    for (let i = 0; i < expr.properties.length; i++) {
                        const property = expr.properties[i];
                        this.reinterpretExpressionAsPattern(property.type === syntax_1.Syntax.SpreadElement ? property : property.value);
                    }
                    break;
                case syntax_1.Syntax.AssignmentExpression:
                    expr.type = syntax_1.Syntax.AssignmentPattern;
                    delete expr.operator;
                    this.reinterpretExpressionAsPattern(expr.left);
                    break;
                default:
                    // Allow other node type for tolerant parsing.
                    break;
            }
        }
        parseGroupExpression() {
            let expr;
            this.expect('(');
            if (this.match(')')) {
                this.nextToken();
                if (!this.match('=>')) {
                    this.expect('=>');
                }
                expr = {
                    type: ArrowParameterPlaceHolder,
                    params: [],
                    async: false
                };
            }
            else {
                const startToken = this.lookahead;
                const params = [];
                if (this.match('...')) {
                    expr = this.parseRestElement(params);
                    this.expect(')');
                    if (!this.match('=>')) {
                        this.expect('=>');
                    }
                    expr = {
                        type: ArrowParameterPlaceHolder,
                        params: [expr],
                        async: false
                    };
                }
                else {
                    let arrow = false;
                    this.context.isBindingElement = true;
                    expr = this.inheritCoverGrammar(this.parseAssignmentExpression);
                    if (this.match(',')) {
                        const expressions = [];
                        this.context.isAssignmentTarget = false;
                        expressions.push(expr);
                        while (this.lookahead.type !== 2 /* EOF */) {
                            if (!this.match(',')) {
                                break;
                            }
                            this.nextToken();
                            if (this.match(')')) {
                                this.nextToken();
                                for (let i = 0; i < expressions.length; i++) {
                                    this.reinterpretExpressionAsPattern(expressions[i]);
                                }
                                arrow = true;
                                expr = {
                                    type: ArrowParameterPlaceHolder,
                                    params: expressions,
                                    async: false
                                };
                            }
                            else if (this.match('...')) {
                                if (!this.context.isBindingElement) {
                                    this.throwUnexpectedToken(this.lookahead);
                                }
                                expressions.push(this.parseRestElement(params));
                                this.expect(')');
                                if (!this.match('=>')) {
                                    this.expect('=>');
                                }
                                this.context.isBindingElement = false;
                                for (let i = 0; i < expressions.length; i++) {
                                    this.reinterpretExpressionAsPattern(expressions[i]);
                                }
                                arrow = true;
                                expr = {
                                    type: ArrowParameterPlaceHolder,
                                    params: expressions,
                                    async: false
                                };
                            }
                            else {
                                expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
                            }
                            if (arrow) {
                                break;
                            }
                        }
                        if (!arrow) {
                            expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions));
                        }
                    }
                    if (!arrow) {
                        this.expect(')');
                        if (this.match('=>')) {
                            if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') {
                                arrow = true;
                                expr = {
                                    type: ArrowParameterPlaceHolder,
                                    params: [expr],
                                    async: false
                                };
                            }
                            if (!arrow) {
                                if (!this.context.isBindingElement) {
                                    this.throwUnexpectedToken(this.lookahead);
                                }
                                if (expr.type === syntax_1.Syntax.SequenceExpression) {
                                    for (let i = 0; i < expr.expressions.length; i++) {
                                        this.reinterpretExpressionAsPattern(expr.expressions[i]);
                                    }
                                }
                                else {
                                    this.reinterpretExpressionAsPattern(expr);
                                }
                                const parameters = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]);
                                expr = {
                                    type: ArrowParameterPlaceHolder,
                                    params: parameters,
                                    async: false
                                };
                            }
                        }
                        this.context.isBindingElement = false;
                    }
                }
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions
        parseArguments() {
            this.expect('(');
            const args = [];
            if (!this.match(')')) {
                while (true) {
                    const expr = this.match('...') ? this.parseSpreadElement() :
                        this.isolateCoverGrammar(this.parseAssignmentExpression);
                    args.push(expr);
                    if (this.match(')')) {
                        break;
                    }
                    this.expectCommaSeparator();
                    if (this.match(')')) {
                        break;
                    }
                }
            }
            this.expect(')');
            return args;
        }
        isIdentifierName(token) {
            return token.type === 3 /* Identifier */ ||
                token.type === 4 /* Keyword */ ||
                token.type === 1 /* BooleanLiteral */ ||
                token.type === 5 /* NullLiteral */;
        }
        parseIdentifierName() {
            const node = this.createNode();
            const token = this.nextToken();
            if (!this.isIdentifierName(token)) {
                this.throwUnexpectedToken(token);
            }
            return this.finalize(node, new Node.Identifier(token.value));
        }
        parseNewExpression() {
            const node = this.createNode();
            const id = this.parseIdentifierName();
            assert_1.assert(id.name === 'new', 'New expression must start with `new`');
            let expr;
            if (this.match('.')) {
                this.nextToken();
                if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === 'target') {
                    const property = this.parseIdentifierName();
                    expr = new Node.MetaProperty(id, property);
                }
                else {
                    this.throwUnexpectedToken(this.lookahead);
                }
            }
            else if (this.matchKeyword('import')) {
                this.throwUnexpectedToken(this.lookahead);
            }
            else {
                const callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression);
                const args = this.match('(') ? this.parseArguments() : [];
                expr = new Node.NewExpression(callee, args);
                this.context.isAssignmentTarget = false;
                this.context.isBindingElement = false;
            }
            return this.finalize(node, expr);
        }
        parseAsyncArgument() {
            const arg = this.parseAssignmentExpression();
            this.context.firstCoverInitializedNameError = null;
            return arg;
        }
        parseAsyncArguments() {
            this.expect('(');
            const args = [];
            if (!this.match(')')) {
                while (true) {
                    const expr = this.match('...') ? this.parseSpreadElement() :
                        this.isolateCoverGrammar(this.parseAsyncArgument);
                    args.push(expr);
                    if (this.match(')')) {
                        break;
                    }
                    this.expectCommaSeparator();
                    if (this.match(')')) {
                        break;
                    }
                }
            }
            this.expect(')');
            return args;
        }
        matchImportCall() {
            let match = this.matchKeyword('import');
            if (match) {
                const state = this.scanner.saveState();
                this.scanner.scanComments();
                const next = this.scanner.lex();
                this.scanner.restoreState(state);
                match = (next.type === 7 /* Punctuator */) && (next.value === '(');
            }
            return match;
        }
        parseImportCall() {
            const node = this.createNode();
            this.expectKeyword('import');
            return this.finalize(node, new Node.Import());
        }
        parseLeftHandSideExpressionAllowCall() {
            const startToken = this.lookahead;
            const maybeAsync = this.matchContextualKeyword('async');
            const previousAllowIn = this.context.allowIn;
            this.context.allowIn = true;
            let expr;
            if (this.matchKeyword('super') && this.context.inFunctionBody) {
                expr = this.createNode();
                this.nextToken();
                expr = this.finalize(expr, new Node.Super());
                if (!this.match('(') && !this.match('.') && !this.match('[')) {
                    this.throwUnexpectedToken(this.lookahead);
                }
            }
            else {
                expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression);
            }
            while (true) {
                if (this.match('.')) {
                    this.context.isBindingElement = false;
                    this.context.isAssignmentTarget = true;
                    this.expect('.');
                    const property = this.parseIdentifierName();
                    expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property));
                }
                else if (this.match('(')) {
                    const asyncArrow = maybeAsync && (startToken.lineNumber === this.lookahead.lineNumber);
                    this.context.isBindingElement = false;
                    this.context.isAssignmentTarget = false;
                    const args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments();
                    if (expr.type === syntax_1.Syntax.Import && args.length !== 1) {
                        this.tolerateError(messages_1.Messages.BadImportCallArity);
                    }
                    expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args));
                    if (asyncArrow && this.match('=>')) {
                        for (let i = 0; i < args.length; ++i) {
                            this.reinterpretExpressionAsPattern(args[i]);
                        }
                        expr = {
                            type: ArrowParameterPlaceHolder,
                            params: args,
                            async: true
                        };
                    }
                }
                else if (this.match('[')) {
                    this.context.isBindingElement = false;
                    this.context.isAssignmentTarget = true;
                    this.expect('[');
                    const property = this.isolateCoverGrammar(this.parseExpression);
                    this.expect(']');
                    expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property));
                }
                else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) {
                    const quasi = this.parseTemplateLiteral();
                    expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi));
                }
                else {
                    break;
                }
            }
            this.context.allowIn = previousAllowIn;
            return expr;
        }
        parseSuper() {
            const node = this.createNode();
            this.expectKeyword('super');
            if (!this.match('[') && !this.match('.')) {
                this.throwUnexpectedToken(this.lookahead);
            }
            return this.finalize(node, new Node.Super());
        }
        parseLeftHandSideExpression() {
            assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.');
            const node = this.startNode(this.lookahead);
            let expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() :
                this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression);
            while (true) {
                if (this.match('[')) {
                    this.context.isBindingElement = false;
                    this.context.isAssignmentTarget = true;
                    this.expect('[');
                    const property = this.isolateCoverGrammar(this.parseExpression);
                    this.expect(']');
                    expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property));
                }
                else if (this.match('.')) {
                    this.context.isBindingElement = false;
                    this.context.isAssignmentTarget = true;
                    this.expect('.');
                    const property = this.parseIdentifierName();
                    expr = this.finalize(node, new Node.StaticMemberExpression(expr, property));
                }
                else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) {
                    const quasi = this.parseTemplateLiteral();
                    expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi));
                }
                else {
                    break;
                }
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-update-expressions
        parseUpdateExpression() {
            let expr;
            const startToken = this.lookahead;
            if (this.match('++') || this.match('--')) {
                const node = this.startNode(startToken);
                const token = this.nextToken();
                expr = this.inheritCoverGrammar(this.parseUnaryExpression);
                if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) {
                    this.tolerateError(messages_1.Messages.StrictLHSPrefix);
                }
                if (!this.context.isAssignmentTarget) {
                    this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
                }
                const prefix = true;
                expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix));
                this.context.isAssignmentTarget = false;
                this.context.isBindingElement = false;
            }
            else {
                expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
                if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) {
                    if (this.match('++') || this.match('--')) {
                        if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) {
                            this.tolerateError(messages_1.Messages.StrictLHSPostfix);
                        }
                        if (!this.context.isAssignmentTarget) {
                            this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
                        }
                        this.context.isAssignmentTarget = false;
                        this.context.isBindingElement = false;
                        const operator = this.nextToken().value;
                        const prefix = false;
                        expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix));
                    }
                }
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-unary-operators
        parseAwaitExpression() {
            const node = this.createNode();
            this.nextToken();
            const argument = this.parseUnaryExpression();
            return this.finalize(node, new Node.AwaitExpression(argument));
        }
        parseUnaryExpression() {
            let expr;
            if (this.match('+') || this.match('-') || this.match('~') || this.match('!') ||
                this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) {
                const node = this.startNode(this.lookahead);
                const token = this.nextToken();
                expr = this.inheritCoverGrammar(this.parseUnaryExpression);
                expr = this.finalize(node, new Node.UnaryExpression(token.value, expr));
                if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) {
                    this.tolerateError(messages_1.Messages.StrictDelete);
                }
                this.context.isAssignmentTarget = false;
                this.context.isBindingElement = false;
            }
            else if (this.context.await && this.matchContextualKeyword('await')) {
                expr = this.parseAwaitExpression();
            }
            else {
                expr = this.parseUpdateExpression();
            }
            return expr;
        }
        parseExponentiationExpression() {
            const startToken = this.lookahead;
            let expr = this.inheritCoverGrammar(this.parseUnaryExpression);
            if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) {
                this.nextToken();
                this.context.isAssignmentTarget = false;
                this.context.isBindingElement = false;
                const left = expr;
                const right = this.isolateCoverGrammar(this.parseExponentiationExpression);
                expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right));
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-exp-operator
        // https://tc39.github.io/ecma262/#sec-multiplicative-operators
        // https://tc39.github.io/ecma262/#sec-additive-operators
        // https://tc39.github.io/ecma262/#sec-bitwise-shift-operators
        // https://tc39.github.io/ecma262/#sec-relational-operators
        // https://tc39.github.io/ecma262/#sec-equality-operators
        // https://tc39.github.io/ecma262/#sec-binary-bitwise-operators
        // https://tc39.github.io/ecma262/#sec-binary-logical-operators
        binaryPrecedence(token) {
            const op = token.value;
            let precedence;
            if (token.type === 7 /* Punctuator */) {
                precedence = this.operatorPrecedence[op] || 0;
            }
            else if (token.type === 4 /* Keyword */) {
                precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0;
            }
            else {
                precedence = 0;
            }
            return precedence;
        }
        parseBinaryExpression() {
            const startToken = this.lookahead;
            let expr = this.inheritCoverGrammar(this.parseExponentiationExpression);
            const token = this.lookahead;
            let prec = this.binaryPrecedence(token);
            if (prec > 0) {
                this.nextToken();
                this.context.isAssignmentTarget = false;
                this.context.isBindingElement = false;
                const markers = [startToken, this.lookahead];
                let left = expr;
                let right = this.isolateCoverGrammar(this.parseExponentiationExpression);
                const stack = [left, token.value, right];
                const precedences = [prec];
                while (true) {
                    prec = this.binaryPrecedence(this.lookahead);
                    if (prec <= 0) {
                        break;
                    }
                    // Reduce: make a binary expression from the three topmost entries.
                    while ((stack.length > 2) && (prec <= precedences[precedences.length - 1])) {
                        right = stack.pop();
                        const operator = stack.pop();
                        precedences.pop();
                        left = stack.pop();
                        markers.pop();
                        const node = this.startNode(markers[markers.length - 1]);
                        stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right)));
                    }
                    // Shift.
                    stack.push(this.nextToken().value);
                    precedences.push(prec);
                    markers.push(this.lookahead);
                    stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression));
                }
                // Final reduce to clean-up the stack.
                let i = stack.length - 1;
                expr = stack[i];
                let lastMarker = markers.pop();
                while (i > 1) {
                    const marker = markers.pop();
                    const lastLineStart = lastMarker && lastMarker.lineStart;
                    const node = this.startNode(marker, lastLineStart);
                    const operator = stack[i - 1];
                    expr = this.finalize(node, new Node.BinaryExpression(operator, stack[i - 2], expr));
                    i -= 2;
                    lastMarker = marker;
                }
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-conditional-operator
        parseConditionalExpression() {
            const startToken = this.lookahead;
            let expr = this.inheritCoverGrammar(this.parseBinaryExpression);
            if (this.match('?')) {
                this.nextToken();
                const previousAllowIn = this.context.allowIn;
                this.context.allowIn = true;
                const consequent = this.isolateCoverGrammar(this.parseAssignmentExpression);
                this.context.allowIn = previousAllowIn;
                this.expect(':');
                const alternate = this.isolateCoverGrammar(this.parseAssignmentExpression);
                expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate));
                this.context.isAssignmentTarget = false;
                this.context.isBindingElement = false;
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-assignment-operators
        checkPatternParam(options, param) {
            switch (param.type) {
                case syntax_1.Syntax.Identifier:
                    this.validateParam(options, param, param.name);
                    break;
                case syntax_1.Syntax.RestElement:
                    this.checkPatternParam(options, param.argument);
                    break;
                case syntax_1.Syntax.AssignmentPattern:
                    this.checkPatternParam(options, param.left);
                    break;
                case syntax_1.Syntax.ArrayPattern:
                    for (let i = 0; i < param.elements.length; i++) {
                        if (param.elements[i] !== null) {
                            this.checkPatternParam(options, param.elements[i]);
                        }
                    }
                    break;
                case syntax_1.Syntax.ObjectPattern:
                    for (let i = 0; i < param.properties.length; i++) {
                        const property = param.properties[i];
                        this.checkPatternParam(options, (property.type === syntax_1.Syntax.RestElement) ? property : property.value);
                    }
                    break;
                default:
                    break;
            }
            options.simple = options.simple && (param instanceof Node.Identifier);
        }
        reinterpretAsCoverFormalsList(expr) {
            let params = [expr];
            let options;
            let asyncArrow = false;
            switch (expr.type) {
                case syntax_1.Syntax.Identifier:
                    break;
                case ArrowParameterPlaceHolder:
                    params = expr.params;
                    asyncArrow = expr.async;
                    break;
                default:
                    return null;
            }
            options = {
                simple: true,
                paramSet: {}
            };
            for (let i = 0; i < params.length; ++i) {
                const param = params[i];
                if (param.type === syntax_1.Syntax.AssignmentPattern) {
                    if (param.right.type === syntax_1.Syntax.YieldExpression) {
                        if (param.right.argument) {
                            this.throwUnexpectedToken(this.lookahead);
                        }
                        param.right.type = syntax_1.Syntax.Identifier;
                        param.right.name = 'yield';
                        delete param.right.argument;
                        delete param.right.delegate;
                    }
                }
                else if (asyncArrow && param.type === syntax_1.Syntax.Identifier && param.name === 'await') {
                    this.throwUnexpectedToken(this.lookahead);
                }
                this.checkPatternParam(options, param);
                params[i] = param;
            }
            if (this.context.strict || !this.context.allowYield) {
                for (let i = 0; i < params.length; ++i) {
                    const param = params[i];
                    if (param.type === syntax_1.Syntax.YieldExpression) {
                        this.throwUnexpectedToken(this.lookahead);
                    }
                }
            }
            if (options.message === messages_1.Messages.StrictParamDupe) {
                const token = this.context.strict ? options.stricted : options.firstRestricted;
                this.throwUnexpectedToken(token, options.message);
            }
            return {
                simple: options.simple,
                params: params,
                stricted: options.stricted,
                firstRestricted: options.firstRestricted,
                message: options.message
            };
        }
        parseAssignmentExpression() {
            let expr;
            if (!this.context.allowYield && this.matchKeyword('yield')) {
                expr = this.parseYieldExpression();
            }
            else {
                const startToken = this.lookahead;
                let token = startToken;
                expr = this.parseConditionalExpression();
                if (token.type === 3 /* Identifier */ && (token.lineNumber === this.lookahead.lineNumber) && token.value === 'async') {
                    if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword('yield')) {
                        const arg = this.parsePrimaryExpression();
                        this.reinterpretExpressionAsPattern(arg);
                        expr = {
                            type: ArrowParameterPlaceHolder,
                            params: [arg],
                            async: true
                        };
                    }
                }
                if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) {
                    // https://tc39.github.io/ecma262/#sec-arrow-function-definitions
                    this.context.isAssignmentTarget = false;
                    this.context.isBindingElement = false;
                    const isAsync = expr.async;
                    const list = this.reinterpretAsCoverFormalsList(expr);
                    if (list) {
                        if (this.hasLineTerminator) {
                            this.tolerateUnexpectedToken(this.lookahead);
                        }
                        this.context.firstCoverInitializedNameError = null;
                        const previousStrict = this.context.strict;
                        const previousAllowStrictDirective = this.context.allowStrictDirective;
                        this.context.allowStrictDirective = list.simple;
                        const previousAllowYield = this.context.allowYield;
                        const previousAwait = this.context.await;
                        this.context.allowYield = true;
                        this.context.await = isAsync;
                        const node = this.startNode(startToken);
                        this.expect('=>');
                        let body;
                        if (this.match('{')) {
                            const previousAllowIn = this.context.allowIn;
                            this.context.allowIn = true;
                            body = this.parseFunctionSourceElements();
                            this.context.allowIn = previousAllowIn;
                        }
                        else {
                            body = this.isolateCoverGrammar(this.parseAssignmentExpression);
                        }
                        const expression = body.type !== syntax_1.Syntax.BlockStatement;
                        if (this.context.strict && list.firstRestricted) {
                            this.throwUnexpectedToken(list.firstRestricted, list.message);
                        }
                        if (this.context.strict && list.stricted) {
                            this.tolerateUnexpectedToken(list.stricted, list.message);
                        }
                        expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) :
                            this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression));
                        this.context.strict = previousStrict;
                        this.context.allowStrictDirective = previousAllowStrictDirective;
                        this.context.allowYield = previousAllowYield;
                        this.context.await = previousAwait;
                    }
                }
                else {
                    if (this.matchAssign()) {
                        if (!this.context.isAssignmentTarget) {
                            this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
                        }
                        if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) {
                            const id = expr;
                            if (this.scanner.isRestrictedWord(id.name)) {
                                this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment);
                            }
                            if (this.scanner.isStrictModeReservedWord(id.name)) {
                                this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
                            }
                        }
                        if (!this.match('=')) {
                            this.context.isAssignmentTarget = false;
                            this.context.isBindingElement = false;
                        }
                        else {
                            this.reinterpretExpressionAsPattern(expr);
                        }
                        token = this.nextToken();
                        const operator = token.value;
                        const right = this.isolateCoverGrammar(this.parseAssignmentExpression);
                        expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(operator, expr, right));
                        this.context.firstCoverInitializedNameError = null;
                    }
                }
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-comma-operator
        parseExpression() {
            const startToken = this.lookahead;
            let expr = this.isolateCoverGrammar(this.parseAssignmentExpression);
            if (this.match(',')) {
                const expressions = [];
                expressions.push(expr);
                while (this.lookahead.type !== 2 /* EOF */) {
                    if (!this.match(',')) {
                        break;
                    }
                    this.nextToken();
                    expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
                }
                expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions));
            }
            return expr;
        }
        // https://tc39.github.io/ecma262/#sec-block
        parseStatementListItem() {
            let statement;
            this.context.isAssignmentTarget = true;
            this.context.isBindingElement = true;
            if (this.lookahead.type === 4 /* Keyword */) {
                switch (this.lookahead.value) {
                    case 'export':
                        if (!this.context.isModule) {
                            this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration);
                        }
                        statement = this.parseExportDeclaration();
                        break;
                    case 'import':
                        if (this.matchImportCall()) {
                            statement = this.parseExpressionStatement();
                        }
                        else {
                            if (!this.context.isModule) {
                                this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration);
                            }
                            statement = this.parseImportDeclaration();
                        }
                        break;
                    case 'const':
                        statement = this.parseLexicalDeclaration({ inFor: false });
                        break;
                    case 'function':
                        statement = this.parseFunctionDeclaration();
                        break;
                    case 'class':
                        statement = this.parseClassDeclaration();
                        break;
                    case 'let':
                        statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement();
                        break;
                    default:
                        statement = this.parseStatement();
                        break;
                }
            }
            else {
                statement = this.parseStatement();
            }
            return statement;
        }
        parseBlock() {
            const node = this.createNode();
            this.expect('{');
            const block = [];
            while (true) {
                if (this.match('}')) {
                    break;
                }
                block.push(this.parseStatementListItem());
            }
            this.expect('}');
            return this.finalize(node, new Node.BlockStatement(block));
        }
        // https://tc39.github.io/ecma262/#sec-let-and-const-declarations
        parseLexicalBinding(kind, options) {
            const node = this.createNode();
            const params = [];
            const id = this.parsePattern(params, kind);
            if (this.context.strict && id.type === syntax_1.Syntax.Identifier) {
                if (this.scanner.isRestrictedWord(id.name)) {
                    this.tolerateError(messages_1.Messages.StrictVarName);
                }
            }
            let init = null;
            if (kind === 'const') {
                if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) {
                    if (this.match('=')) {
                        this.nextToken();
                        init = this.isolateCoverGrammar(this.parseAssignmentExpression);
                    }
                    else {
                        this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const');
                    }
                }
            }
            else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) {
                this.expect('=');
                init = this.isolateCoverGrammar(this.parseAssignmentExpression);
            }
            return this.finalize(node, new Node.VariableDeclarator(id, init));
        }
        parseBindingList(kind, options) {
            const list = [this.parseLexicalBinding(kind, options)];
            while (this.match(',')) {
                this.nextToken();
                list.push(this.parseLexicalBinding(kind, options));
            }
            return list;
        }
        isLexicalDeclaration() {
            const state = this.scanner.saveState();
            this.scanner.scanComments();
            const next = this.scanner.lex();
            this.scanner.restoreState(state);
            return (next.type === 3 /* Identifier */) ||
                (next.type === 7 /* Punctuator */ && next.value === '[') ||
                (next.type === 7 /* Punctuator */ && next.value === '{') ||
                (next.type === 4 /* Keyword */ && next.value === 'let') ||
                (next.type === 4 /* Keyword */ && next.value === 'yield');
        }
        parseLexicalDeclaration(options) {
            const node = this.createNode();
            const kind = this.nextToken().value;
            assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');
            const declarations = this.parseBindingList(kind, options);
            this.consumeSemicolon();
            return this.finalize(node, new Node.VariableDeclaration(declarations, kind));
        }
        // https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns
        parseBindingRestElement(params, kind) {
            const node = this.createNode();
            this.expect('...');
            const arg = this.parsePattern(params, kind);
            return this.finalize(node, new Node.RestElement(arg));
        }
        parseArrayPattern(params, kind) {
            const node = this.createNode();
            this.expect('[');
            const elements = [];
            while (!this.match(']')) {
                if (this.match(',')) {
                    this.nextToken();
                    elements.push(null);
                }
                else {
                    if (this.match('...')) {
                        elements.push(this.parseBindingRestElement(params, kind));
                        break;
                    }
                    else {
                        elements.push(this.parsePatternWithDefault(params, kind));
                    }
                    if (!this.match(']')) {
                        this.expect(',');
                    }
                }
            }
            this.expect(']');
            return this.finalize(node, new Node.ArrayPattern(elements));
        }
        parsePropertyPattern(params, kind) {
            const node = this.createNode();
            let computed = false;
            let shorthand = false;
            const method = false;
            let key;
            let value;
            if (this.lookahead.type === 3 /* Identifier */) {
                const keyToken = this.lookahead;
                key = this.parseVariableIdentifier();
                const init = this.finalize(node, new Node.Identifier(keyToken.value));
                if (this.match('=')) {
                    params.push(keyToken);
                    shorthand = true;
                    this.nextToken();
                    const expr = this.parseAssignmentExpression();
                    value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr));
                }
                else if (!this.match(':')) {
                    params.push(keyToken);
                    shorthand = true;
                    value = init;
                }
                else {
                    this.expect(':');
                    value = this.parsePatternWithDefault(params, kind);
                }
            }
            else {
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
                this.expect(':');
                value = this.parsePatternWithDefault(params, kind);
            }
            return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand));
        }
        parseRestProperty(params, kind) {
            const node = this.createNode();
            this.expect('...');
            const arg = this.parsePattern(params);
            if (this.match('=')) {
                this.throwError(messages_1.Messages.DefaultRestProperty);
            }
            if (!this.match('}')) {
                this.throwError(messages_1.Messages.PropertyAfterRestProperty);
            }
            return this.finalize(node, new Node.RestElement(arg));
        }
        parseObjectPattern(params, kind) {
            const node = this.createNode();
            const properties = [];
            this.expect('{');
            while (!this.match('}')) {
                properties.push(this.match('...') ? this.parseRestProperty(params, kind) : this.parsePropertyPattern(params, kind));
                if (!this.match('}')) {
                    this.expect(',');
                }
            }
            this.expect('}');
            return this.finalize(node, new Node.ObjectPattern(properties));
        }
        parsePattern(params, kind) {
            let pattern;
            if (this.match('[')) {
                pattern = this.parseArrayPattern(params, kind);
            }
            else if (this.match('{')) {
                pattern = this.parseObjectPattern(params, kind);
            }
            else {
                if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) {
                    this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding);
                }
                params.push(this.lookahead);
                pattern = this.parseVariableIdentifier(kind);
            }
            return pattern;
        }
        parsePatternWithDefault(params, kind) {
            const startToken = this.lookahead;
            let pattern = this.parsePattern(params, kind);
            if (this.match('=')) {
                this.nextToken();
                const previousAllowYield = this.context.allowYield;
                this.context.allowYield = true;
                const right = this.isolateCoverGrammar(this.parseAssignmentExpression);
                this.context.allowYield = previousAllowYield;
                pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right));
            }
            return pattern;
        }
        // https://tc39.github.io/ecma262/#sec-variable-statement
        parseVariableIdentifier(kind) {
            const node = this.createNode();
            const token = this.nextToken();
            if (token.type === 4 /* Keyword */ && token.value === 'yield') {
                if (this.context.strict) {
                    this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
                }
                else if (!this.context.allowYield) {
                    this.throwUnexpectedToken(token);
                }
            }
            else if (token.type !== 3 /* Identifier */) {
                if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) {
                    this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
                }
                else {
                    if (this.context.strict || token.value !== 'let' || kind !== 'var') {
                        this.throwUnexpectedToken(token);
                    }
                }
            }
            else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') {
                this.tolerateUnexpectedToken(token);
            }
            return this.finalize(node, new Node.Identifier(token.value));
        }
        parseVariableDeclaration(options) {
            const node = this.createNode();
            const params = [];
            const id = this.parsePattern(params, 'var');
            if (this.context.strict && id.type === syntax_1.Syntax.Identifier) {
                if (this.scanner.isRestrictedWord(id.name)) {
                    this.tolerateError(messages_1.Messages.StrictVarName);
                }
            }
            let init = null;
            if (this.match('=')) {
                this.nextToken();
                init = this.isolateCoverGrammar(this.parseAssignmentExpression);
            }
            else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) {
                this.expect('=');
            }
            return this.finalize(node, new Node.VariableDeclarator(id, init));
        }
        parseVariableDeclarationList(options) {
            const opt = { inFor: options.inFor };
            const list = [];
            list.push(this.parseVariableDeclaration(opt));
            while (this.match(',')) {
                this.nextToken();
                list.push(this.parseVariableDeclaration(opt));
            }
            return list;
        }
        parseVariableStatement() {
            const node = this.createNode();
            this.expectKeyword('var');
            const declarations = this.parseVariableDeclarationList({ inFor: false });
            this.consumeSemicolon();
            return this.finalize(node, new Node.VariableDeclaration(declarations, 'var'));
        }
        // https://tc39.github.io/ecma262/#sec-empty-statement
        parseEmptyStatement() {
            const node = this.createNode();
            this.expect(';');
            return this.finalize(node, new Node.EmptyStatement());
        }
        // https://tc39.github.io/ecma262/#sec-expression-statement
        parseExpressionStatement() {
            const node = this.createNode();
            const expr = this.parseExpression();
            this.consumeSemicolon();
            return this.finalize(node, new Node.ExpressionStatement(expr));
        }
        // https://tc39.github.io/ecma262/#sec-if-statement
        parseIfClause() {
            if (this.context.strict && this.matchKeyword('function')) {
                this.tolerateError(messages_1.Messages.StrictFunction);
            }
            return this.parseStatement();
        }
        parseIfStatement() {
            const node = this.createNode();
            let consequent;
            let alternate = null;
            this.expectKeyword('if');
            this.expect('(');
            const test = this.parseExpression();
            if (!this.match(')') && this.config.tolerant) {
                this.tolerateUnexpectedToken(this.nextToken());
                consequent = this.finalize(this.createNode(), new Node.EmptyStatement());
            }
            else {
                this.expect(')');
                consequent = this.parseIfClause();
                if (this.matchKeyword('else')) {
                    this.nextToken();
                    alternate = this.parseIfClause();
                }
            }
            return this.finalize(node, new Node.IfStatement(test, consequent, alternate));
        }
        // https://tc39.github.io/ecma262/#sec-do-while-statement
        parseDoWhileStatement() {
            const node = this.createNode();
            this.expectKeyword('do');
            const previousInIteration = this.context.inIteration;
            this.context.inIteration = true;
            const body = this.parseStatement();
            this.context.inIteration = previousInIteration;
            this.expectKeyword('while');
            this.expect('(');
            const test = this.parseExpression();
            if (!this.match(')') && this.config.tolerant) {
                this.tolerateUnexpectedToken(this.nextToken());
            }
            else {
                this.expect(')');
                if (this.match(';')) {
                    this.nextToken();
                }
            }
            return this.finalize(node, new Node.DoWhileStatement(body, test));
        }
        // https://tc39.github.io/ecma262/#sec-while-statement
        parseWhileStatement() {
            const node = this.createNode();
            let body;
            this.expectKeyword('while');
            this.expect('(');
            const test = this.parseExpression();
            if (!this.match(')') && this.config.tolerant) {
                this.tolerateUnexpectedToken(this.nextToken());
                body = this.finalize(this.createNode(), new Node.EmptyStatement());
            }
            else {
                this.expect(')');
                const previousInIteration = this.context.inIteration;
                this.context.inIteration = true;
                body = this.parseStatement();
                this.context.inIteration = previousInIteration;
            }
            return this.finalize(node, new Node.WhileStatement(test, body));
        }
        // https://tc39.github.io/ecma262/#sec-for-statement
        // https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements
        parseForStatement() {
            let init = null;
            let test = null;
            let update = null;
            let forIn = true;
            let isForAwaitOf = false;
            let left, right;
            const node = this.createNode();
            this.expectKeyword('for');
            if (this.matchContextualKeyword('await')) {
                if (!this.context.await) {
                    this.throwUnexpectedToken(this.lookahead, messages_1.Messages.ForAwaitInNonAsync);
                }
                this.nextToken();
                isForAwaitOf = true;
            }
            this.expect('(');
            if (this.match(';')) {
                if (isForAwaitOf) {
                    this.throwUnexpectedToken(this.lookahead, messages_1.Messages.ForAwaitOfSemicolon);
                }
                this.nextToken();
            }
            else {
                if (this.matchKeyword('var')) {
                    init = this.createNode();
                    this.nextToken();
                    const previousAllowIn = this.context.allowIn;
                    this.context.allowIn = false;
                    const declarations = this.parseVariableDeclarationList({ inFor: true });
                    this.context.allowIn = previousAllowIn;
                    if (declarations.length === 1 && this.matchKeyword('in')) {
                        if (isForAwaitOf) {
                            this.throwUnexpectedToken(this.lookahead, messages_1.Messages.ForAwaitOfSawIn);
                        }
                        const decl = declarations[0];
                        if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) {
                            this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in');
                        }
                        init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
                        this.nextToken();
                        left = init;
                        right = this.parseExpression();
                        init = null;
                    }
                    else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) {
                        init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
                        this.nextToken();
                        left = init;
                        right = this.parseAssignmentExpression();
                        init = null;
                        forIn = false;
                    }
                    else {
                        init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
                        this.expect(';');
                    }
                }
                else if (this.matchKeyword('const') || this.matchKeyword('let')) {
                    init = this.createNode();
                    const kind = this.nextToken().value;
                    if (!this.context.strict && this.lookahead.value === 'in') {
                        init = this.finalize(init, new Node.Identifier(kind));
                        this.nextToken();
                        left = init;
                        right = this.parseExpression();
                        init = null;
                    }
                    else {
                        const previousAllowIn = this.context.allowIn;
                        this.context.allowIn = false;
                        const declarations = this.parseBindingList(kind, { inFor: true });
                        this.context.allowIn = previousAllowIn;
                        if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) {
                            if (isForAwaitOf) {
                                this.throwUnexpectedToken(this.lookahead, messages_1.Messages.ForAwaitOfSawIn);
                            }
                            init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
                            this.nextToken();
                            left = init;
                            right = this.parseExpression();
                            init = null;
                        }
                        else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) {
                            init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
                            this.nextToken();
                            left = init;
                            right = this.parseAssignmentExpression();
                            init = null;
                            forIn = false;
                        }
                        else {
                            this.consumeSemicolon();
                            init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
                        }
                    }
                }
                else {
                    const initStartToken = this.lookahead;
                    const previousAllowIn = this.context.allowIn;
                    this.context.allowIn = false;
                    init = this.inheritCoverGrammar(this.parseAssignmentExpression);
                    this.context.allowIn = previousAllowIn;
                    if (this.matchKeyword('in')) {
                        if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
                            this.tolerateError(messages_1.Messages.InvalidLHSInForIn);
                        }
                        if (isForAwaitOf) {
                            this.throwUnexpectedToken(this.lookahead, messages_1.Messages.ForAwaitOfSawIn);
                        }
                        this.nextToken();
                        this.reinterpretExpressionAsPattern(init);
                        left = init;
                        right = this.parseExpression();
                        init = null;
                    }
                    else if (this.matchContextualKeyword('of')) {
                        if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
                            this.tolerateError(messages_1.Messages.InvalidLHSInForLoop);
                        }
                        this.nextToken();
                        this.reinterpretExpressionAsPattern(init);
                        left = init;
                        right = this.parseAssignmentExpression();
                        init = null;
                        forIn = false;
                    }
                    else {
                        if (this.match(',')) {
                            const initSeq = [init];
                            while (this.match(',')) {
                                this.nextToken();
                                initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
                            }
                            init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq));
                        }
                        this.expect(';');
                    }
                }
            }
            if (typeof left === 'undefined') {
                if (!this.match(';')) {
                    test = this.parseExpression();
                }
                this.expect(';');
                if (!this.match(')')) {
                    update = this.parseExpression();
                }
            }
            let body;
            if (!this.match(')') && this.config.tolerant) {
                this.tolerateUnexpectedToken(this.nextToken());
                body = this.finalize(this.createNode(), new Node.EmptyStatement());
            }
            else {
                this.expect(')');
                const previousInIteration = this.context.inIteration;
                this.context.inIteration = true;
                body = this.isolateCoverGrammar(this.parseStatement);
                this.context.inIteration = previousInIteration;
            }
            return (typeof left === 'undefined') ?
                this.finalize(node, new Node.ForStatement(init, test, update, body)) :
                forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) :
                    this.finalize(node, new Node.ForOfStatement(left, right, body, isForAwaitOf));
        }
        // https://tc39.github.io/ecma262/#sec-continue-statement
        parseContinueStatement() {
            const node = this.createNode();
            this.expectKeyword('continue');
            let label = null;
            if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) {
                const id = this.parseVariableIdentifier();
                label = id;
                const key = '$' + id.name;
                if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
                    this.throwError(messages_1.Messages.UnknownLabel, id.name);
                }
            }
            this.consumeSemicolon();
            if (label === null && !this.context.inIteration) {
                this.throwError(messages_1.Messages.IllegalContinue);
            }
            return this.finalize(node, new Node.ContinueStatement(label));
        }
        // https://tc39.github.io/ecma262/#sec-break-statement
        parseBreakStatement() {
            const node = this.createNode();
            this.expectKeyword('break');
            let label = null;
            if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) {
                const id = this.parseVariableIdentifier();
                const key = '$' + id.name;
                if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
                    this.throwError(messages_1.Messages.UnknownLabel, id.name);
                }
                label = id;
            }
            this.consumeSemicolon();
            if (label === null && !this.context.inIteration && !this.context.inSwitch) {
                this.throwError(messages_1.Messages.IllegalBreak);
            }
            return this.finalize(node, new Node.BreakStatement(label));
        }
        // https://tc39.github.io/ecma262/#sec-return-statement
        parseReturnStatement() {
            if (!this.context.inFunctionBody) {
                this.tolerateError(messages_1.Messages.IllegalReturn);
            }
            const node = this.createNode();
            this.expectKeyword('return');
            const hasArgument = (!this.match(';') && !this.match('}') &&
                !this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */) ||
                this.lookahead.type === 8 /* StringLiteral */ ||
                this.lookahead.type === 10 /* Template */;
            const argument = hasArgument ? this.parseExpression() : null;
            this.consumeSemicolon();
            return this.finalize(node, new Node.ReturnStatement(argument));
        }
        // https://tc39.github.io/ecma262/#sec-with-statement
        parseWithStatement() {
            if (this.context.strict) {
                this.tolerateError(messages_1.Messages.StrictModeWith);
            }
            const node = this.createNode();
            let body;
            this.expectKeyword('with');
            this.expect('(');
            const object = this.parseExpression();
            if (!this.match(')') && this.config.tolerant) {
                this.tolerateUnexpectedToken(this.nextToken());
                body = this.finalize(this.createNode(), new Node.EmptyStatement());
            }
            else {
                this.expect(')');
                body = this.parseStatement();
            }
            return this.finalize(node, new Node.WithStatement(object, body));
        }
        // https://tc39.github.io/ecma262/#sec-switch-statement
        parseSwitchCase() {
            const node = this.createNode();
            let test;
            if (this.matchKeyword('default')) {
                this.nextToken();
                test = null;
            }
            else {
                this.expectKeyword('case');
                test = this.parseExpression();
            }
            this.expect(':');
            const consequent = [];
            while (true) {
                if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) {
                    break;
                }
                consequent.push(this.parseStatementListItem());
            }
            return this.finalize(node, new Node.SwitchCase(test, consequent));
        }
        parseSwitchStatement() {
            const node = this.createNode();
            this.expectKeyword('switch');
            this.expect('(');
            const discriminant = this.parseExpression();
            this.expect(')');
            const previousInSwitch = this.context.inSwitch;
            this.context.inSwitch = true;
            const cases = [];
            let defaultFound = false;
            this.expect('{');
            while (true) {
                if (this.match('}')) {
                    break;
                }
                const clause = this.parseSwitchCase();
                if (clause.test === null) {
                    if (defaultFound) {
                        this.throwError(messages_1.Messages.MultipleDefaultsInSwitch);
                    }
                    defaultFound = true;
                }
                cases.push(clause);
            }
            this.expect('}');
            this.context.inSwitch = previousInSwitch;
            return this.finalize(node, new Node.SwitchStatement(discriminant, cases));
        }
        // https://tc39.github.io/ecma262/#sec-labelled-statements
        parseLabelledStatement() {
            const node = this.createNode();
            const expr = this.parseExpression();
            let statement;
            if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) {
                this.nextToken();
                const id = expr;
                const key = '$' + id.name;
                if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
                    this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name);
                }
                this.context.labelSet[key] = true;
                let body;
                if (this.matchKeyword('class')) {
                    this.tolerateUnexpectedToken(this.lookahead);
                    body = this.parseClassDeclaration();
                }
                else if (this.matchKeyword('function')) {
                    const token = this.lookahead;
                    const declaration = this.parseFunctionDeclaration();
                    if (this.context.strict) {
                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunction);
                    }
                    else if (declaration.generator) {
                        this.tolerateUnexpectedToken(token, messages_1.Messages.GeneratorInLegacyContext);
                    }
                    body = declaration;
                }
                else {
                    body = this.parseStatement();
                }
                delete this.context.labelSet[key];
                statement = new Node.LabeledStatement(id, body);
            }
            else {
                this.consumeSemicolon();
                statement = new Node.ExpressionStatement(expr);
            }
            return this.finalize(node, statement);
        }
        // https://tc39.github.io/ecma262/#sec-throw-statement
        parseThrowStatement() {
            const node = this.createNode();
            this.expectKeyword('throw');
            if (this.hasLineTerminator) {
                this.throwError(messages_1.Messages.NewlineAfterThrow);
            }
            const argument = this.parseExpression();
            this.consumeSemicolon();
            return this.finalize(node, new Node.ThrowStatement(argument));
        }
        // https://tc39.github.io/ecma262/#sec-try-statement
        parseCatchClause() {
            const node = this.createNode();
            let body;
            this.expectKeyword('catch');
            if (!this.match('(')) {
                body = this.parseBlock();
                return this.finalize(node, new Node.CatchClause(null, body));
            }
            this.expect('(');
            if (this.match(')')) {
                this.throwUnexpectedToken(this.lookahead);
            }
            const params = [];
            const param = this.parsePattern(params);
            const paramMap = {};
            for (let i = 0; i < params.length; i++) {
                const key = '$' + params[i].value;
                if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
                    this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value);
                }
                paramMap[key] = true;
            }
            if (this.context.strict && param.type === syntax_1.Syntax.Identifier) {
                if (this.scanner.isRestrictedWord(param.name)) {
                    this.tolerateError(messages_1.Messages.StrictCatchVariable);
                }
            }
            this.expect(')');
            body = this.parseBlock();
            return this.finalize(node, new Node.CatchClause(param, body));
        }
        parseFinallyClause() {
            this.expectKeyword('finally');
            return this.parseBlock();
        }
        parseTryStatement() {
            const node = this.createNode();
            this.expectKeyword('try');
            const block = this.parseBlock();
            const handler = this.matchKeyword('catch') ? this.parseCatchClause() : null;
            const finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null;
            if (!handler && !finalizer) {
                this.throwError(messages_1.Messages.NoCatchOrFinally);
            }
            return this.finalize(node, new Node.TryStatement(block, handler, finalizer));
        }
        // https://tc39.github.io/ecma262/#sec-debugger-statement
        parseDebuggerStatement() {
            const node = this.createNode();
            this.expectKeyword('debugger');
            this.consumeSemicolon();
            return this.finalize(node, new Node.DebuggerStatement());
        }
        // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations
        parseStatement() {
            let statement;
            switch (this.lookahead.type) {
                case 1 /* BooleanLiteral */:
                case 5 /* NullLiteral */:
                case 6 /* NumericLiteral */:
                case 8 /* StringLiteral */:
                case 10 /* Template */:
                case 9 /* RegularExpression */:
                    statement = this.parseExpressionStatement();
                    break;
                case 7 /* Punctuator */:
                    const value = this.lookahead.value;
                    if (value === '{') {
                        statement = this.parseBlock();
                    }
                    else if (value === '(') {
                        statement = this.parseExpressionStatement();
                    }
                    else if (value === ';') {
                        statement = this.parseEmptyStatement();
                    }
                    else {
                        statement = this.parseExpressionStatement();
                    }
                    break;
                case 3 /* Identifier */:
                    statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement();
                    break;
                case 4 /* Keyword */:
                    switch (this.lookahead.value) {
                        case 'break':
                            statement = this.parseBreakStatement();
                            break;
                        case 'continue':
                            statement = this.parseContinueStatement();
                            break;
                        case 'debugger':
                            statement = this.parseDebuggerStatement();
                            break;
                        case 'do':
                            statement = this.parseDoWhileStatement();
                            break;
                        case 'for':
                            statement = this.parseForStatement();
                            break;
                        case 'function':
                            statement = this.parseFunctionDeclaration();
                            break;
                        case 'if':
                            statement = this.parseIfStatement();
                            break;
                        case 'return':
                            statement = this.parseReturnStatement();
                            break;
                        case 'switch':
                            statement = this.parseSwitchStatement();
                            break;
                        case 'throw':
                            statement = this.parseThrowStatement();
                            break;
                        case 'try':
                            statement = this.parseTryStatement();
                            break;
                        case 'var':
                            statement = this.parseVariableStatement();
                            break;
                        case 'while':
                            statement = this.parseWhileStatement();
                            break;
                        case 'with':
                            statement = this.parseWithStatement();
                            break;
                        default:
                            statement = this.parseExpressionStatement();
                            break;
                    }
                    break;
                default:
                    statement = this.throwUnexpectedToken(this.lookahead);
            }
            return statement;
        }
        // https://tc39.github.io/ecma262/#sec-function-definitions
        parseFunctionSourceElements() {
            const node = this.createNode();
            this.expect('{');
            const body = this.parseDirectivePrologues();
            const previousLabelSet = this.context.labelSet;
            const previousInIteration = this.context.inIteration;
            const previousInSwitch = this.context.inSwitch;
            const previousInFunctionBody = this.context.inFunctionBody;
            this.context.labelSet = {};
            this.context.inIteration = false;
            this.context.inSwitch = false;
            this.context.inFunctionBody = true;
            while (this.lookahead.type !== 2 /* EOF */) {
                if (this.match('}')) {
                    break;
                }
                body.push(this.parseStatementListItem());
            }
            this.expect('}');
            this.context.labelSet = previousLabelSet;
            this.context.inIteration = previousInIteration;
            this.context.inSwitch = previousInSwitch;
            this.context.inFunctionBody = previousInFunctionBody;
            return this.finalize(node, new Node.BlockStatement(body));
        }
        validateParam(options, param, name) {
            const key = '$' + name;
            if (this.context.strict) {
                if (this.scanner.isRestrictedWord(name)) {
                    options.stricted = param;
                    options.message = messages_1.Messages.StrictParamName;
                }
                if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
                    options.stricted = param;
                    options.message = messages_1.Messages.StrictParamDupe;
                }
            }
            else if (!options.firstRestricted) {
                if (this.scanner.isRestrictedWord(name)) {
                    options.firstRestricted = param;
                    options.message = messages_1.Messages.StrictParamName;
                }
                else if (this.scanner.isStrictModeReservedWord(name)) {
                    options.firstRestricted = param;
                    options.message = messages_1.Messages.StrictReservedWord;
                }
                else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
                    options.stricted = param;
                    options.message = messages_1.Messages.StrictParamDupe;
                }
            }
            /* istanbul ignore next */
            if (typeof Object.defineProperty === 'function') {
                Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true });
            }
            else {
                options.paramSet[key] = true;
            }
        }
        parseRestElement(params) {
            const node = this.createNode();
            this.expect('...');
            const arg = this.parsePattern(params);
            if (this.match('=')) {
                this.throwError(messages_1.Messages.DefaultRestParameter);
            }
            if (!this.match(')')) {
                this.throwError(messages_1.Messages.ParameterAfterRestParameter);
            }
            return this.finalize(node, new Node.RestElement(arg));
        }
        parseFormalParameter(options) {
            const params = [];
            const param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params);
            for (let i = 0; i < params.length; i++) {
                this.validateParam(options, params[i], params[i].value);
            }
            options.simple = options.simple && (param instanceof Node.Identifier);
            options.params.push(param);
        }
        parseFormalParameters(firstRestricted) {
            let options;
            options = {
                simple: true,
                params: [],
                firstRestricted: firstRestricted
            };
            this.expect('(');
            if (!this.match(')')) {
                options.paramSet = {};
                while (this.lookahead.type !== 2 /* EOF */) {
                    this.parseFormalParameter(options);
                    if (this.match(')')) {
                        break;
                    }
                    this.expect(',');
                    if (this.match(')')) {
                        break;
                    }
                }
            }
            this.expect(')');
            return {
                simple: options.simple,
                params: options.params,
                stricted: options.stricted,
                firstRestricted: options.firstRestricted,
                message: options.message
            };
        }
        matchAsyncFunction() {
            let match = this.matchContextualKeyword('async');
            if (match) {
                const state = this.scanner.saveState();
                this.scanner.scanComments();
                const next = this.scanner.lex();
                this.scanner.restoreState(state);
                match = (state.lineNumber === next.lineNumber) && (next.type === 4 /* Keyword */) && (next.value === 'function');
            }
            return match;
        }
        parseFunctionDeclaration(identifierIsOptional) {
            const node = this.createNode();
            const isAsync = this.matchContextualKeyword('async');
            if (isAsync) {
                this.nextToken();
            }
            this.expectKeyword('function');
            const isGenerator = this.match('*');
            if (isGenerator) {
                this.nextToken();
            }
            let message;
            let id = null;
            let firstRestricted = null;
            if (!identifierIsOptional || !this.match('(')) {
                const token = this.lookahead;
                id = this.parseVariableIdentifier();
                if (this.context.strict) {
                    if (this.scanner.isRestrictedWord(token.value)) {
                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName);
                    }
                }
                else {
                    if (this.scanner.isRestrictedWord(token.value)) {
                        firstRestricted = token;
                        message = messages_1.Messages.StrictFunctionName;
                    }
                    else if (this.scanner.isStrictModeReservedWord(token.value)) {
                        firstRestricted = token;
                        message = messages_1.Messages.StrictReservedWord;
                    }
                }
            }
            const previousAllowAwait = this.context.await;
            const previousAllowYield = this.context.allowYield;
            this.context.await = isAsync;
            this.context.allowYield = !isGenerator;
            const formalParameters = this.parseFormalParameters(firstRestricted);
            const params = formalParameters.params;
            const stricted = formalParameters.stricted;
            firstRestricted = formalParameters.firstRestricted;
            if (formalParameters.message) {
                message = formalParameters.message;
            }
            const previousStrict = this.context.strict;
            const previousAllowStrictDirective = this.context.allowStrictDirective;
            this.context.allowStrictDirective = formalParameters.simple;
            const body = this.parseFunctionSourceElements();
            if (this.context.strict && firstRestricted) {
                this.throwUnexpectedToken(firstRestricted, message);
            }
            if (this.context.strict && stricted) {
                this.tolerateUnexpectedToken(stricted, message);
            }
            this.context.strict = previousStrict;
            this.context.allowStrictDirective = previousAllowStrictDirective;
            this.context.await = previousAllowAwait;
            this.context.allowYield = previousAllowYield;
            return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body, isGenerator)) :
                this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator));
        }
        parseFunctionExpression() {
            const node = this.createNode();
            const isAsync = this.matchContextualKeyword('async');
            if (isAsync) {
                this.nextToken();
            }
            this.expectKeyword('function');
            const isGenerator = this.match('*');
            if (isGenerator) {
                this.nextToken();
            }
            let message;
            let id = null;
            let firstRestricted;
            const previousAllowAwait = this.context.await;
            const previousAllowYield = this.context.allowYield;
            this.context.await = isAsync;
            this.context.allowYield = !isGenerator;
            if (!this.match('(')) {
                const token = this.lookahead;
                id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier();
                if (this.context.strict) {
                    if (this.scanner.isRestrictedWord(token.value)) {
                        this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName);
                    }
                }
                else {
                    if (this.scanner.isRestrictedWord(token.value)) {
                        firstRestricted = token;
                        message = messages_1.Messages.StrictFunctionName;
                    }
                    else if (this.scanner.isStrictModeReservedWord(token.value)) {
                        firstRestricted = token;
                        message = messages_1.Messages.StrictReservedWord;
                    }
                }
            }
            const formalParameters = this.parseFormalParameters(firstRestricted);
            const params = formalParameters.params;
            const stricted = formalParameters.stricted;
            firstRestricted = formalParameters.firstRestricted;
            if (formalParameters.message) {
                message = formalParameters.message;
            }
            const previousStrict = this.context.strict;
            const previousAllowStrictDirective = this.context.allowStrictDirective;
            this.context.allowStrictDirective = formalParameters.simple;
            const body = this.parseFunctionSourceElements();
            if (this.context.strict && firstRestricted) {
                this.throwUnexpectedToken(firstRestricted, message);
            }
            if (this.context.strict && stricted) {
                this.tolerateUnexpectedToken(stricted, message);
            }
            this.context.strict = previousStrict;
            this.context.allowStrictDirective = previousAllowStrictDirective;
            this.context.await = previousAllowAwait;
            this.context.allowYield = previousAllowYield;
            return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body, isGenerator)) :
                this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator));
        }
        // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive
        parseDirective() {
            const token = this.lookahead;
            const node = this.createNode();
            const expr = this.parseExpression();
            const directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null;
            this.consumeSemicolon();
            return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr));
        }
        parseDirectivePrologues() {
            let firstRestricted = null;
            const body = [];
            while (true) {
                const token = this.lookahead;
                if (token.type !== 8 /* StringLiteral */) {
                    break;
                }
                const statement = this.parseDirective();
                body.push(statement);
                const directive = statement.directive;
                if (typeof directive !== 'string') {
                    break;
                }
                if (directive === 'use strict') {
                    this.context.strict = true;
                    if (firstRestricted) {
                        this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral);
                    }
                    if (!this.context.allowStrictDirective) {
                        this.tolerateUnexpectedToken(token, messages_1.Messages.IllegalLanguageModeDirective);
                    }
                }
                else {
                    if (!firstRestricted && token.octal) {
                        firstRestricted = token;
                    }
                }
            }
            return body;
        }
        // https://tc39.github.io/ecma262/#sec-method-definitions
        qualifiedPropertyName(token) {
            switch (token.type) {
                case 3 /* Identifier */:
                case 8 /* StringLiteral */:
                case 1 /* BooleanLiteral */:
                case 5 /* NullLiteral */:
                case 6 /* NumericLiteral */:
                case 4 /* Keyword */:
                    return true;
                case 7 /* Punctuator */:
                    return token.value === '[';
                default:
                    break;
            }
            return false;
        }
        parseGetterMethod() {
            const node = this.createNode();
            const isGenerator = false;
            const previousAllowYield = this.context.allowYield;
            this.context.allowYield = !isGenerator;
            const formalParameters = this.parseFormalParameters();
            if (formalParameters.params.length > 0) {
                this.tolerateError(messages_1.Messages.BadGetterArity);
            }
            const method = this.parsePropertyMethod(formalParameters);
            this.context.allowYield = previousAllowYield;
            return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator));
        }
        parseSetterMethod() {
            const node = this.createNode();
            const isGenerator = false;
            const previousAllowYield = this.context.allowYield;
            this.context.allowYield = !isGenerator;
            const formalParameters = this.parseFormalParameters();
            if (formalParameters.params.length !== 1) {
                this.tolerateError(messages_1.Messages.BadSetterArity);
            }
            else if (formalParameters.params[0] instanceof Node.RestElement) {
                this.tolerateError(messages_1.Messages.BadSetterRestParameter);
            }
            const method = this.parsePropertyMethod(formalParameters);
            this.context.allowYield = previousAllowYield;
            return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator));
        }
        parseGeneratorMethod() {
            const node = this.createNode();
            const isGenerator = true;
            const previousAllowYield = this.context.allowYield;
            this.context.allowYield = true;
            const params = this.parseFormalParameters();
            this.context.allowYield = false;
            const method = this.parsePropertyMethod(params);
            this.context.allowYield = previousAllowYield;
            return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
        }
        // https://tc39.github.io/ecma262/#sec-generator-function-definitions
        isStartOfExpression() {
            let start = true;
            const value = this.lookahead.value;
            switch (this.lookahead.type) {
                case 7 /* Punctuator */:
                    start = (value === '[') || (value === '(') || (value === '{') ||
                        (value === '+') || (value === '-') ||
                        (value === '!') || (value === '~') ||
                        (value === '++') || (value === '--') ||
                        (value === '/') || (value === '/='); // regular expression literal
                    break;
                case 4 /* Keyword */:
                    start = (value === 'class') || (value === 'delete') ||
                        (value === 'function') || (value === 'let') || (value === 'new') ||
                        (value === 'super') || (value === 'this') || (value === 'typeof') ||
                        (value === 'void') || (value === 'yield');
                    break;
                default:
                    break;
            }
            return start;
        }
        parseYieldExpression() {
            const node = this.createNode();
            this.expectKeyword('yield');
            let argument = null;
            let delegate = false;
            if (!this.hasLineTerminator) {
                const previousAllowYield = this.context.allowYield;
                this.context.allowYield = false;
                delegate = this.match('*');
                if (delegate) {
                    this.nextToken();
                    argument = this.parseAssignmentExpression();
                }
                else if (this.isStartOfExpression()) {
                    argument = this.parseAssignmentExpression();
                }
                this.context.allowYield = previousAllowYield;
            }
            return this.finalize(node, new Node.YieldExpression(argument, delegate));
        }
        // https://tc39.github.io/ecma262/#sec-class-definitions
        parseClassElement(hasConstructor) {
            let token = this.lookahead;
            const node = this.createNode();
            let kind = '';
            let key = null;
            let value = null;
            let computed = false;
            let method = false;
            let isStatic = false;
            let isAsync = false;
            let isAsyncGenerator = false;
            if (this.match('*')) {
                this.nextToken();
            }
            else {
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
                const id = key;
                if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) {
                    token = this.lookahead;
                    isStatic = true;
                    computed = this.match('[');
                    if (this.match('*')) {
                        this.nextToken();
                    }
                    else {
                        key = this.parseObjectPropertyKey();
                    }
                }
                if ((token.type === 3 /* Identifier */) && !this.hasLineTerminator && (token.value === 'async')) {
                    const punctuator = this.lookahead.value;
                    if (punctuator !== ':' && punctuator !== '(') {
                        isAsync = true;
                        isAsyncGenerator = this.match('*');
                        if (isAsyncGenerator) {
                            this.nextToken();
                        }
                        token = this.lookahead;
                        key = this.parseObjectPropertyKey();
                        if (token.type === 3 /* Identifier */ && token.value === 'constructor') {
                            this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync);
                        }
                    }
                }
            }
            const lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead);
            if (token.type === 3 /* Identifier */) {
                if (token.value === 'get' && lookaheadPropertyKey) {
                    kind = 'get';
                    computed = this.match('[');
                    key = this.parseObjectPropertyKey();
                    this.context.allowYield = false;
                    value = this.parseGetterMethod();
                }
                else if (token.value === 'set' && lookaheadPropertyKey) {
                    kind = 'set';
                    computed = this.match('[');
                    key = this.parseObjectPropertyKey();
                    value = this.parseSetterMethod();
                }
            }
            else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) {
                kind = 'init';
                computed = this.match('[');
                key = this.parseObjectPropertyKey();
                value = this.parseGeneratorMethod();
                method = true;
            }
            if (!kind && key && this.match('(')) {
                kind = 'init';
                value = isAsync ? this.parsePropertyMethodAsyncFunction(isAsyncGenerator) : this.parsePropertyMethodFunction();
                method = true;
            }
            if (!kind) {
                this.throwUnexpectedToken(this.lookahead);
            }
            if (kind === 'init') {
                kind = 'method';
            }
            if (!computed) {
                if (isStatic && this.isPropertyKey(key, 'prototype')) {
                    this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype);
                }
                if (!isStatic && this.isPropertyKey(key, 'constructor')) {
                    if (kind !== 'method' || !method || (value && value.generator)) {
                        this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod);
                    }
                    if (hasConstructor.value) {
                        this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor);
                    }
                    else {
                        hasConstructor.value = true;
                    }
                    kind = 'constructor';
                }
            }
            return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic));
        }
        parseClassElementList() {
            const body = [];
            const hasConstructor = { value: false };
            this.expect('{');
            while (!this.match('}')) {
                if (this.match(';')) {
                    this.nextToken();
                }
                else {
                    body.push(this.parseClassElement(hasConstructor));
                }
            }
            this.expect('}');
            return body;
        }
        parseClassBody() {
            const node = this.createNode();
            const elementList = this.parseClassElementList();
            return this.finalize(node, new Node.ClassBody(elementList));
        }
        parseClassDeclaration(identifierIsOptional) {
            const node = this.createNode();
            const previousStrict = this.context.strict;
            this.context.strict = true;
            this.expectKeyword('class');
            const id = (identifierIsOptional && (this.lookahead.type !== 3 /* Identifier */)) ? null : this.parseVariableIdentifier();
            let superClass = null;
            if (this.matchKeyword('extends')) {
                this.nextToken();
                superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
            }
            const classBody = this.parseClassBody();
            this.context.strict = previousStrict;
            return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody));
        }
        parseClassExpression() {
            const node = this.createNode();
            const previousStrict = this.context.strict;
            this.context.strict = true;
            this.expectKeyword('class');
            const id = (this.lookahead.type === 3 /* Identifier */) ? this.parseVariableIdentifier() : null;
            let superClass = null;
            if (this.matchKeyword('extends')) {
                this.nextToken();
                superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
            }
            const classBody = this.parseClassBody();
            this.context.strict = previousStrict;
            return this.finalize(node, new Node.ClassExpression(id, superClass, classBody));
        }
        // https://tc39.github.io/ecma262/#sec-scripts
        // https://tc39.github.io/ecma262/#sec-modules
        parseModule() {
            this.context.strict = true;
            this.context.isModule = true;
            this.scanner.isModule = true;
            const node = this.createNode();
            const body = this.parseDirectivePrologues();
            while (this.lookahead.type !== 2 /* EOF */) {
                body.push(this.parseStatementListItem());
            }
            return this.finalize(node, new Node.Module(body));
        }
        parseScript() {
            const node = this.createNode();
            const body = this.parseDirectivePrologues();
            while (this.lookahead.type !== 2 /* EOF */) {
                body.push(this.parseStatementListItem());
            }
            return this.finalize(node, new Node.Script(body));
        }
        // https://tc39.github.io/ecma262/#sec-imports
        parseModuleSpecifier() {
            const node = this.createNode();
            if (this.lookahead.type !== 8 /* StringLiteral */) {
                this.throwError(messages_1.Messages.InvalidModuleSpecifier);
            }
            const token = this.nextToken();
            const raw = this.getTokenRaw(token);
            return this.finalize(node, new Node.Literal(token.value, raw));
        }
        // import {<foo as bar>} ...;
        parseImportSpecifier() {
            const node = this.createNode();
            let imported;
            let local;
            if (this.lookahead.type === 3 /* Identifier */) {
                imported = this.parseVariableIdentifier();
                local = imported;
                if (this.matchContextualKeyword('as')) {
                    this.nextToken();
                    local = this.parseVariableIdentifier();
                }
            }
            else {
                imported = this.parseIdentifierName();
                local = imported;
                if (this.matchContextualKeyword('as')) {
                    this.nextToken();
                    local = this.parseVariableIdentifier();
                }
                else {
                    this.throwUnexpectedToken(this.nextToken());
                }
            }
            return this.finalize(node, new Node.ImportSpecifier(local, imported));
        }
        // {foo, bar as bas}
        parseNamedImports() {
            this.expect('{');
            const specifiers = [];
            while (!this.match('}')) {
                specifiers.push(this.parseImportSpecifier());
                if (!this.match('}')) {
                    this.expect(',');
                }
            }
            this.expect('}');
            return specifiers;
        }
        // import <foo> ...;
        parseImportDefaultSpecifier() {
            const node = this.createNode();
            const local = this.parseIdentifierName();
            return this.finalize(node, new Node.ImportDefaultSpecifier(local));
        }
        // import <* as foo> ...;
        parseImportNamespaceSpecifier() {
            const node = this.createNode();
            this.expect('*');
            if (!this.matchContextualKeyword('as')) {
                this.throwError(messages_1.Messages.NoAsAfterImportNamespace);
            }
            this.nextToken();
            const local = this.parseIdentifierName();
            return this.finalize(node, new Node.ImportNamespaceSpecifier(local));
        }
        parseImportDeclaration() {
            if (this.context.inFunctionBody) {
                this.throwError(messages_1.Messages.IllegalImportDeclaration);
            }
            const node = this.createNode();
            this.expectKeyword('import');
            let src;
            let specifiers = [];
            if (this.lookahead.type === 8 /* StringLiteral */) {
                // import 'foo';
                src = this.parseModuleSpecifier();
            }
            else {
                if (this.match('{')) {
                    // import {bar}
                    specifiers = specifiers.concat(this.parseNamedImports());
                }
                else if (this.match('*')) {
                    // import * as foo
                    specifiers.push(this.parseImportNamespaceSpecifier());
                }
                else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) {
                    // import foo
                    specifiers.push(this.parseImportDefaultSpecifier());
                    if (this.match(',')) {
                        this.nextToken();
                        if (this.match('*')) {
                            // import foo, * as foo
                            specifiers.push(this.parseImportNamespaceSpecifier());
                        }
                        else if (this.match('{')) {
                            // import foo, {bar}
                            specifiers = specifiers.concat(this.parseNamedImports());
                        }
                        else {
                            this.throwUnexpectedToken(this.lookahead);
                        }
                    }
                }
                else {
                    this.throwUnexpectedToken(this.nextToken());
                }
                if (!this.matchContextualKeyword('from')) {
                    const message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
                    this.throwError(message, this.lookahead.value);
                }
                this.nextToken();
                src = this.parseModuleSpecifier();
            }
            this.consumeSemicolon();
            return this.finalize(node, new Node.ImportDeclaration(specifiers, src));
        }
        // https://tc39.github.io/ecma262/#sec-exports
        parseExportSpecifier() {
            const node = this.createNode();
            const local = this.parseIdentifierName();
            let exported = local;
            if (this.matchContextualKeyword('as')) {
                this.nextToken();
                exported = this.parseIdentifierName();
            }
            return this.finalize(node, new Node.ExportSpecifier(local, exported));
        }
        parseExportDeclaration() {
            if (this.context.inFunctionBody) {
                this.throwError(messages_1.Messages.IllegalExportDeclaration);
            }
            const node = this.createNode();
            this.expectKeyword('export');
            let exportDeclaration;
            if (this.matchKeyword('default')) {
                // export default ...
                this.nextToken();
                if (this.matchKeyword('function')) {
                    // export default function foo () {}
                    // export default function () {}
                    const declaration = this.parseFunctionDeclaration(true);
                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
                }
                else if (this.matchKeyword('class')) {
                    // export default class foo {}
                    const declaration = this.parseClassDeclaration(true);
                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
                }
                else if (this.matchContextualKeyword('async')) {
                    // export default async function f () {}
                    // export default async function () {}
                    // export default async x => x
                    const declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression();
                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
                }
                else {
                    if (this.matchContextualKeyword('from')) {
                        this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value);
                    }
                    // export default {};
                    // export default [];
                    // export default (1 + 2);
                    const declaration = this.match('{') ? this.parseObjectInitializer() :
                        this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression();
                    this.consumeSemicolon();
                    exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
                }
            }
            else if (this.match('*')) {
                // export * from 'foo';
                this.nextToken();
                if (!this.matchContextualKeyword('from')) {
                    const message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
                    this.throwError(message, this.lookahead.value);
                }
                this.nextToken();
                const src = this.parseModuleSpecifier();
                this.consumeSemicolon();
                exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src));
            }
            else if (this.lookahead.type === 4 /* Keyword */) {
                // export var f = 1;
                let declaration;
                switch (this.lookahead.value) {
                    case 'let':
                    case 'const':
                        declaration = this.parseLexicalDeclaration({ inFor: false });
                        break;
                    case 'var':
                    case 'class':
                    case 'function':
                        declaration = this.parseStatementListItem();
                        break;
                    default:
                        this.throwUnexpectedToken(this.lookahead);
                }
                exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null));
            }
            else if (this.matchAsyncFunction()) {
                const declaration = this.parseFunctionDeclaration();
                exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null));
            }
            else {
                const specifiers = [];
                let source = null;
                let isExportFromIdentifier = false;
                this.expect('{');
                while (!this.match('}')) {
                    isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default');
                    specifiers.push(this.parseExportSpecifier());
                    if (!this.match('}')) {
                        this.expect(',');
                    }
                }
                this.expect('}');
                if (this.matchContextualKeyword('from')) {
                    // export {default} from 'foo';
                    // export {foo} from 'foo';
                    this.nextToken();
                    source = this.parseModuleSpecifier();
                    this.consumeSemicolon();
                }
                else if (isExportFromIdentifier) {
                    // export {default}; // missing fromClause
                    const message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
                    this.throwError(message, this.lookahead.value);
                }
                else {
                    // export {foo};
                    this.consumeSemicolon();
                }
                exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source));
            }
            return exportDeclaration;
        }
    }
    exports.Parser = Parser;


/***/ },
/* 9 */
/***/ function(module, exports) {

    "use strict";
    // Ensure the condition is true, otherwise throw an error.
    // This is only to have a better contract semantic, i.e. another safety net
    // to catch a logic error. The condition shall be fulfilled in normal case.
    // Do NOT use this to enforce a certain condition on any user input.
    Object.defineProperty(exports, "__esModule", { value: true });
    function assert(condition, message) {
        /* istanbul ignore if */
        if (!condition) {
            throw new Error('ASSERT: ' + message);
        }
    }
    exports.assert = assert;


/***/ },
/* 10 */
/***/ function(module, exports) {

    "use strict";
    /* tslint:disable:max-classes-per-file */
    Object.defineProperty(exports, "__esModule", { value: true });
    class ErrorHandler {
        constructor() {
            this.errors = [];
            this.tolerant = false;
        }
        recordError(error) {
            this.errors.push(error);
        }
        tolerate(error) {
            if (this.tolerant) {
                this.recordError(error);
            }
            else {
                throw error;
            }
        }
        constructError(msg, column) {
            let error = new Error(msg);
            try {
                throw error;
            }
            catch (base) {
                /* istanbul ignore else */
                if (Object.create && Object.defineProperty) {
                    error = Object.create(base);
                    Object.defineProperty(error, 'column', { value: column });
                }
            }
            /* istanbul ignore next */
            return error;
        }
        createError(index, line, col, description) {
            const msg = 'Line ' + line + ': ' + description;
            const error = this.constructError(msg, col);
            error.index = index;
            error.lineNumber = line;
            error.description = description;
            return error;
        }
        throwError(index, line, col, description) {
            throw this.createError(index, line, col, description);
        }
        tolerateError(index, line, col, description) {
            const error = this.createError(index, line, col, description);
            if (this.tolerant) {
                this.recordError(error);
            }
            else {
                throw error;
            }
        }
    }
    exports.ErrorHandler = ErrorHandler;


/***/ },
/* 11 */
/***/ function(module, exports) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    // Error messages should be identical to V8.
    exports.Messages = {
        BadImportCallArity: 'Unexpected token',
        BadGetterArity: 'Getter must not have any formal parameters',
        BadSetterArity: 'Setter must have exactly one formal parameter',
        BadSetterRestParameter: 'Setter function argument must not be a rest parameter',
        ConstructorIsAsync: 'Class constructor may not be an async method',
        ConstructorSpecialMethod: 'Class constructor may not be an accessor',
        DeclarationMissingInitializer: 'Missing initializer in %0 declaration',
        DefaultRestParameter: 'Unexpected token =',
        DefaultRestProperty: 'Unexpected token =',
        DuplicateBinding: 'Duplicate binding %0',
        DuplicateConstructor: 'A class may only have one constructor',
        DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
        ForAwaitInNonAsync: 'for-await-of can only be used in an async function or async generator',
        ForAwaitOfSemicolon: 'Unexpected \';\' in for-await-of header',
        ForAwaitOfSawIn: 'Unexpected \'in\' in for-await-of header',
        ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer',
        GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts',
        IllegalBreak: 'Illegal break statement',
        IllegalContinue: 'Illegal continue statement',
        IllegalExportDeclaration: 'Unexpected token',
        IllegalImportDeclaration: 'Unexpected token',
        IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list',
        IllegalReturn: 'Illegal return statement',
        InvalidEscapedReservedWord: 'Keyword must not contain escaped characters',
        InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence',
        InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
        InvalidLHSInForIn: 'Invalid left-hand side in for-in',
        InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
        InvalidModuleSpecifier: 'Unexpected token',
        InvalidNumericSeparatorAfterLeadingZero: 'Numeric serparator can not be used after leading 0',
        InvalidNumericSeparatorAfterNumericLiteral: 'Numeric separators are not allowed at the end of numeric literals',
        InvalidRegExp: 'Invalid regular expression',
        LetInLexicalBinding: 'let is disallowed as a lexically bound name',
        MissingFromClause: 'Unexpected token',
        MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
        NewlineAfterThrow: 'Illegal newline after throw',
        NoAsAfterImportNamespace: 'Unexpected token',
        NoCatchOrFinally: 'Missing catch or finally after try',
        ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
        PropertyAfterRestProperty: 'Unexpected token',
        Redeclaration: '%0 \'%1\' has already been declared',
        StaticPrototype: 'Classes may not have static property named prototype',
        StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
        StrictDelete: 'Delete of an unqualified identifier in strict mode.',
        StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block',
        StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
        StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
        StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
        StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
        StrictModeWith: 'Strict mode code may not include a with statement',
        StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
        StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
        StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
        StrictReservedWord: 'Use of future reserved word in strict mode',
        StrictVarName: 'Variable name may not be eval or arguments in strict mode',
        TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
        UnexpectedEOS: 'Unexpected end of input',
        UnexpectedIdentifier: 'Unexpected identifier',
        UnexpectedNumber: 'Unexpected number',
        UnexpectedReserved: 'Unexpected reserved word',
        UnexpectedString: 'Unexpected string',
        UnexpectedTemplate: 'Unexpected quasi %0',
        UnexpectedToken: 'Unexpected token %0',
        UnexpectedTokenIllegal: 'Unexpected token ILLEGAL',
        UnknownLabel: 'Undefined label \'%0\'',
        UnterminatedRegExp: 'Invalid regular expression: missing /'
    };


/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const assert_1 = __webpack_require__(9);
    const character_1 = __webpack_require__(4);
    const messages_1 = __webpack_require__(11);
    function hexValue(ch) {
        return '0123456789abcdef'.indexOf(ch.toLowerCase());
    }
    function octalValue(ch) {
        return '01234567'.indexOf(ch);
    }
    class Scanner {
        constructor(code, handler) {
            this.source = code;
            this.errorHandler = handler;
            this.trackComment = false;
            this.isModule = false;
            this.length = code.length;
            this.index = 0;
            this.lineNumber = (code.length > 0) ? 1 : 0;
            this.lineStart = 0;
            this.curlyStack = [];
        }
        saveState() {
            return {
                index: this.index,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart
            };
        }
        restoreState(state) {
            this.index = state.index;
            this.lineNumber = state.lineNumber;
            this.lineStart = state.lineStart;
        }
        eof() {
            return this.index >= this.length;
        }
        throwUnexpectedToken(message = messages_1.Messages.UnexpectedTokenIllegal) {
            return this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message);
        }
        tolerateUnexpectedToken(message = messages_1.Messages.UnexpectedTokenIllegal) {
            this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, message);
        }
        // https://tc39.github.io/ecma262/#sec-comments
        skipSingleLineComment(offset) {
            let comments = [];
            let start, loc;
            if (this.trackComment) {
                comments = [];
                start = this.index - offset;
                loc = {
                    start: {
                        line: this.lineNumber,
                        column: this.index - this.lineStart - offset
                    },
                    end: {}
                };
            }
            while (!this.eof()) {
                const ch = this.source.charCodeAt(this.index);
                ++this.index;
                if (character_1.Character.isLineTerminator(ch)) {
                    if (this.trackComment) {
                        loc.end = {
                            line: this.lineNumber,
                            column: this.index - this.lineStart - 1
                        };
                        const entry = {
                            multiLine: false,
                            slice: [start + offset, this.index - 1],
                            range: [start, this.index - 1],
                            loc: loc
                        };
                        comments.push(entry);
                    }
                    if (ch === 13 && this.source.charCodeAt(this.index) === 10) {
                        ++this.index;
                    }
                    ++this.lineNumber;
                    this.lineStart = this.index;
                    return comments;
                }
            }
            if (this.trackComment) {
                loc.end = {
                    line: this.lineNumber,
                    column: this.index - this.lineStart
                };
                const entry = {
                    multiLine: false,
                    slice: [start + offset, this.index],
                    range: [start, this.index],
                    loc: loc
                };
                comments.push(entry);
            }
            return comments;
        }
        skipMultiLineComment() {
            let comments = [];
            let start, loc;
            if (this.trackComment) {
                comments = [];
                start = this.index - 2;
                loc = {
                    start: {
                        line: this.lineNumber,
                        column: this.index - this.lineStart - 2
                    },
                    end: {}
                };
            }
            while (!this.eof()) {
                const ch = this.source.charCodeAt(this.index);
                if (character_1.Character.isLineTerminator(ch)) {
                    if (ch === 0x0D && this.source.charCodeAt(this.index + 1) === 0x0A) {
                        ++this.index;
                    }
                    ++this.lineNumber;
                    ++this.index;
                    this.lineStart = this.index;
                }
                else if (ch === 0x2A) {
                    // Block comment ends with '*/'.
                    if (this.source.charCodeAt(this.index + 1) === 0x2F) {
                        this.index += 2;
                        if (this.trackComment) {
                            loc.end = {
                                line: this.lineNumber,
                                column: this.index - this.lineStart
                            };
                            const entry = {
                                multiLine: true,
                                slice: [start + 2, this.index - 2],
                                range: [start, this.index],
                                loc: loc
                            };
                            comments.push(entry);
                        }
                        return comments;
                    }
                    ++this.index;
                }
                else {
                    ++this.index;
                }
            }
            // Ran off the end of the file - the whole thing is a comment
            if (this.trackComment) {
                loc.end = {
                    line: this.lineNumber,
                    column: this.index - this.lineStart
                };
                const entry = {
                    multiLine: true,
                    slice: [start + 2, this.index],
                    range: [start, this.index],
                    loc: loc
                };
                comments.push(entry);
            }
            this.tolerateUnexpectedToken();
            return comments;
        }
        scanComments() {
            let comments;
            if (this.trackComment) {
                comments = [];
            }
            let start = (this.index === 0);
            while (!this.eof()) {
                let ch = this.source.charCodeAt(this.index);
                if (character_1.Character.isWhiteSpace(ch)) {
                    ++this.index;
                }
                else if (character_1.Character.isLineTerminator(ch)) {
                    ++this.index;
                    if (ch === 0x0D && this.source.charCodeAt(this.index) === 0x0A) {
                        ++this.index;
                    }
                    ++this.lineNumber;
                    this.lineStart = this.index;
                    start = true;
                }
                else if (ch === 0x2F) { // U+002F is '/'
                    ch = this.source.charCodeAt(this.index + 1);
                    if (ch === 0x2F) {
                        this.index += 2;
                        const comment = this.skipSingleLineComment(2);
                        if (this.trackComment) {
                            comments = comments.concat(comment);
                        }
                        start = true;
                    }
                    else if (ch === 0x2A) { // U+002A is '*'
                        this.index += 2;
                        const comment = this.skipMultiLineComment();
                        if (this.trackComment) {
                            comments = comments.concat(comment);
                        }
                    }
                    else {
                        break;
                    }
                }
                else if (start && ch === 0x2D) { // U+002D is '-'
                    // U+003E is '>'
                    if ((this.source.charCodeAt(this.index + 1) === 0x2D) && (this.source.charCodeAt(this.index + 2) === 0x3E)) {
                        // '-->' is a single-line comment
                        this.index += 3;
                        const comment = this.skipSingleLineComment(3);
                        if (this.trackComment) {
                            comments = comments.concat(comment);
                        }
                    }
                    else {
                        break;
                    }
                }
                else if (ch === 0x3C && !this.isModule) { // U+003C is '<'
                    if (this.source.slice(this.index + 1, this.index + 4) === '!--') {
                        this.index += 4; // `<!--`
                        const comment = this.skipSingleLineComment(4);
                        if (this.trackComment) {
                            comments = comments.concat(comment);
                        }
                    }
                    else {
                        break;
                    }
                }
                else {
                    break;
                }
            }
            return comments;
        }
        // https://tc39.github.io/ecma262/#sec-future-reserved-words
        isFutureReservedWord(id) {
            switch (id) {
                case 'enum':
                case 'export':
                case 'import':
                case 'super':
                    return true;
                default:
                    return false;
            }
        }
        isStrictModeReservedWord(id) {
            switch (id) {
                case 'implements':
                case 'interface':
                case 'package':
                case 'private':
                case 'protected':
                case 'public':
                case 'static':
                case 'yield':
                case 'let':
                    return true;
                default:
                    return false;
            }
        }
        isRestrictedWord(id) {
            return id === 'eval' || id === 'arguments';
        }
        // https://tc39.github.io/ecma262/#sec-keywords
        isKeyword(id) {
            switch (id.length) {
                case 2:
                    return (id === 'if') || (id === 'in') || (id === 'do');
                case 3:
                    return (id === 'var') || (id === 'for') || (id === 'new') ||
                        (id === 'try') || (id === 'let');
                case 4:
                    return (id === 'this') || (id === 'else') || (id === 'case') ||
                        (id === 'void') || (id === 'with') || (id === 'enum');
                case 5:
                    return (id === 'while') || (id === 'break') || (id === 'catch') ||
                        (id === 'throw') || (id === 'const') || (id === 'yield') ||
                        (id === 'class') || (id === 'super');
                case 6:
                    return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
                        (id === 'switch') || (id === 'export') || (id === 'import');
                case 7:
                    return (id === 'default') || (id === 'finally') || (id === 'extends');
                case 8:
                    return (id === 'function') || (id === 'continue') || (id === 'debugger');
                case 10:
                    return (id === 'instanceof');
                default:
                    return false;
            }
        }
        codePointAt(i) {
            let cp = this.source.charCodeAt(i);
            if (cp >= 0xD800 && cp <= 0xDBFF) {
                const second = this.source.charCodeAt(i + 1);
                if (second >= 0xDC00 && second <= 0xDFFF) {
                    const first = cp;
                    cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
                }
            }
            return cp;
        }
        scanHexEscape(prefix) {
            const len = (prefix === 'u') ? 4 : 2;
            let code = 0;
            for (let i = 0; i < len; ++i) {
                if (!this.eof() && character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) {
                    code = code * 16 + hexValue(this.source[this.index++]);
                }
                else {
                    return null;
                }
            }
            return String.fromCharCode(code);
        }
        scanUnicodeCodePointEscape() {
            let ch = this.source[this.index];
            let code = 0;
            // At least, one hex digit is required.
            if (ch === '}') {
                this.throwUnexpectedToken();
            }
            while (!this.eof()) {
                ch = this.source[this.index++];
                if (!character_1.Character.isHexDigit(ch.charCodeAt(0))) {
                    break;
                }
                code = code * 16 + hexValue(ch);
            }
            if (code > 0x10FFFF || ch !== '}') {
                this.throwUnexpectedToken();
            }
            return character_1.Character.fromCodePoint(code);
        }
        getIdentifier() {
            const start = this.index++;
            while (!this.eof()) {
                const ch = this.source.charCodeAt(this.index);
                if (ch === 0x5C) {
                    // Blackslash (U+005C) marks Unicode escape sequence.
                    this.index = start;
                    return this.getComplexIdentifier();
                }
                else if (ch >= 0xD800 && ch < 0xDFFF) {
                    // Need to handle surrogate pairs.
                    this.index = start;
                    return this.getComplexIdentifier();
                }
                if (character_1.Character.isIdentifierPart(ch)) {
                    ++this.index;
                }
                else {
                    break;
                }
            }
            return this.source.slice(start, this.index);
        }
        getComplexIdentifier() {
            let cp = this.codePointAt(this.index);
            let id = character_1.Character.fromCodePoint(cp);
            this.index += id.length;
            // '\u' (U+005C, U+0075) denotes an escaped character.
            let ch;
            if (cp === 0x5C) {
                if (this.source.charCodeAt(this.index) !== 0x75) {
                    this.throwUnexpectedToken();
                }
                ++this.index;
                if (this.source[this.index] === '{') {
                    ++this.index;
                    ch = this.scanUnicodeCodePointEscape();
                }
                else {
                    ch = this.scanHexEscape('u');
                    if (ch === null || ch === '\\' || !character_1.Character.isIdentifierStart(ch.charCodeAt(0))) {
                        this.throwUnexpectedToken();
                    }
                }
                id = ch;
            }
            while (!this.eof()) {
                cp = this.codePointAt(this.index);
                if (!character_1.Character.isIdentifierPart(cp)) {
                    break;
                }
                ch = character_1.Character.fromCodePoint(cp);
                id += ch;
                this.index += ch.length;
                // '\u' (U+005C, U+0075) denotes an escaped character.
                if (cp === 0x5C) {
                    id = id.substr(0, id.length - 1);
                    if (this.source.charCodeAt(this.index) !== 0x75) {
                        this.throwUnexpectedToken();
                    }
                    ++this.index;
                    if (this.source[this.index] === '{') {
                        ++this.index;
                        ch = this.scanUnicodeCodePointEscape();
                    }
                    else {
                        ch = this.scanHexEscape('u');
                        if (ch === null || ch === '\\' || !character_1.Character.isIdentifierPart(ch.charCodeAt(0))) {
                            this.throwUnexpectedToken();
                        }
                    }
                    id += ch;
                }
            }
            return id;
        }
        octalToDecimal(ch) {
            // \0 is not octal escape sequence
            let octal = (ch !== '0');
            let code = octalValue(ch);
            if (!this.eof() && character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
                octal = true;
                code = code * 8 + octalValue(this.source[this.index++]);
                // 3 digits are only allowed when string starts
                // with 0, 1, 2, 3
                if ('0123'.indexOf(ch) >= 0 && !this.eof() && character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
                    code = code * 8 + octalValue(this.source[this.index++]);
                }
            }
            return {
                code: code,
                octal: octal
            };
        }
        // https://tc39.github.io/ecma262/#sec-names-and-keywords
        scanIdentifier() {
            let type;
            const start = this.index;
            // Backslash (U+005C) starts an escaped character.
            const id = (this.source.charCodeAt(start) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier();
            // There is no keyword or literal with only one character.
            // Thus, it must be an identifier.
            if (id.length === 1) {
                type = 3 /* Identifier */;
            }
            else if (this.isKeyword(id)) {
                type = 4 /* Keyword */;
            }
            else if (id === 'null') {
                type = 5 /* NullLiteral */;
            }
            else if (id === 'true' || id === 'false') {
                type = 1 /* BooleanLiteral */;
            }
            else {
                type = 3 /* Identifier */;
            }
            if (type !== 3 /* Identifier */ && (start + id.length !== this.index)) {
                const restore = this.index;
                this.index = start;
                this.tolerateUnexpectedToken(messages_1.Messages.InvalidEscapedReservedWord);
                this.index = restore;
            }
            return {
                type: type,
                value: id,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        // https://tc39.github.io/ecma262/#sec-punctuators
        scanPunctuator() {
            const start = this.index;
            // Check for most common single-character punctuators.
            let str = this.source[this.index];
            switch (str) {
                case '(':
                case '{':
                    if (str === '{') {
                        this.curlyStack.push('{');
                    }
                    ++this.index;
                    break;
                case '.':
                    ++this.index;
                    if (this.source[this.index] === '.' && this.source[this.index + 1] === '.') {
                        // Spread operator: ...
                        this.index += 2;
                        str = '...';
                    }
                    break;
                case '}':
                    ++this.index;
                    this.curlyStack.pop();
                    break;
                case ')':
                case ';':
                case ',':
                case '[':
                case ']':
                case ':':
                case '?':
                case '~':
                    ++this.index;
                    break;
                default:
                    // 4-character punctuator.
                    str = this.source.substr(this.index, 4);
                    if (str === '>>>=') {
                        this.index += 4;
                    }
                    else {
                        // 3-character punctuators.
                        str = str.substr(0, 3);
                        if (str === '===' || str === '!==' || str === '>>>' ||
                            str === '<<=' || str === '>>=' || str === '**=') {
                            this.index += 3;
                        }
                        else {
                            // 2-character punctuators.
                            str = str.substr(0, 2);
                            if (str === '&&' || str === '||' || str === '==' || str === '!=' ||
                                str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
                                str === '++' || str === '--' || str === '<<' || str === '>>' ||
                                str === '&=' || str === '|=' || str === '^=' || str === '%=' ||
                                str === '<=' || str === '>=' || str === '=>' || str === '**') {
                                this.index += 2;
                            }
                            else {
                                // 1-character punctuators.
                                str = this.source[this.index];
                                if ('<>=!+-*%&|^/'.indexOf(str) >= 0) {
                                    ++this.index;
                                }
                            }
                        }
                    }
            }
            if (this.index === start) {
                this.throwUnexpectedToken();
            }
            return {
                type: 7 /* Punctuator */,
                value: str,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        // https://tc39.github.io/ecma262/#sec-literals-numeric-literals
        scanHexLiteral(start) {
            let num = '';
            let nextInvalidNumericSeparatorPosition = this.index;
            while (character_1.Character.isHexDigit(this.source.charCodeAt(this.index)) || this.source[this.index] === '_') {
                if (this.source[this.index] === '_') {
                    if (this.index === nextInvalidNumericSeparatorPosition) {
                        this.throwUnexpectedToken();
                    }
                    ++this.index;
                    nextInvalidNumericSeparatorPosition = this.index;
                    continue;
                }
                num += this.source[this.index++];
            }
            if (num.length === 0) {
                this.throwUnexpectedToken();
            }
            if (this.index === nextInvalidNumericSeparatorPosition) {
                this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterNumericLiteral);
            }
            let bigint = false;
            if (this.source[this.index] === 'n') {
                ++this.index;
                bigint = true;
            }
            if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
                this.throwUnexpectedToken();
            }
            return {
                type: 6 /* NumericLiteral */,
                value: parseInt('0x' + num, 16),
                bigint: bigint,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        scanBinaryLiteral(start) {
            let num = '';
            let ch;
            let nextInvalidNumericSeparatorPosition = this.index;
            while (this.source[this.index] === '0' || this.source[this.index] === '1' || this.source[this.index] === '_') {
                if (this.source[this.index] === '_') {
                    if (this.index === nextInvalidNumericSeparatorPosition) {
                        this.throwUnexpectedToken();
                    }
                    ++this.index;
                    nextInvalidNumericSeparatorPosition = this.index;
                    continue;
                }
                num += this.source[this.index++];
            }
            if (num.length === 0) {
                // only 0b or 0B
                this.throwUnexpectedToken();
            }
            if (this.index === nextInvalidNumericSeparatorPosition) {
                this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterNumericLiteral);
            }
            let bigint = false;
            if (this.source[this.index] === 'n') {
                ++this.index;
                bigint = true;
            }
            if (!this.eof()) {
                ch = this.source.charCodeAt(this.index);
                /* istanbul ignore else */
                if (character_1.Character.isIdentifierStart(ch) || character_1.Character.isDecimalDigit(ch)) {
                    this.throwUnexpectedToken();
                }
            }
            return {
                type: 6 /* NumericLiteral */,
                value: parseInt(num, 2),
                bigint: bigint,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        scanOctalLiteral(prefix, start, legacy) {
            let num = '';
            let octal = false;
            if (character_1.Character.isOctalDigit(prefix.charCodeAt(0))) {
                octal = true;
                num = '0' + this.source[this.index++];
            }
            else {
                ++this.index;
            }
            let nextInvalidNumericSeparatorPosition = legacy ? -1 : this.index;
            while (character_1.Character.isOctalDigit(this.source.charCodeAt(this.index)) || this.source[this.index] === '_') {
                if (this.source[this.index] === '_') {
                    if (legacy || this.index === nextInvalidNumericSeparatorPosition) {
                        this.throwUnexpectedToken();
                    }
                    ++this.index;
                    nextInvalidNumericSeparatorPosition = this.index;
                    continue;
                }
                num += this.source[this.index++];
            }
            if (!octal && num.length === 0) {
                // only 0o or 0O
                this.throwUnexpectedToken();
            }
            if (this.index === nextInvalidNumericSeparatorPosition) {
                this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterNumericLiteral);
            }
            let bigint = false;
            if (!legacy && this.source[this.index] === 'n') {
                ++this.index;
                bigint = true;
            }
            if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index)) || character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
                this.throwUnexpectedToken();
            }
            return {
                type: 6 /* NumericLiteral */,
                value: parseInt(num, 8),
                octal: octal,
                bigint: bigint,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        isImplicitOctalLiteral() {
            // Implicit octal, unless there is a non-octal digit.
            // (Annex B.1.1 on Numeric Literals)
            for (let i = this.index + 1; i < this.length; ++i) {
                const ch = this.source[i];
                if (ch === '8' || ch === '9') {
                    return false;
                }
                if (!character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
                    return true;
                }
            }
            return true;
        }
        scanNumericLiteral() {
            const start = this.index;
            let ch = this.source[start];
            assert_1.assert(character_1.Character.isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), 'Numeric literal must start with a decimal digit or a decimal point');
            let nextInvalidNumericSeparatorPosition = -1;
            let num = '';
            if (ch !== '.') {
                num = this.source[this.index++];
                ch = this.source[this.index];
                // Hex number starts with '0x'.
                // Octal number starts with '0'.
                // Octal number in ES6 starts with '0o'.
                // Binary number in ES6 starts with '0b'.
                let wasZeroPrefixed = false;
                if (num === '0') {
                    if (ch === 'x' || ch === 'X') {
                        ++this.index;
                        return this.scanHexLiteral(start);
                    }
                    if (ch === 'b' || ch === 'B') {
                        ++this.index;
                        return this.scanBinaryLiteral(start);
                    }
                    if (ch === 'o' || ch === 'O') {
                        const legacy = false;
                        return this.scanOctalLiteral(ch, start, legacy);
                    }
                    if (ch && character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
                        if (this.isImplicitOctalLiteral()) {
                            const legacy = true;
                            return this.scanOctalLiteral(ch, start, legacy);
                        }
                    }
                    if (ch === '_') {
                        this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterLeadingZero);
                    }
                    wasZeroPrefixed = true;
                }
                while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index)) || this.source[this.index] === '_') {
                    if (this.source[this.index] === '_') {
                        if (wasZeroPrefixed || this.index === nextInvalidNumericSeparatorPosition) {
                            this.throwUnexpectedToken();
                        }
                        ++this.index;
                        nextInvalidNumericSeparatorPosition = this.index;
                        continue;
                    }
                    num += this.source[this.index++];
                }
                if (this.index === nextInvalidNumericSeparatorPosition) {
                    this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterLeadingZero);
                }
                ch = this.source[this.index];
                if (ch === 'n' && (!wasZeroPrefixed || num === '0')) {
                    ++this.index;
                    if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
                        this.throwUnexpectedToken();
                    }
                    const value = globalThis.BigInt ? globalThis.BigInt(this.source.slice(start, this.index - 1).replace(/_/g, '')) : /* istanbul ignore next */ null;
                    return {
                        type: 6 /* NumericLiteral */,
                        value: value,
                        bigint: true,
                        lineNumber: this.lineNumber,
                        lineStart: this.lineStart,
                        start: start,
                        end: this.index
                    };
                }
            }
            if (ch === '.') {
                num += this.source[this.index++];
                if (this.source[this.index] === '_') {
                    this.throwUnexpectedToken();
                }
                nextInvalidNumericSeparatorPosition = -1;
                while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index)) || this.source[this.index] === '_') {
                    if (this.source[this.index] === '_') {
                        if (this.index === nextInvalidNumericSeparatorPosition) {
                            this.throwUnexpectedToken();
                        }
                        ++this.index;
                        nextInvalidNumericSeparatorPosition = this.index;
                        continue;
                    }
                    num += this.source[this.index++];
                }
                ch = this.source[this.index];
                if (this.index === nextInvalidNumericSeparatorPosition) {
                    this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterNumericLiteral);
                }
            }
            if (ch === 'e' || ch === 'E') {
                num += this.source[this.index++];
                ch = this.source[this.index];
                if (ch === '_') {
                    this.throwUnexpectedToken();
                }
                if (ch === '+' || ch === '-') {
                    num += this.source[this.index++];
                    if (this.source[this.index] === '_') {
                        this.throwUnexpectedToken();
                    }
                }
                nextInvalidNumericSeparatorPosition = -1;
                if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
                    while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index)) || this.source[this.index] === '_') {
                        if (this.source[this.index] === '_') {
                            if (this.index === nextInvalidNumericSeparatorPosition) {
                                this.throwUnexpectedToken();
                            }
                            ++this.index;
                            nextInvalidNumericSeparatorPosition = this.index;
                            continue;
                        }
                        num += this.source[this.index++];
                    }
                }
                else {
                    this.throwUnexpectedToken();
                }
            }
            if (this.index === nextInvalidNumericSeparatorPosition) {
                this.throwUnexpectedToken(messages_1.Messages.InvalidNumericSeparatorAfterNumericLiteral);
            }
            if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
                this.throwUnexpectedToken();
            }
            return {
                type: 6 /* NumericLiteral */,
                value: parseFloat(num),
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        // https://tc39.github.io/ecma262/#sec-literals-string-literals
        scanStringLiteral() {
            const start = this.index;
            let quote = this.source[start];
            assert_1.assert((quote === '\'' || quote === '"'), 'String literal must starts with a quote');
            ++this.index;
            let octal = false;
            let str = '';
            while (!this.eof()) {
                let ch = this.source[this.index++];
                if (ch === quote) {
                    quote = '';
                    break;
                }
                else if (ch === '\\') {
                    ch = this.source[this.index++];
                    if (!ch || !character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                        switch (ch) {
                            case 'u':
                                if (this.source[this.index] === '{') {
                                    ++this.index;
                                    str += this.scanUnicodeCodePointEscape();
                                }
                                else {
                                    const unescapedChar = this.scanHexEscape(ch);
                                    if (unescapedChar === null) {
                                        this.throwUnexpectedToken();
                                    }
                                    str += unescapedChar;
                                }
                                break;
                            case 'x':
                                const unescaped = this.scanHexEscape(ch);
                                if (unescaped === null) {
                                    this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence);
                                }
                                str += unescaped;
                                break;
                            case 'n':
                                str += '\n';
                                break;
                            case 'r':
                                str += '\r';
                                break;
                            case 't':
                                str += '\t';
                                break;
                            case 'b':
                                str += '\b';
                                break;
                            case 'f':
                                str += '\f';
                                break;
                            case 'v':
                                str += '\x0B';
                                break;
                            case '8':
                            case '9':
                                str += ch;
                                this.tolerateUnexpectedToken();
                                break;
                            default:
                                if (ch && character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
                                    const octToDec = this.octalToDecimal(ch);
                                    octal = octToDec.octal || octal;
                                    str += String.fromCharCode(octToDec.code);
                                }
                                else {
                                    str += ch;
                                }
                                break;
                        }
                    }
                    else {
                        ++this.lineNumber;
                        if (ch === '\r' && this.source[this.index] === '\n') {
                            ++this.index;
                        }
                        this.lineStart = this.index;
                    }
                }
                else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                    break;
                }
                else {
                    str += ch;
                }
            }
            if (quote !== '') {
                this.index = start;
                this.throwUnexpectedToken();
            }
            return {
                type: 8 /* StringLiteral */,
                value: str,
                octal: octal,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        // https://tc39.github.io/ecma262/#sec-template-literal-lexical-components
        scanTemplate() {
            let cooked = '';
            let terminated = false;
            const start = this.index;
            const head = (this.source[start] === '`');
            let tail = false;
            let rawOffset = 2;
            ++this.index;
            while (!this.eof()) {
                let ch = this.source[this.index++];
                if (ch === '`') {
                    rawOffset = 1;
                    tail = true;
                    terminated = true;
                    break;
                }
                else if (ch === '$') {
                    if (this.source[this.index] === '{') {
                        this.curlyStack.push('${');
                        ++this.index;
                        terminated = true;
                        break;
                    }
                    cooked += ch;
                }
                else if (ch === '\\') {
                    ch = this.source[this.index++];
                    if (!character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                        switch (ch) {
                            case 'n':
                                cooked += '\n';
                                break;
                            case 'r':
                                cooked += '\r';
                                break;
                            case 't':
                                cooked += '\t';
                                break;
                            case 'u':
                                if (this.source[this.index] === '{') {
                                    ++this.index;
                                    cooked += this.scanUnicodeCodePointEscape();
                                }
                                else {
                                    const restore = this.index;
                                    const unescapedChar = this.scanHexEscape(ch);
                                    if (unescapedChar !== null) {
                                        cooked += unescapedChar;
                                    }
                                    else {
                                        this.index = restore;
                                        cooked += ch;
                                    }
                                }
                                break;
                            case 'x':
                                const unescaped = this.scanHexEscape(ch);
                                if (unescaped === null) {
                                    this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence);
                                }
                                cooked += unescaped;
                                break;
                            case 'b':
                                cooked += '\b';
                                break;
                            case 'f':
                                cooked += '\f';
                                break;
                            case 'v':
                                cooked += '\v';
                                break;
                            default:
                                if (ch === '0') {
                                    if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
                                        // Illegal: \01 \02 and so on
                                        this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
                                    }
                                    cooked += '\0';
                                }
                                else if (character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
                                    // Illegal: \1 \2
                                    this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
                                }
                                else {
                                    cooked += ch;
                                }
                                break;
                        }
                    }
                    else {
                        ++this.lineNumber;
                        if (ch === '\r' && this.source[this.index] === '\n') {
                            ++this.index;
                        }
                        this.lineStart = this.index;
                    }
                }
                else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                    ++this.lineNumber;
                    if (ch === '\r' && this.source[this.index] === '\n') {
                        ++this.index;
                    }
                    this.lineStart = this.index;
                    cooked += '\n';
                }
                else {
                    cooked += ch;
                }
            }
            if (!terminated) {
                this.throwUnexpectedToken();
            }
            if (!head) {
                this.curlyStack.pop();
            }
            return {
                type: 10 /* Template */,
                value: this.source.slice(start + 1, this.index - rawOffset),
                cooked: cooked,
                head: head,
                tail: tail,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        // https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals
        testRegExp(pattern, flags) {
            // The BMP character to use as a replacement for astral symbols when
            // translating an ES6 "u"-flagged pattern to an ES5-compatible
            // approximation.
            // Note: replacing with '\uFFFF' enables false positives in unlikely
            // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
            // pattern that would not be detected by this substitution.
            const astralSubstitute = '\uFFFF';
            let tmp = pattern;
            const self = this;
            if (flags.indexOf('u') >= 0) {
                tmp = tmp
                    // Replace every Unicode escape sequence with the equivalent
                    // BMP character or a constant ASCII code point in the case of
                    // astral symbols. (See the above note on `astralSubstitute`
                    // for more information.)
                    .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, ($0, $1, $2) => {
                    const codePoint = parseInt($1 || $2, 16);
                    if (codePoint > 0x10FFFF) {
                        self.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
                    }
                    if (codePoint <= 0xFFFF) {
                        return String.fromCharCode(codePoint);
                    }
                    return astralSubstitute;
                })
                    // Replace each paired surrogate with a single ASCII symbol to
                    // avoid throwing on regular expressions that are only valid in
                    // combination with the "u" flag.
                    .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, astralSubstitute);
            }
            // First, detect invalid regular expressions.
            try {
                RegExp(tmp);
            }
            catch (e) {
                this.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
            }
            // Return a regular expression object for this pattern-flag pair, or
            // `null` in case the current environment doesn't support the flags it
            // uses.
            try {
                return new RegExp(pattern, flags);
            }
            catch (exception) {
                /* istanbul ignore next */
                return null;
            }
        }
        scanRegExpBody() {
            let ch = this.source[this.index];
            assert_1.assert(ch === '/', 'Regular expression literal must start with a slash');
            let str = this.source[this.index++];
            let classMarker = false;
            let terminated = false;
            while (!this.eof()) {
                ch = this.source[this.index++];
                str += ch;
                if (ch === '\\') {
                    ch = this.source[this.index++];
                    // https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals
                    if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                        this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
                    }
                    str += ch;
                }
                else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
                    this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
                }
                else if (classMarker) {
                    if (ch === ']') {
                        classMarker = false;
                    }
                }
                else {
                    if (ch === '/') {
                        terminated = true;
                        break;
                    }
                    else if (ch === '[') {
                        classMarker = true;
                    }
                }
            }
            if (!terminated) {
                this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
            }
            // Exclude leading and trailing slash.
            return str.substr(1, str.length - 2);
        }
        scanRegExpFlags() {
            let str = '';
            let flags = '';
            while (!this.eof()) {
                let ch = this.source[this.index];
                if (!character_1.Character.isIdentifierPart(ch.charCodeAt(0))) {
                    break;
                }
                ++this.index;
                if (ch === '\\' && !this.eof()) {
                    ch = this.source[this.index];
                    if (ch === 'u') {
                        ++this.index;
                        let restore = this.index;
                        const char = this.scanHexEscape('u');
                        if (char !== null) {
                            flags += char;
                            for (str += '\\u'; restore < this.index; ++restore) {
                                str += this.source[restore];
                            }
                        }
                        else {
                            this.index = restore;
                            flags += 'u';
                            str += '\\u';
                        }
                        this.tolerateUnexpectedToken();
                    }
                    else {
                        str += '\\';
                        this.tolerateUnexpectedToken();
                    }
                }
                else {
                    flags += ch;
                    str += ch;
                }
            }
            return flags;
        }
        scanRegExp() {
            const start = this.index;
            const pattern = this.scanRegExpBody();
            const flags = this.scanRegExpFlags();
            const value = this.testRegExp(pattern, flags);
            return {
                type: 9 /* RegularExpression */,
                value: '',
                pattern: pattern,
                flags: flags,
                regex: value,
                lineNumber: this.lineNumber,
                lineStart: this.lineStart,
                start: start,
                end: this.index
            };
        }
        lex() {
            if (this.eof()) {
                return {
                    type: 2 /* EOF */,
                    value: '',
                    lineNumber: this.lineNumber,
                    lineStart: this.lineStart,
                    start: this.index,
                    end: this.index
                };
            }
            const cp = this.source.charCodeAt(this.index);
            if (character_1.Character.isIdentifierStart(cp)) {
                return this.scanIdentifier();
            }
            // Very common: ( and ) and ;
            if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
                return this.scanPunctuator();
            }
            // String literal starts with single quote (U+0027) or double quote (U+0022).
            if (cp === 0x27 || cp === 0x22) {
                return this.scanStringLiteral();
            }
            // Dot (.) U+002E can also start a floating-point number, hence the need
            // to check the next character.
            if (cp === 0x2E) {
                if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) {
                    return this.scanNumericLiteral();
                }
                return this.scanPunctuator();
            }
            if (character_1.Character.isDecimalDigit(cp)) {
                return this.scanNumericLiteral();
            }
            // Template literals start with ` (U+0060) for template head
            // or } (U+007D) for template middle or template tail.
            if (cp === 0x60 || (cp === 0x7D && this.curlyStack[this.curlyStack.length - 1] === '${')) {
                return this.scanTemplate();
            }
            // Possible identifier start in a surrogate pair.
            if (cp >= 0xD800 && cp < 0xDFFF) {
                if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) {
                    return this.scanIdentifier();
                }
            }
            return this.scanPunctuator();
        }
    }
    exports.Scanner = Scanner;


/***/ },
/* 13 */
/***/ function(module, exports) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TokenName = {};
    exports.TokenName[1 /* BooleanLiteral */] = 'Boolean';
    exports.TokenName[2 /* EOF */] = '<end>';
    exports.TokenName[3 /* Identifier */] = 'Identifier';
    exports.TokenName[4 /* Keyword */] = 'Keyword';
    exports.TokenName[5 /* NullLiteral */] = 'Null';
    exports.TokenName[6 /* NumericLiteral */] = 'Numeric';
    exports.TokenName[7 /* Punctuator */] = 'Punctuator';
    exports.TokenName[8 /* StringLiteral */] = 'String';
    exports.TokenName[9 /* RegularExpression */] = 'RegularExpression';
    exports.TokenName[10 /* Template */] = 'Template';


/***/ },
/* 14 */
/***/ function(module, exports) {

    "use strict";
    // Generated by generate-xhtml-entities.js. DO NOT MODIFY!
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.XHTMLEntities = {
        quot: '\u0022',
        amp: '\u0026',
        apos: '\u0027',
        gt: '\u003E',
        nbsp: '\u00A0',
        iexcl: '\u00A1',
        cent: '\u00A2',
        pound: '\u00A3',
        curren: '\u00A4',
        yen: '\u00A5',
        brvbar: '\u00A6',
        sect: '\u00A7',
        uml: '\u00A8',
        copy: '\u00A9',
        ordf: '\u00AA',
        laquo: '\u00AB',
        not: '\u00AC',
        shy: '\u00AD',
        reg: '\u00AE',
        macr: '\u00AF',
        deg: '\u00B0',
        plusmn: '\u00B1',
        sup2: '\u00B2',
        sup3: '\u00B3',
        acute: '\u00B4',
        micro: '\u00B5',
        para: '\u00B6',
        middot: '\u00B7',
        cedil: '\u00B8',
        sup1: '\u00B9',
        ordm: '\u00BA',
        raquo: '\u00BB',
        frac14: '\u00BC',
        frac12: '\u00BD',
        frac34: '\u00BE',
        iquest: '\u00BF',
        Agrave: '\u00C0',
        Aacute: '\u00C1',
        Acirc: '\u00C2',
        Atilde: '\u00C3',
        Auml: '\u00C4',
        Aring: '\u00C5',
        AElig: '\u00C6',
        Ccedil: '\u00C7',
        Egrave: '\u00C8',
        Eacute: '\u00C9',
        Ecirc: '\u00CA',
        Euml: '\u00CB',
        Igrave: '\u00CC',
        Iacute: '\u00CD',
        Icirc: '\u00CE',
        Iuml: '\u00CF',
        ETH: '\u00D0',
        Ntilde: '\u00D1',
        Ograve: '\u00D2',
        Oacute: '\u00D3',
        Ocirc: '\u00D4',
        Otilde: '\u00D5',
        Ouml: '\u00D6',
        times: '\u00D7',
        Oslash: '\u00D8',
        Ugrave: '\u00D9',
        Uacute: '\u00DA',
        Ucirc: '\u00DB',
        Uuml: '\u00DC',
        Yacute: '\u00DD',
        THORN: '\u00DE',
        szlig: '\u00DF',
        agrave: '\u00E0',
        aacute: '\u00E1',
        acirc: '\u00E2',
        atilde: '\u00E3',
        auml: '\u00E4',
        aring: '\u00E5',
        aelig: '\u00E6',
        ccedil: '\u00E7',
        egrave: '\u00E8',
        eacute: '\u00E9',
        ecirc: '\u00EA',
        euml: '\u00EB',
        igrave: '\u00EC',
        iacute: '\u00ED',
        icirc: '\u00EE',
        iuml: '\u00EF',
        eth: '\u00F0',
        ntilde: '\u00F1',
        ograve: '\u00F2',
        oacute: '\u00F3',
        ocirc: '\u00F4',
        otilde: '\u00F5',
        ouml: '\u00F6',
        divide: '\u00F7',
        oslash: '\u00F8',
        ugrave: '\u00F9',
        uacute: '\u00FA',
        ucirc: '\u00FB',
        uuml: '\u00FC',
        yacute: '\u00FD',
        thorn: '\u00FE',
        yuml: '\u00FF',
        OElig: '\u0152',
        oelig: '\u0153',
        Scaron: '\u0160',
        scaron: '\u0161',
        Yuml: '\u0178',
        fnof: '\u0192',
        circ: '\u02C6',
        tilde: '\u02DC',
        Alpha: '\u0391',
        Beta: '\u0392',
        Gamma: '\u0393',
        Delta: '\u0394',
        Epsilon: '\u0395',
        Zeta: '\u0396',
        Eta: '\u0397',
        Theta: '\u0398',
        Iota: '\u0399',
        Kappa: '\u039A',
        Lambda: '\u039B',
        Mu: '\u039C',
        Nu: '\u039D',
        Xi: '\u039E',
        Omicron: '\u039F',
        Pi: '\u03A0',
        Rho: '\u03A1',
        Sigma: '\u03A3',
        Tau: '\u03A4',
        Upsilon: '\u03A5',
        Phi: '\u03A6',
        Chi: '\u03A7',
        Psi: '\u03A8',
        Omega: '\u03A9',
        alpha: '\u03B1',
        beta: '\u03B2',
        gamma: '\u03B3',
        delta: '\u03B4',
        epsilon: '\u03B5',
        zeta: '\u03B6',
        eta: '\u03B7',
        theta: '\u03B8',
        iota: '\u03B9',
        kappa: '\u03BA',
        lambda: '\u03BB',
        mu: '\u03BC',
        nu: '\u03BD',
        xi: '\u03BE',
        omicron: '\u03BF',
        pi: '\u03C0',
        rho: '\u03C1',
        sigmaf: '\u03C2',
        sigma: '\u03C3',
        tau: '\u03C4',
        upsilon: '\u03C5',
        phi: '\u03C6',
        chi: '\u03C7',
        psi: '\u03C8',
        omega: '\u03C9',
        thetasym: '\u03D1',
        upsih: '\u03D2',
        piv: '\u03D6',
        ensp: '\u2002',
        emsp: '\u2003',
        thinsp: '\u2009',
        zwnj: '\u200C',
        zwj: '\u200D',
        lrm: '\u200E',
        rlm: '\u200F',
        ndash: '\u2013',
        mdash: '\u2014',
        lsquo: '\u2018',
        rsquo: '\u2019',
        sbquo: '\u201A',
        ldquo: '\u201C',
        rdquo: '\u201D',
        bdquo: '\u201E',
        dagger: '\u2020',
        Dagger: '\u2021',
        bull: '\u2022',
        hellip: '\u2026',
        permil: '\u2030',
        prime: '\u2032',
        Prime: '\u2033',
        lsaquo: '\u2039',
        rsaquo: '\u203A',
        oline: '\u203E',
        frasl: '\u2044',
        euro: '\u20AC',
        image: '\u2111',
        weierp: '\u2118',
        real: '\u211C',
        trade: '\u2122',
        alefsym: '\u2135',
        larr: '\u2190',
        uarr: '\u2191',
        rarr: '\u2192',
        darr: '\u2193',
        harr: '\u2194',
        crarr: '\u21B5',
        lArr: '\u21D0',
        uArr: '\u21D1',
        rArr: '\u21D2',
        dArr: '\u21D3',
        hArr: '\u21D4',
        forall: '\u2200',
        part: '\u2202',
        exist: '\u2203',
        empty: '\u2205',
        nabla: '\u2207',
        isin: '\u2208',
        notin: '\u2209',
        ni: '\u220B',
        prod: '\u220F',
        sum: '\u2211',
        minus: '\u2212',
        lowast: '\u2217',
        radic: '\u221A',
        prop: '\u221D',
        infin: '\u221E',
        ang: '\u2220',
        and: '\u2227',
        or: '\u2228',
        cap: '\u2229',
        cup: '\u222A',
        int: '\u222B',
        there4: '\u2234',
        sim: '\u223C',
        cong: '\u2245',
        asymp: '\u2248',
        ne: '\u2260',
        equiv: '\u2261',
        le: '\u2264',
        ge: '\u2265',
        sub: '\u2282',
        sup: '\u2283',
        nsub: '\u2284',
        sube: '\u2286',
        supe: '\u2287',
        oplus: '\u2295',
        otimes: '\u2297',
        perp: '\u22A5',
        sdot: '\u22C5',
        lceil: '\u2308',
        rceil: '\u2309',
        lfloor: '\u230A',
        rfloor: '\u230B',
        loz: '\u25CA',
        spades: '\u2660',
        clubs: '\u2663',
        hearts: '\u2665',
        diams: '\u2666',
        lang: '\u27E8',
        rang: '\u27E9'
    };


/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const error_handler_1 = __webpack_require__(10);
    const scanner_1 = __webpack_require__(12);
    const token_1 = __webpack_require__(13);
    class Reader {
        constructor() {
            this.values = [];
            this.curly = this.paren = -1;
        }
        // A function following one of those tokens is an expression.
        beforeFunctionExpression(t) {
            return ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
                'return', 'case', 'delete', 'throw', 'void',
                // assignment operators
                '=', '+=', '-=', '*=', '**=', '/=', '%=', '<<=', '>>=', '>>>=',
                '&=', '|=', '^=', ',',
                // binary/unary operators
                '+', '-', '*', '**', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
                '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
                '<=', '<', '>', '!=', '!=='].indexOf(t) >= 0;
        }
        // Determine if forward slash (/) is an operator or part of a regular expression
        // https://github.com/mozilla/sweet.js/wiki/design
        isRegexStart() {
            const previous = this.values[this.values.length - 1];
            let regex = (previous !== null);
            switch (previous) {
                case 'this':
                case ']':
                    regex = false;
                    break;
                case ')':
                    const keyword = this.values[this.paren - 1];
                    regex = (keyword === 'if' || keyword === 'while' || keyword === 'for' || keyword === 'with');
                    break;
                case '}':
                    // Dividing a function by anything makes little sense,
                    // but we have to check for that.
                    regex = true;
                    if (this.values[this.curly - 3] === 'function') {
                        // Anonymous function, e.g. function(){} /42
                        const check = this.values[this.curly - 4];
                        regex = check ? !this.beforeFunctionExpression(check) : false;
                    }
                    else if (this.values[this.curly - 4] === 'function') {
                        // Named function, e.g. function f(){} /42/
                        const check = this.values[this.curly - 5];
                        regex = check ? !this.beforeFunctionExpression(check) : true;
                    }
                    break;
                default:
                    break;
            }
            return regex;
        }
        push(token) {
            if (token.type === 7 /* Punctuator */ || token.type === 4 /* Keyword */) {
                if (token.value === '{') {
                    this.curly = this.values.length;
                }
                else if (token.value === '(') {
                    this.paren = this.values.length;
                }
                this.values.push(token.value);
            }
            else {
                this.values.push(null);
            }
        }
    }
    class Tokenizer {
        constructor(code, config) {
            this.errorHandler = new error_handler_1.ErrorHandler();
            this.errorHandler.tolerant = config ? (typeof config.tolerant === 'boolean' && config.tolerant) : false;
            this.scanner = new scanner_1.Scanner(code, this.errorHandler);
            this.scanner.trackComment = config ? (typeof config.comment === 'boolean' && config.comment) : false;
            this.trackRange = config ? (typeof config.range === 'boolean' && config.range) : false;
            this.trackLoc = config ? (typeof config.loc === 'boolean' && config.loc) : false;
            this.buffer = [];
            this.reader = new Reader();
        }
        errors() {
            return this.errorHandler.errors;
        }
        getNextToken() {
            if (this.buffer.length === 0) {
                const comments = this.scanner.scanComments();
                if (this.scanner.trackComment) {
                    for (let i = 0; i < comments.length; ++i) {
                        const e = comments[i];
                        const value = this.scanner.source.slice(e.slice[0], e.slice[1]);
                        const comment = {
                            type: e.multiLine ? 'BlockComment' : 'LineComment',
                            value: value
                        };
                        if (this.trackRange) {
                            comment.range = e.range;
                        }
                        if (this.trackLoc) {
                            comment.loc = e.loc;
                        }
                        this.buffer.push(comment);
                    }
                }
                if (!this.scanner.eof()) {
                    let loc;
                    if (this.trackLoc) {
                        loc = {
                            start: {
                                line: this.scanner.lineNumber,
                                column: this.scanner.index - this.scanner.lineStart
                            },
                            end: {}
                        };
                    }
                    const maybeRegex = (this.scanner.source[this.scanner.index] === '/') && this.reader.isRegexStart();
                    let token;
                    if (maybeRegex) {
                        const state = this.scanner.saveState();
                        try {
                            token = this.scanner.scanRegExp();
                        }
                        catch (e) {
                            this.scanner.restoreState(state);
                            token = this.scanner.lex();
                        }
                    }
                    else {
                        token = this.scanner.lex();
                    }
                    this.reader.push(token);
                    const entry = {
                        type: token_1.TokenName[token.type],
                        value: this.scanner.source.slice(token.start, token.end)
                    };
                    if (this.trackRange) {
                        entry.range = [token.start, token.end];
                    }
                    if (this.trackLoc) {
                        loc.end = {
                            line: this.scanner.lineNumber,
                            column: this.scanner.index - this.scanner.lineStart
                        };
                        entry.loc = loc;
                    }
                    if (token.type === 9 /* RegularExpression */) {
                        const pattern = token.pattern;
                        const flags = token.flags;
                        entry.regex = { pattern, flags };
                    }
                    this.buffer.push(entry);
                }
            }
            return this.buffer.shift();
        }
    }
    exports.Tokenizer = Tokenizer;


/***/ }
/******/ ])
});
